From fa29ff4c43032762d0976ca5d4d479eb7cbc18c5 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Wed, 8 May 2024 13:16:23 +0200 Subject: [PATCH] Update UI Refactor and added new functioms --- README.md | 4 +- build.js | 29 +- config/build.config.js | 16 +- config/coin.config.js | 10 +- config/config.js | 46 +- config/crypto.config.js | 2 +- config/customConfig.js | 8 +- config/default.config.js | 3 +- config/styles.config.js | 2 +- config/user.config.js | 9 +- core/config/config.js | 2 +- core/config/default.build.options.js | 216 +- core/config/default.coin.config.js | 16 +- core/config/default.crypto.config.js | 16 +- core/config/default.styles.config.js | 69 +- core/config/default.user.config.js | 75 +- core/config/load-config.js | 25 +- core/font/switch-theme.css | 2 + core/language/us.json | 11 +- core/public/index.html | 254 +- core/server/ServerFactory.js | 47 +- core/server/routes/createCommonRoutes.js | 192 +- core/server/routes/createPrimaryRoutes.js | 247 +- core/server/server.js | 26 +- core/src/apiKeyUtils.js | 83 +- core/src/components/WebWorkerFile.js | 6 +- core/src/components/app-info.js | 222 +- core/src/components/app-view.js | 5671 +++---- core/src/components/base.js | 29 +- .../beginner-tour/sync-indicator.js | 80 +- .../beginner-tour/tour-component.js | 542 +- core/src/components/check-for-update.js | 15 +- core/src/components/computePowWorker.js | 114 +- core/src/components/computePowWorkerFile.js | 134 +- .../controllers/coin-balances-controller.js | 559 +- .../friends-view/ChatSideNavHeads.js | 391 +- .../friends-view/add-friends-modal.js | 633 +- core/src/components/friends-view/avatar.js | 473 +- .../friends-view/beginner-checklist.js | 454 +- .../friends-view/computePowWorkerFile.src.js | 136 +- .../friends-view/core-sync-status.js | 104 +- core/src/components/friends-view/feed-item.js | 743 +- .../friends-view/friend-item-actions.js | 250 +- .../components/friends-view/friends-feed.js | 733 +- .../friends-view/friends-side-panel-parent.js | 90 +- .../friends-view/friends-side-panel.js | 208 +- .../friends-view/friends-view-css.js | 182 - .../components/friends-view/friends-view.js | 491 +- .../friends-view/profile-modal-update.js | 896 +- core/src/components/friends-view/profile.js | 1617 +- .../friends-view/save-settings-qdn.js | 878 +- core/src/components/language-selector.js | 171 +- .../login-view/create-account-section.js | 1135 +- .../components/login-view/login-section.js | 1359 +- core/src/components/login-view/login-view.js | 655 +- .../src/components/login-view/welcome-page.js | 102 +- .../src/components/logout-view/logout-view.js | 111 +- core/src/components/main-app.js | 117 +- core/src/components/new-selector.js | 200 +- .../notification-bell-general.js | 656 +- .../notification-view/notification-bell.js | 517 +- .../components/notification-view/popover.js | 106 +- core/src/components/qort-theme-toggle.js | 172 +- core/src/components/search-modal.js | 68 +- .../components/settings-view/account-view.js | 202 +- .../components/settings-view/export-keys.js | 916 +- .../settings-view/notifications-view.js | 370 +- .../components/settings-view/qr-login-view.js | 193 +- .../components/settings-view/security-view.js | 406 +- .../components/settings-view/user-settings.js | 405 +- core/src/components/show-plugin.js | 4308 +++-- core/src/components/start-minting.js | 556 +- core/src/components/theme-toggle.js | 65 +- .../user-info-view/user-info-view.js | 3371 ++-- core/src/components/wallet-profile.js | 186 +- core/src/cryptoUtils.js | 101 +- core/src/custom-elements/frag-file-input.js | 115 - core/src/data/defaultQapps.js | 11 + core/src/epml.js | 2 +- .../confirm-transaction-dialog.js | 155 +- .../functional-components/frag-file-input.js | 93 + .../functional-components/loading-ripple.js | 277 +- core/src/functional-components/my-button.js | 60 +- core/src/functional-components/mykey-page.js | 185 +- .../random-sentence-generator.js | 78 +- .../functional-components/settings-page.js | 352 +- .../side-menu-item-style.js | 157 - .../functional-components/side-menu-item.js | 372 +- core/src/functional-components/side-menu.js | 120 +- core/src/functional-components/snackbar.js | 126 +- .../functional-components/verb-past-tense.js | 10 +- core/src/functional-components/wordlists.js | 19 +- core/src/initStore.js | 50 +- core/src/localStorageHelpers.js | 30 +- core/src/lockScreen.js | 16 +- core/src/main.js | 4 +- core/src/notifications/config.js | 18 +- core/src/notifications/controller.js | 144 +- core/src/notifications/dispatcher.js | 22 +- .../notification-actions/index.js | 2 +- .../notification-actions/new-message.js | 467 +- core/src/notifications/types.js | 2 +- core/src/persistState.js | 29 +- core/src/plugins/addPluginRoutes.js | 10 +- core/src/plugins/load-plugins.js | 69 +- core/src/plugins/plugin-mainjs-loader.html | 11 +- core/src/plugins/plugin-mainjs-loader.js | 9 +- core/src/plugins/routes.js | 130 +- core/src/plugins/streams.js | 85 +- core/src/redux/app/actions/app-core.js | 238 +- core/src/redux/app/actions/init-worker.js | 52 +- core/src/redux/app/actions/login.js | 52 +- core/src/redux/app/actions/node-config.js | 156 +- core/src/redux/app/actions/plugins.js | 46 +- core/src/redux/app/app-action-types.js | 2 +- core/src/redux/app/app-actions.js | 38 +- core/src/redux/app/app-reducer.js | 689 +- core/src/redux/app/reducers/init-workers.js | 64 +- core/src/redux/app/reducers/login-reducer.js | 44 +- core/src/redux/app/reducers/manage-node.js | 75 +- core/src/redux/config/config-actions.js | 36 +- core/src/redux/config/config-reducer.js | 56 +- .../config/reducers/load-config-from-api.js | 42 +- core/src/redux/reducers.js | 13 +- core/src/redux/user/actions/claim-airdrop.js | 18 +- .../redux/user/actions/notification-config.js | 63 +- core/src/redux/user/actions/store-wallet.js | 66 +- .../redux/user/actions/update-account-info.js | 18 +- core/src/redux/user/actions/update-name.js | 74 +- core/src/redux/user/user-actions.js | 8 +- core/src/redux/user/user-reducer.js | 122 +- core/src/stateAwait.js | 34 +- core/src/store.js | 13 +- core/src/styles/app-styles.js | 107 +- core/src/styles/app-theme.js | 98 +- core/src/styles/core-css.js | 4753 ++++++ core/src/styles/styles.scss | 4 +- core/src/styles/switch-theme.css | 19 +- core/src/tradebot/addTradeBotRoutes.js | 10 +- core/src/tradebot/trade-bot-routes.js | 62 +- core/src/transactionRequest.js | 12 +- core/src/worker.js | 22 +- core/tooling/build.js | 43 +- core/tooling/generateBuildConfig.js | 157 +- core/tooling/generateES5BuildConfig.js | 122 +- core/tooling/utils.js | 19 +- core/tooling/watch-inlines.js | 26 +- core/tooling/watch.js | 47 +- .../translate/directives/lang-changed-base.js | 58 +- core/translate/directives/lang-changed.js | 7 +- .../directives/translate-unsafe-html.js | 6 +- core/translate/directives/translate.js | 6 +- core/translate/helpers.js | 18 +- core/translate/util.js | 48 +- core/ui-core.js | 12 +- crypto/api/createTransaction.js | 3 - crypto/api/fetch-request.js | 2 + crypto/api/transactions/AirdropTransaction.js | 5 +- .../api/transactions/DelegationTransaction.js | 3 +- .../api/transactions/DeployAtTransaction.js | 17 +- crypto/api/transactions/MessageTransaction.js | 9 +- crypto/api/transactions/PaymentTransaction.js | 7 +- .../api/transactions/PublicizeTransaction.js | 11 +- crypto/api/transactions/TransactionBase.js | 11 +- .../transactions/TransferPrivsTransaction.js | 19 +- .../transactions/arbitrary/signArbitrary.js | 10 +- .../arbitrary/signArbitraryWithFee.js | 12 +- crypto/api/transactions/arbitraryV3.js | 1 + crypto/api/transactions/chat/ChatBase.js | 12 +- .../api/transactions/chat/ChatTransaction.js | 10 +- .../transactions/chat/GroupChatTransaction.js | 8 +- .../transactions/chat/decryptChatMessage.js | 29 +- crypto/api/transactions/chat/signChat.js | 4 +- .../groups/AddGroupAdminTransaction.js | 5 +- .../groups/CancelGroupBanTransaction.js | 5 +- .../groups/CancelGroupInviteTransaction.js | 5 +- .../groups/CreateGroupTransaction.js | 30 +- .../groups/GroupBanTransaction.js | 7 +- .../groups/GroupInviteTransaction.js | 5 +- .../groups/GroupKickTransaction.js | 7 +- .../groups/JoinGroupTransaction.js | 5 +- .../groups/LeaveGroupTransaction.js | 5 +- .../groups/RemoveGroupAdminTransaction.js | 5 +- .../groups/UpdateGroupTransaction.js | 155 +- .../transactions/names/BuyNameTransacion.js | 5 +- .../names/CancelSellNameTransacion.js | 5 +- .../names/RegisterNameTransaction.js | 5 +- .../transactions/names/SellNameTransacion.js | 5 +- .../names/UpdateNameTransaction.js | 5 +- .../polls/CreatePollTransaction.js | 25 +- .../polls/VoteOnPollTransaction.js | 13 +- .../RemoveRewardShareTransaction.js | 9 +- .../reward-share/RewardShareTransaction.js | 21 +- .../tradebot/signTradeBotTransaction.js | 6 +- .../tradeoffer/cancelAllOffers.js | 8 +- crypto/api/transactions/transactions.js | 54 +- electron-builder.yml | 1 + electron.js | 472 +- img/qdcgroup.png | Bin 0 -> 14569 bytes img/qgcgroup.png | Bin 0 -> 28235 bytes lib/detect-platform.js | 6 +- lib/i18n.js | 303 +- lib/preload.js | 2 +- package-lock.json | 922 +- package.json | 26 +- plugins/build-config.js | 202 +- plugins/build.js | 28 +- plugins/default-plugins.js | 6 +- plugins/epml.js | 3 +- .../become-minter/become-minter-css.src.js | 253 - .../core/become-minter/become-minter.src.js | 211 +- .../become-minter/components/not-sponsored.js | 132 - .../become-minter/components/yes-sponsored.js | 107 - .../plugins/core/components/ButtonIconCopy.js | 137 +- plugins/plugins/core/components/ChatGifs.js | 923 ++ .../core/components/ChatGifs/ChatGifs-css.js | 521 - .../core/components/ChatGifs/ChatGifs.js | 980 -- .../ChatGifs/ChatGifsExplore-css.js | 157 - .../components/ChatGifs/ChatGifsExplore.js | 170 - .../core/components/ChatGifsExplore.js | 191 + .../core/components/ChatGroupInvites.js | 346 +- .../core/components/ChatGroupManager.js | 361 +- .../core/components/ChatGroupSettings.js | 358 +- .../core/components/ChatGroupsManagement.js | 411 +- .../core/components/ChatGroupsModal.js | 119 +- plugins/plugins/core/components/ChatHead.js | 482 +- plugins/plugins/core/components/ChatImage.js | 580 +- .../plugins/core/components/ChatLeaveGroup.js | 380 +- .../plugins/core/components/ChatMessage.js | 185 +- plugins/plugins/core/components/ChatModals.js | 662 +- .../plugins/core/components/ChatPage-css.js | 1154 -- plugins/plugins/core/components/ChatPage.js | 6464 ++++---- .../plugins/core/components/ChatRightPanel.js | 430 +- .../components/ChatRightPanelResources.js | 757 +- .../core/components/ChatScroller-css.js | 819 - .../plugins/core/components/ChatScroller.js | 3288 ++-- .../core/components/ChatSeachResults.js | 66 - .../core/components/ChatSearchResults-css.js | 120 - .../core/components/ChatSearchResults.js | 137 +- plugins/plugins/core/components/ChatSelect.js | 342 +- .../core/components/ChatSideNavHeads.js | 330 +- .../core/components/ChatTextEditor copy.js | 825 - .../plugins/core/components/ChatTextEditor.js | 1060 +- .../core/components/ChatWelcomePage.js | 809 +- .../plugins/core/components/ImageComponent.js | 227 +- .../plugins/core/components/LevelFounder.js | 202 +- plugins/plugins/core/components/NameMenu.js | 930 +- plugins/plugins/core/components/QRCode.js | 917 +- .../core/components/QortalFileSaver.js | 276 +- .../core/components/QortalQrcodeGenerator.js | 349 +- .../plugins/core/components/ReusableImage.js | 264 +- plugins/plugins/core/components/TimeAgo.js | 95 +- .../plugins/core/components/TipUser-css.js | 85 - plugins/plugins/core/components/TipUser.js | 517 +- plugins/plugins/core/components/ToolTip.js | 148 +- .../core/components/TradeInfoView-css.js | 1124 -- .../plugins/core/components/TradeInfoView.js | 464 +- .../plugins/core/components/TraderInfoView.js | 3389 ++-- plugins/plugins/core/components/UserInfo.js | 145 + .../core/components/UserInfo/UserInfo-css.js | 68 - .../core/components/UserInfo/UserInfo.js | 133 - .../core/components/WrapperModal-css.js | 57 - .../plugins/core/components/WrapperModal.js | 71 +- .../core/components/computePowWorker.js | 116 +- .../core/components/computePowWorkerFile.js | 136 +- .../core/components/frag-file-input.js | 173 +- .../plugins/core/components/plugins-css.js | 13539 ++++++++++++++++ .../core/components/qdn-action-constants.js | 102 +- .../core/components/qdn-action-encryption.js | 632 +- .../core/components/qdn-action-types.js | 77 +- .../core/components/qortal-info-view.js | 3143 ++-- plugins/plugins/core/components/snackbar.js | 139 +- .../time-elements/extended-time-element.js | 180 +- .../core/components/time-elements/index.js | 1375 +- .../time-elements/local-time-element.js | 177 +- .../time-elements/relative-time-element.js | 92 +- .../components/time-elements/relative-time.js | 554 +- .../time-elements/time-ago-element.js | 39 +- .../time-elements/time-until-element.js | 39 +- .../core/components/time-elements/utils.js | 320 +- .../components/webworkerDecodeMessages.js | 4653 +++--- .../core/components/webworkerSortMessages.js | 20 +- plugins/plugins/core/connect.js | 17 +- .../data-management/data-management.src.js | 932 ++ .../core/{qdn => }/data-management/index.html | 0 .../group-management/group-management.src.js | 6865 ++++---- .../group-transaction.src.js | 169 - .../group-transaction/index.html | 55 - plugins/plugins/core/index.html | 1 - plugins/plugins/core/main.src.js | 226 +- .../chain-messaging/chain-messaging.src.js | 96 - .../core/messaging/chain-messaging/index.html | 55 - plugins/plugins/core/messaging/index.html | 55 - .../plugins/core/messaging/messaging.src.js | 201 - .../messaging/q-chat/computePowWorker.src.js | 82 - .../core/messaging/q-chat/q-chat-css.src.js | 479 - .../core/{minting => minting-info}/index.html | 0 .../core/minting-info/minting-info.src.js | 776 + .../plugins/core/minting/minting-info.src.js | 899 - .../name-registration.src.js | 1878 +-- .../core/names-market/names-market.src.js | 2013 +-- .../node-management/node-management.src.js | 1007 +- .../core/overview-page/overview-page-css.js | 745 - .../core/overview-page/overview-page.src.js | 850 +- plugins/plugins/core/puzzles/puzzles.src.js | 669 +- plugins/plugins/core/q-app/q-apps.src.js | 2502 ++- .../core/{messaging => }/q-chat/index.html | 0 .../core/{messaging => }/q-chat/q-chat.src.js | 616 +- .../core/{qdn => q-website}/index.html | 4 +- .../plugins/core/q-website/q-websites.src.js | 976 ++ .../plugins/core/qdn/browser/browser.src.js | 2025 +-- .../core/qdn/browser/computePowWorker.src.js | 82 - .../qdn/browser/computePowWorkerFile.src.js | 91 - .../data-management/data-management.src.js | 1099 -- .../plugins/core/qdn/publish/publish.src.js | 1263 +- plugins/plugins/core/qdn/websites.src.js | 1116 -- .../core/qortal-lottery/qortal-lottery.src.js | 1428 +- .../core/reward-share/reward-share.src.js | 1139 +- .../sponsorship-list-css.src.js | 484 - .../sponsorship-list/sponsorship-list.src.js | 149 +- .../plugins/core/streams/AddressWatcher.js | 112 +- .../streams/UnconfirmedTransactionWatcher.js | 78 +- plugins/plugins/core/streams/onNewBlock.js | 376 +- plugins/plugins/core/streams/streams.js | 341 +- .../core/trade-bot/trade-bot-portal-css.js | 679 - .../core/trade-bot/trade-bot-portal.src.js | 6469 ++++---- .../core/trade-portal/charts/arrr-charts.js | 68 +- .../core/trade-portal/charts/btc-charts.js | 68 +- .../core/trade-portal/charts/dgb-charts.js | 68 +- .../core/trade-portal/charts/doge-charts.js | 68 +- .../core/trade-portal/charts/ltc-charts.js | 68 +- .../core/trade-portal/charts/rvn-charts.js | 68 +- .../core/trade-portal/trade-portal-css.js | 687 - .../core/trade-portal/trade-portal.src.js | 5366 +++--- plugins/plugins/core/wallet/wallet-app.src.js | 10791 ++++++------ plugins/plugins/utils/blocks-needed.js | 23 - plugins/plugins/utils/bytesToMegabytes.js | 3 - plugins/plugins/utils/classes.js | 926 ++ plugins/plugins/utils/cropAddress.js | 8 - plugins/plugins/utils/functions.js | 208 + .../plugins/utils/getUserNameFromAddress.js | 20 - plugins/plugins/utils/id-generation.js | 14 - plugins/plugins/utils/keyCodes.js | 1 - plugins/plugins/utils/loader.js | 52 - plugins/plugins/utils/publish-image.js | 248 - plugins/plugins/utils/publish-modal.css | 147 - plugins/plugins/utils/publish-modal.js | 270 - plugins/plugins/utils/queue.js | 71 - .../plugins/utils/replace-messages-edited.js | 251 - .../plugins/utils/roundToNearestDecimal.js | 4 - plugins/plugins/utils/warning-modal.js | 252 - plugins/watch.js | 3 +- scripts/afterPack.js | 52 +- scripts/notarize.js | 33 +- server.js | 30 +- watch-inline.js | 25 +- watch.js | 19 +- 357 files changed, 82113 insertions(+), 83085 deletions(-) delete mode 100644 core/src/components/friends-view/friends-view-css.js delete mode 100644 core/src/custom-elements/frag-file-input.js create mode 100644 core/src/functional-components/frag-file-input.js delete mode 100644 core/src/functional-components/side-menu-item-style.js create mode 100644 core/src/styles/core-css.js create mode 100644 img/qdcgroup.png create mode 100644 img/qgcgroup.png delete mode 100644 plugins/plugins/core/become-minter/become-minter-css.src.js delete mode 100644 plugins/plugins/core/become-minter/components/not-sponsored.js delete mode 100644 plugins/plugins/core/become-minter/components/yes-sponsored.js create mode 100644 plugins/plugins/core/components/ChatGifs.js delete mode 100644 plugins/plugins/core/components/ChatGifs/ChatGifs-css.js delete mode 100644 plugins/plugins/core/components/ChatGifs/ChatGifs.js delete mode 100644 plugins/plugins/core/components/ChatGifs/ChatGifsExplore-css.js delete mode 100644 plugins/plugins/core/components/ChatGifs/ChatGifsExplore.js create mode 100644 plugins/plugins/core/components/ChatGifsExplore.js delete mode 100644 plugins/plugins/core/components/ChatPage-css.js delete mode 100644 plugins/plugins/core/components/ChatScroller-css.js delete mode 100644 plugins/plugins/core/components/ChatSeachResults.js delete mode 100644 plugins/plugins/core/components/ChatSearchResults-css.js delete mode 100644 plugins/plugins/core/components/ChatTextEditor copy.js delete mode 100644 plugins/plugins/core/components/TipUser-css.js delete mode 100644 plugins/plugins/core/components/TradeInfoView-css.js create mode 100644 plugins/plugins/core/components/UserInfo.js delete mode 100644 plugins/plugins/core/components/UserInfo/UserInfo-css.js delete mode 100644 plugins/plugins/core/components/UserInfo/UserInfo.js delete mode 100644 plugins/plugins/core/components/WrapperModal-css.js create mode 100644 plugins/plugins/core/components/plugins-css.js create mode 100644 plugins/plugins/core/data-management/data-management.src.js rename plugins/plugins/core/{qdn => }/data-management/index.html (100%) delete mode 100644 plugins/plugins/core/group-management/group-transaction/group-transaction.src.js delete mode 100644 plugins/plugins/core/group-management/group-transaction/index.html delete mode 100644 plugins/plugins/core/index.html delete mode 100644 plugins/plugins/core/messaging/chain-messaging/chain-messaging.src.js delete mode 100644 plugins/plugins/core/messaging/chain-messaging/index.html delete mode 100644 plugins/plugins/core/messaging/index.html delete mode 100644 plugins/plugins/core/messaging/messaging.src.js delete mode 100644 plugins/plugins/core/messaging/q-chat/computePowWorker.src.js delete mode 100644 plugins/plugins/core/messaging/q-chat/q-chat-css.src.js rename plugins/plugins/core/{minting => minting-info}/index.html (100%) create mode 100644 plugins/plugins/core/minting-info/minting-info.src.js delete mode 100644 plugins/plugins/core/minting/minting-info.src.js delete mode 100644 plugins/plugins/core/overview-page/overview-page-css.js rename plugins/plugins/core/{messaging => }/q-chat/index.html (100%) rename plugins/plugins/core/{messaging => }/q-chat/q-chat.src.js (74%) rename plugins/plugins/core/{qdn => q-website}/index.html (94%) create mode 100644 plugins/plugins/core/q-website/q-websites.src.js delete mode 100644 plugins/plugins/core/qdn/browser/computePowWorker.src.js delete mode 100644 plugins/plugins/core/qdn/browser/computePowWorkerFile.src.js delete mode 100644 plugins/plugins/core/qdn/data-management/data-management.src.js delete mode 100644 plugins/plugins/core/qdn/websites.src.js delete mode 100644 plugins/plugins/core/sponsorship-list/sponsorship-list-css.src.js delete mode 100644 plugins/plugins/core/trade-bot/trade-bot-portal-css.js delete mode 100644 plugins/plugins/core/trade-portal/trade-portal-css.js delete mode 100644 plugins/plugins/utils/blocks-needed.js delete mode 100644 plugins/plugins/utils/bytesToMegabytes.js create mode 100644 plugins/plugins/utils/classes.js delete mode 100644 plugins/plugins/utils/cropAddress.js create mode 100644 plugins/plugins/utils/functions.js delete mode 100644 plugins/plugins/utils/getUserNameFromAddress.js delete mode 100644 plugins/plugins/utils/id-generation.js delete mode 100644 plugins/plugins/utils/keyCodes.js delete mode 100644 plugins/plugins/utils/loader.js delete mode 100644 plugins/plugins/utils/publish-image.js delete mode 100644 plugins/plugins/utils/publish-modal.css delete mode 100644 plugins/plugins/utils/publish-modal.js delete mode 100644 plugins/plugins/utils/queue.js delete mode 100644 plugins/plugins/utils/replace-messages-edited.js delete mode 100644 plugins/plugins/utils/roundToNearestDecimal.js delete mode 100644 plugins/plugins/utils/warning-modal.js diff --git a/README.md b/README.md index 6af149dc..f9116d7f 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,8 @@ Easiest way to install the lastest required packages on Linux is via nvm. ``` source ~/.profile ``` (For Debian based distro)
``` source ~/.bashrc ``` (For Fedora / CentOS)
``` nvm ls-remote ``` (Fetch list of available versions)
-``` nvm install v18.17.1 ``` (LTS: Hydrogen supported by Electron V27)
-``` npm --location=global install npm@10.5.0 ```
+``` nvm install v20.11.1 ``` (LTS: Iron supported by Electron V30)
+``` npm --location=global install npm@10.7.0 ```
Adding via binary package mirror will only work if you have set the package path. You can do a node or java build via ports instead by downloading ports with portsnap fetch method. diff --git a/build.js b/build.js index b635217e..f0ba308f 100644 --- a/build.js +++ b/build.js @@ -1,28 +1,23 @@ const path = require('path') const uiCore = require('./core/ui-core.js') - +const config = require('./config/config.js') +const pluginsController = require('./plugins/default-plugins.js') const generateBuildConfig = uiCore('generate_build_config') const build = uiCore('build') - -const config = require('./config/config.js') - -const pluginsController = require('./plugins/default-plugins.js') const buildDefalutPlugins = pluginsController('build') - srcConfig = { - ...config.build, - options: { - ...config.build.options, - outputDir: path.join(__dirname, '/builtWWW'), - sassOutputDir: path.join(__dirname, '/builtWWW/styles.bundle.css'), - } + ...config.build, + options: { + ...config.build.options, + outputDir: path.join(__dirname, '/builtWWW'), + sassOutputDir: path.join(__dirname, '/builtWWW/styles.bundle.css') + } } const { buildConfig, inlineConfigs } = generateBuildConfig(srcConfig) -build(buildConfig.options, buildConfig.outputs, buildConfig.outputOptions, buildConfig.inputOptions, inlineConfigs) - .then(() => { - console.log("Building and Bundling Plugins"); - buildDefalutPlugins() - }) +build(buildConfig.options, buildConfig.outputs, buildConfig.outputOptions, buildConfig.inputOptions, inlineConfigs).then(() => { + console.log("Building and Bundling Plugins") + buildDefalutPlugins() +}) \ No newline at end of file diff --git a/config/build.config.js b/config/build.config.js index 938710f4..e40f22bf 100644 --- a/config/build.config.js +++ b/config/build.config.js @@ -2,13 +2,13 @@ const path = require('path') const defaultConfig = require('./default.config.js') const build = { - options: { - outputDir: path.join(__dirname, '../build'), - imgDir: path.join(__dirname, '../img') - }, - aliases: { - 'qortal-ui-crypto': path.join(__dirname, '../crypto/api.js') - } + options: { + outputDir: path.join(__dirname, '../build'), + imgDir: path.join(__dirname, '../img') + }, + aliases: { + 'qortal-ui-crypto': path.join(__dirname, '../crypto/api.js') + } } -module.exports = build +module.exports = build \ No newline at end of file diff --git a/config/coin.config.js b/config/coin.config.js index bcd320e9..0f0f1c3d 100644 --- a/config/coin.config.js +++ b/config/coin.config.js @@ -1,8 +1,8 @@ const defaultConfig = require('./default.config.js') module.exports = { - name: 'Qortal', - symbol: 'Qort', - addressVersion: 58, // Q for Qortal - logo: '/img/QORT_LOGO.svg' -} + name: 'Qortal', + symbol: 'Qort', + addressVersion: 58, // Q for Qortal + logo: '/img/QORT_LOGO.svg' +} \ No newline at end of file diff --git a/config/config.js b/config/config.js index 8fd79649..992f6466 100644 --- a/config/config.js +++ b/config/config.js @@ -1,27 +1,33 @@ let config = require('./default.config.js') -let userConfig = {} -try { - userConfig = require('./customConfig.js') -} catch (e) { - console.warn(e) - console.warn('Error loading user config') -} -const checkKeys = (storeObj, newObj) => { - for (const key in newObj) { - if (!Object.prototype.hasOwnProperty.call(storeObj, key)) return - if (typeof newObj[key] === 'object') { - storeObj[key] = checkKeys(storeObj[key], newObj[key]) - } else { - storeObj[key] = newObj[key] - } - } - return storeObj +let userConfig = {} + +try { + userConfig = require('./customConfig.js') +} catch (e) { + console.warn(e) + console.warn('Error loading user config') +} + +const checkKeys = (storeObj, newObj) => { + for (const key in newObj) { + if (!Object.prototype.hasOwnProperty.call(storeObj, key)) { + return + } + + if (typeof newObj[key] === 'object') { + storeObj[key] = checkKeys(storeObj[key], newObj[key]) + } else { + storeObj[key] = newObj[key] + } + } + + return storeObj } const getConfig = customConfig => { - config = checkKeys(config, customConfig) - return config + config = checkKeys(config, customConfig) + return config } -module.exports = getConfig(userConfig) +module.exports = getConfig(userConfig) \ No newline at end of file diff --git a/config/crypto.config.js b/config/crypto.config.js index 968d2e8e..34ea6e98 100644 --- a/config/crypto.config.js +++ b/config/crypto.config.js @@ -1,3 +1,3 @@ const defaultConfig = require('./default.config.js') -module.exports = {} +module.exports = {} \ No newline at end of file diff --git a/config/customConfig.js b/config/customConfig.js index 6c6d12f3..ab37e550 100644 --- a/config/customConfig.js +++ b/config/customConfig.js @@ -4,10 +4,4 @@ const styles = require('./styles.config.js') const build = require('./build.config.js') const user = require('./user.config.js') -module.exports = { - coin, - styles, - build, - user, - crypto -} +module.exports = { coin, styles, build, user, crypto } \ No newline at end of file diff --git a/config/default.config.js b/config/default.config.js index 8d23d608..d0476954 100644 --- a/config/default.config.js +++ b/config/default.config.js @@ -1,5 +1,4 @@ const uiCore = require('../core/ui-core.js') const defaultConfig = uiCore('default_config') - -module.exports = defaultConfig +module.exports = defaultConfig \ No newline at end of file diff --git a/config/styles.config.js b/config/styles.config.js index 4ba52ba2..7c6d6c73 100644 --- a/config/styles.config.js +++ b/config/styles.config.js @@ -1 +1 @@ -module.exports = {} +module.exports = {} \ No newline at end of file diff --git a/config/user.config.js b/config/user.config.js index ef45ffdb..15f71ce0 100644 --- a/config/user.config.js +++ b/config/user.config.js @@ -1,10 +1,11 @@ const user = require('./default.config.js').user + module.exports = { node: 0, // set to mainnet server: { primary: { port: 12388, // set as default UI port - address: '0.0.0.0', // can specify an IP for a fixed bind - }, - }, -} + address: '0.0.0.0' // can specify an IP for a fixed bind + } + } +} \ No newline at end of file diff --git a/core/config/config.js b/core/config/config.js index 2e228fbc..ef8d5633 100644 --- a/core/config/config.js +++ b/core/config/config.js @@ -4,4 +4,4 @@ const user = require('./default.user.config.js') const styles = require('./default.styles.config.js') const build = require('./default.build.options.js') -module.exports = { coin, crypto, user, styles, build } +module.exports = { coin, crypto, user, styles, build } \ No newline at end of file diff --git a/core/config/default.build.options.js b/core/config/default.build.options.js index 0ad66df8..6940eaa1 100644 --- a/core/config/default.build.options.js +++ b/core/config/default.build.options.js @@ -4,132 +4,132 @@ const { makeSourceAbsolute } = require('../tooling/utils.js') const srcDir = '../src' const options = { - inputFile: path.join(__dirname, '../src/main.js'), - outputDir: path.join(__dirname, '../build'), - sassOutputDir: path.join(__dirname, '../build/styles.bundle.css'), - imgDir: path.join(__dirname, '../img') + inputFile: path.join(__dirname, '../src/main.js'), + outputDir: path.join(__dirname, '../build'), + sassOutputDir: path.join(__dirname, '../build/styles.bundle.css'), + imgDir: path.join(__dirname, '../img') } const aliases = { - 'qortal-ui-crypto': '../../crypto/api.js' + 'qortal-ui-crypto': '../../crypto/api.js' } const apiComponents = { - api: { - file: '../../crypto/api.js', - className: 'api' - } + api: { + file: '../../crypto/api.js', + className: 'api' + } } const functionalComponents = { - 'loading-ripple': { - file: 'functional-components/loading-ripple.js', - className: 'LoadingRipple' - }, - 'confirm-transaction-dialog': { - file: 'functional-components/confirm-transaction-dialog', - className: 'ConfirmTransactionDialog' - } + 'loading-ripple': { + file: 'functional-components/loading-ripple.js', + className: 'LoadingRipple' + }, + 'confirm-transaction-dialog': { + file: 'functional-components/confirm-transaction-dialog', + className: 'ConfirmTransactionDialog' + } } const inlineComponents = [ - { - className: 'worker', - input: path.join(__dirname, srcDir, 'worker.js'), - output: 'worker.js' - }, - { - className: 'PluginMainJSLoader', - input: path.join(__dirname, srcDir, '/plugins/plugin-mainjs-loader.js'), - output: 'plugins/plugin-mainjs-loader.js' - } + { + className: 'worker', + input: path.join(__dirname, srcDir, 'worker.js'), + output: 'worker.js' + }, + { + className: 'PluginMainJSLoader', + input: path.join(__dirname, srcDir, '/plugins/plugin-mainjs-loader.js'), + output: 'plugins/plugin-mainjs-loader.js' + } ] const elementComponents = { - 'main-app': { - file: 'components/main-app.js', - className: 'MainApp', - children: { - 'app-styles': { - file: 'styles/app-styles.js', - className: 'AppStyles', - children: { - 'app-theme': { - className: 'AppTheme', - file: 'styles/app-theme.js' - } - } - }, - 'app-view': { - file: 'components/app-view.js', - className: 'AppView', - children: { - 'show-plugin': { - file: 'components/show-plugin.js', - className: 'ShowPlugin' - }, - 'wallet-profile': { - file: 'components/wallet-profile.js', - className: 'WalletProfile' - }, - 'app-info': { - file: 'components/app-info.js', - className: 'AppInfo' - } - } - }, - 'login-view': { - file: 'components/login-view/login-view.js', - className: 'LoginView', - children: { - 'create-account-section': { - file: 'components/login-view/create-account-section.js', - className: 'CreateAccountSection' - }, - 'login-section': { - file: 'components/login-view/login-section.js', - className: 'LoginSection' - } - } - }, - 'settings-view': { - file: 'components/settings-view/user-settings.js', - className: 'UserSettings', - children: { - 'account-view': { - file: 'components/settings-view/account-view.js', - className: 'AccountView' - }, - 'security-view': { - file: 'components/settings-view/security-view.js', - className: 'SecurityView' - }, - 'qr-login-view': { - file: 'components/settings-view/qr-login-view.js', - className: 'QRLoginView' - }, - 'notifications-view': { - file: 'components/settings-view/notifications-view.js', - className: 'NotificationsView' - } - } - }, - 'user-info-view': { - file: 'components/user-info-view/user-info-view.js', - className: 'UserInfoView' - } - } - } + 'main-app': { + file: 'components/main-app.js', + className: 'MainApp', + children: { + 'app-styles': { + file: 'styles/app-styles.js', + className: 'AppStyles', + children: { + 'app-theme': { + className: 'AppTheme', + file: 'styles/app-theme.js' + } + } + }, + 'app-view': { + file: 'components/app-view.js', + className: 'AppView', + children: { + 'show-plugin': { + file: 'components/show-plugin.js', + className: 'ShowPlugin' + }, + 'wallet-profile': { + file: 'components/wallet-profile.js', + className: 'WalletProfile' + }, + 'app-info': { + file: 'components/app-info.js', + className: 'AppInfo' + } + } + }, + 'login-view': { + file: 'components/login-view/login-view.js', + className: 'LoginView', + children: { + 'create-account-section': { + file: 'components/login-view/create-account-section.js', + className: 'CreateAccountSection' + }, + 'login-section': { + file: 'components/login-view/login-section.js', + className: 'LoginSection' + } + } + }, + 'settings-view': { + file: 'components/settings-view/user-settings.js', + className: 'UserSettings', + children: { + 'account-view': { + file: 'components/settings-view/account-view.js', + className: 'AccountView' + }, + 'security-view': { + file: 'components/settings-view/security-view.js', + className: 'SecurityView' + }, + 'qr-login-view': { + file: 'components/settings-view/qr-login-view.js', + className: 'QRLoginView' + }, + 'notifications-view': { + file: 'components/settings-view/notifications-view.js', + className: 'NotificationsView' + } + } + }, + 'user-info-view': { + file: 'components/user-info-view/user-info-view.js', + className: 'UserInfoView' + } + } + } } makeSourceAbsolute(path.join(__dirname, srcDir), elementComponents) makeSourceAbsolute(path.join(__dirname, srcDir), functionalComponents) module.exports = { - options, - elementComponents, - functionalComponents, - inlineComponents, - apiComponents, - aliases -} + options, + elementComponents, + functionalComponents, + inlineComponents, + apiComponents, + aliases +} \ No newline at end of file diff --git a/core/config/default.coin.config.js b/core/config/default.coin.config.js index ef1dbb00..0f7775d1 100644 --- a/core/config/default.coin.config.js +++ b/core/config/default.coin.config.js @@ -1,11 +1,11 @@ const coin = { - name: 'Qortal', - symbol: 'QORT', - addressCount: 1, - addressVersion: 58, - decimals: 100000000, - logo: '/img/QORT_LOGO.png', - icon: '/img/QORT_LOGO.png' + name: 'Qortal', + symbol: 'QORT', + addressCount: 1, + addressVersion: 58, + decimals: 100000000, + logo: '/img/QORT_LOGO.png', + icon: '/img/QORT_LOGO.png' } -module.exports = coin +module.exports = coin \ No newline at end of file diff --git a/core/config/default.crypto.config.js b/core/config/default.crypto.config.js index f8a1b22d..270f7c5a 100644 --- a/core/config/default.crypto.config.js +++ b/core/config/default.crypto.config.js @@ -1,11 +1,11 @@ const crypto = { - kdfThreads: 16, - staticSalt: '4ghkVQExoneGqZqHTMMhhFfxXsVg2A75QeS1HCM5KAih', // Base58 encoded - bcryptRounds: 11, // Note it's kinda bcryptRounds * log.2.16, cause it runs on all 16 threads - bcryptVersion: '2a', - get staticBcryptSalt () { - return `$${this.bcryptVersion}$${this.bcryptRounds}$IxVE941tXVUD4cW0TNVm.O` - } + kdfThreads: 16, + staticSalt: '4ghkVQExoneGqZqHTMMhhFfxXsVg2A75QeS1HCM5KAih', // Base58 encoded + bcryptRounds: 11, // Note it's kinda bcryptRounds * log.2.16, cause it runs on all 16 threads + bcryptVersion: '2a', + get staticBcryptSalt() { + return `$${this.bcryptVersion}$${this.bcryptRounds}$IxVE941tXVUD4cW0TNVm.O` + } } -module.exports = crypto +module.exports = crypto \ No newline at end of file diff --git a/core/config/default.styles.config.js b/core/config/default.styles.config.js index 17123264..b99bff62 100644 --- a/core/config/default.styles.config.js +++ b/core/config/default.styles.config.js @@ -1,40 +1,41 @@ const styles = { - breakpoints: { - desktop: '', - laptop: '', - tablet: '', - mobile: '' - }, - theme: { - colors: { - primary: '#03a9f4', /* Sets the text color to the theme primary color. */ - primaryBg: '#e8eaf6', /* Sets the background color to the theme primary color. */ - onPrimary: '#fff', /* Sets the text color to the color configured for text on the primary color. */ + breakpoints: { + desktop: '', + laptop: '', + tablet: '', + mobile: '' + }, + theme: { + colors: { + primary: '#03a9f4', /* Sets the text color to the theme primary color. */ + primaryBg: '#e8eaf6', /* Sets the background color to the theme primary color. */ + onPrimary: '#fff', /* Sets the text color to the color configured for text on the primary color. */ - secondary: '#03a9f4', /* Sets the text color to the theme secondary color. */ - secondaryBg: '#fce4ec', /* Sets the background color to the theme secondary color. */ - onSecondary: '#fff', /* Sets the text color to the color configured for text on the secondary color. */ + secondary: '#03a9f4', /* Sets the text color to the theme secondary color. */ + secondaryBg: '#fce4ec', /* Sets the background color to the theme secondary color. */ + onSecondary: '#fff', /* Sets the text color to the color configured for text on the secondary color. */ - surface: '#fff', /* Sets the background color to the surface background color. */ - onSurface: '#333', /* Sets the text color to the color configured for text on the surface color. */ - background: '#eee', /* Sets the background color to the theme background color. */ + surface: '#fff', /* Sets the background color to the surface background color. */ + onSurface: '#333', /* Sets the text color to the color configured for text on the surface color. */ + background: '#eee', /* Sets the background color to the theme background color. */ - warning: '#FFA000', - error: '#F44336' - }, + warning: '#FFA000', + error: '#F44336' + }, - addressColors: [ - '#256480', - '#002530', - '#02564e', - '#d32f2f', - '#795548', - '#004d40', - '#006064', - '#9c27b0', - '#2196f3', - '#d81b60' - ] - } + addressColors: [ + '#256480', + '#002530', + '#02564e', + '#d32f2f', + '#795548', + '#004d40', + '#006064', + '#9c27b0', + '#2196f3', + '#d81b60' + ] + } } -module.exports = styles + +module.exports = styles \ No newline at end of file diff --git a/core/config/default.user.config.js b/core/config/default.user.config.js index fb0363b7..e5f02519 100644 --- a/core/config/default.user.config.js +++ b/core/config/default.user.config.js @@ -1,42 +1,43 @@ const path = require('path') const user = { - node: 0, - nodeSettings: { - pingInterval: 30 * 1000, - }, - server: { - writeHosts: { - enabled: true, - }, - relativeTo: path.join(__dirname, '../'), - primary: { - domain: '0.0.0.0', - address: '0.0.0.0', - port: 12388, - directory: './src/', - page404: './src/404.html', - host: '0.0.0.0', - }, - }, - tls: { - enabled: false, - options: { - key: '', - cert: '', - }, - }, - constants: { - pollingInterval: 30 * 1000, // How long between checking for new unconfirmed transactions and new blocks (in milliseconds). - workerURL: '/build/worker.js', - }, + node: 0, + nodeSettings: { + pingInterval: 30 * 1000 + }, + server: { + writeHosts: { + enabled: true + }, + relativeTo: path.join(__dirname, '../'), + primary: { + domain: '0.0.0.0', + address: '0.0.0.0', + port: 12388, + directory: './src/', + page404: './src/404.html', + host: '0.0.0.0' + } + }, + tls: { + enabled: false, + options: { + key: '', + cert: '' + } + }, + constants: { + pollingInterval: 30 * 1000, // How long between checking for new unconfirmed transactions and new blocks (in milliseconds). + workerURL: '/build/worker.js' + }, - // Notification Settings (All defaults to true) - notifications: { - q_chat: { - playSound: true, - showNotification: true, - }, - }, + // Notification Settings (All defaults to true) + notifications: { + q_chat: { + playSound: true, + showNotification: true + } + } } -module.exports = user + +module.exports = user \ No newline at end of file diff --git a/core/config/load-config.js b/core/config/load-config.js index c6d7ae44..0ad62ace 100644 --- a/core/config/load-config.js +++ b/core/config/load-config.js @@ -1,21 +1,22 @@ let config = require('./config.js') const checkKeys = (storeObj, newObj) => { - for (const key in newObj) { - if (!Object.prototype.hasOwnProperty.call(storeObj, key)) return + for (const key in newObj) { + if (!Object.prototype.hasOwnProperty.call(storeObj, key)) return - if (typeof newObj[key] === 'object') { - storeObj[key] = checkKeys(storeObj[key], newObj[key]) - } else { - storeObj[key] = newObj[key] - } - } - return storeObj + if (typeof newObj[key] === 'object') { + storeObj[key] = checkKeys(storeObj[key], newObj[key]) + } else { + storeObj[key] = newObj[key] + } + } + + return storeObj } const getConfig = customConfig => { - config = checkKeys(config, customConfig) - return config + config = checkKeys(config, customConfig) + return config } -module.exports = getConfig +module.exports = getConfig \ No newline at end of file diff --git a/core/font/switch-theme.css b/core/font/switch-theme.css index e7e27c5b..4c56f166 100644 --- a/core/font/switch-theme.css +++ b/core/font/switch-theme.css @@ -6,6 +6,7 @@ html { --plugback: #ffffff; --border: #d0d6de; --border2: #dde2e8; + --border3: #080808; --copybutton: #707584; --chat-group: #080808; --chat-bubble: #9f9f9f0a; @@ -83,6 +84,7 @@ html[theme="dark"] { --plugback: #0f1a2e; --border: #0b305e; --border2: #0b305e; + --border3: #767676; --copybutton: #d0d6de; --chat-group: #ffffff; --chat-bubble: #9694941a; diff --git a/core/language/us.json b/core/language/us.json index 203007d9..85af3543 100644 --- a/core/language/us.json +++ b/core/language/us.json @@ -945,7 +945,16 @@ "gchange56": "Group Name To Search", "gchange57": "Private Group Name Not Found", "gchange58": "Note that group name must be an exact match.", - "gchange59": "Show / Hide Ticker" + "gchange59": "Show / Hide Ticker", + "gchange60": "Please enter an group name", + "gchange61": "Please enter an description", + "gchange62": "Are you sure to update this group?", + "gchange63": "On pressing confirm, the update group request will be sent!", + "gchange64": "Current Owner / New Owner", + "gchange65": "Only replace this address if you want to transfer the group!", + "gchange66": "Invalid Owner / New Owner Address", + "gchange67": "Group Update Successful!", + "gchange68": "Set Group Avatar" }, "puzzlepage": { "pchange1": "Puzzles", diff --git a/core/public/index.html b/core/public/index.html index 4fdc606c..76ff26e4 100644 --- a/core/public/index.html +++ b/core/public/index.html @@ -1,139 +1,121 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Qortal UI - - - - - - - -
- - - - - -
- - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + Qortal UI + + + + +
+ + +
+ + diff --git a/core/server/ServerFactory.js b/core/server/ServerFactory.js index e4d2c5be..4c8b6a3f 100644 --- a/core/server/ServerFactory.js +++ b/core/server/ServerFactory.js @@ -3,32 +3,33 @@ const Hapi = require('@hapi/hapi') const Inert = require('@hapi/inert') function serverFactory(routes, address, port, tls) { - this.server = new Hapi.Server({ - routes: { - files: { - relativeTo: Path.join(__dirname, '../') - } - }, - address: address, - port: port, - tls: tls - }) + this.server = new Hapi.Server({ + routes: { + files: { + relativeTo: Path.join(__dirname, '../') + } + }, + address: address, + port: port, + tls: tls + }) - this.startServer = async () => { - try { - await this.server.register([Inert]) + this.startServer = async () => { + try { + await this.server.register([Inert]) - this.server.route(routes) + this.server.route(routes) - await this.server.start() + await this.server.start() - delete this.startServer - return this.server - } catch (e) { - console.error(e) - throw e - } - } + delete this.startServer + + return this.server + } catch (e) { + console.error(e) + throw e + } + } } -module.exports = serverFactory +module.exports = serverFactory \ No newline at end of file diff --git a/core/server/routes/createCommonRoutes.js b/core/server/routes/createCommonRoutes.js index 4eed35f7..5ba2df12 100644 --- a/core/server/routes/createCommonRoutes.js +++ b/core/server/routes/createCommonRoutes.js @@ -1,106 +1,106 @@ const path = require('path') const routesOptions = { - security: { - hsts: { - maxAge: 15768000, - includeSubDomains: true, - preload: true - }, - xframe: 'sameorigin' - } + security: { + hsts: { + maxAge: 15768000, + includeSubDomains: true, + preload: true + }, + xframe: 'sameorigin' + } } const createRoutes = config => [ + { + method: 'GET', + path: '/img/{param*}', + handler: { + directory: { + path: config.build.options.imgDir, + redirectToSlash: true, + index: true + } + }, + options: routesOptions + }, + { + method: 'GET', + path: '/language/{param*}', + handler: { + directory: { + path: path.join(__dirname, '../../language'), + redirectToSlash: true, + index: true + } + }, + options: routesOptions + }, + { + method: 'GET', + path: '/font/{param*}', + handler: { + directory: { + path: path.join(__dirname, '../../font'), + redirectToSlash: true, + index: true + } + }, + options: routesOptions + }, + { + method: 'GET', + path: '/sound/{param*}', + handler: { + directory: { + path: path.join(__dirname, '../../sound/'), + redirectToSlash: true, + index: true + } + }, + options: routesOptions + }, + { + method: 'GET', + path: '/emoji/{param*}', + handler: { + directory: { + path: path.join(__dirname, '../../emoji/'), + redirectToSlash: true, + index: true + } + }, + options: routesOptions + }, + { + method: 'GET', + path: '/memory-pow/{param*}', + handler: { + directory: { + path: path.join(__dirname, '../../memory-pow/'), + redirectToSlash: true, + index: true + } + }, + options: routesOptions + }, + { + method: 'GET', + path: '/getConfig', + handler: (request, h) => { + const response = { + config: { + ...config + } + } - { - method: 'GET', - path: '/img/{param*}', - handler: { - directory: { - path: config.build.options.imgDir, - redirectToSlash: true, - index: true - } - }, - options: routesOptions - }, - { - method: 'GET', - path: '/language/{param*}', - handler: { - directory: { - path: path.join(__dirname, '../../language'), - redirectToSlash: true, - index: true - } - }, - options: routesOptions - }, - { - method: 'GET', - path: '/font/{param*}', - handler: { - directory: { - path: path.join(__dirname, '../../font'), - redirectToSlash: true, - index: true - } - }, - options: routesOptions - }, - { - method: 'GET', - path: '/sound/{param*}', - handler: { - directory: { - path: path.join(__dirname, '../../sound/'), - redirectToSlash: true, - index: true - } - }, - options: routesOptions - }, - { - method: 'GET', - path: '/emoji/{param*}', - handler: { - directory: { - path: path.join(__dirname, '../../emoji/'), - redirectToSlash: true, - index: true - } - }, - options: routesOptions - }, - { - method: 'GET', - path: '/memory-pow/{param*}', - handler: { - directory: { - path: path.join(__dirname, '../../memory-pow/'), - redirectToSlash: true, - index: true - } - }, - options: routesOptions - }, - { - method: 'GET', - path: '/getConfig', - handler: (request, h) => { - const response = { - config: { - ...config - } - } + delete response.config.user.tls + delete response.config.build - delete response.config.user.tls - delete response.config.build - return JSON.stringify(response) - }, - options: routesOptions - } + return JSON.stringify(response) + }, + options: routesOptions + } ] -module.exports = createRoutes +module.exports = createRoutes \ No newline at end of file diff --git a/core/server/routes/createPrimaryRoutes.js b/core/server/routes/createPrimaryRoutes.js index ef398aae..0eae497c 100644 --- a/core/server/routes/createPrimaryRoutes.js +++ b/core/server/routes/createPrimaryRoutes.js @@ -1,141 +1,140 @@ const path = require('path') - const createCommonRoutes = require('./createCommonRoutes.js') const createPrimaryRoutes = (config, plugins) => { - const routes = createCommonRoutes(config) + const routes = createCommonRoutes(config) - let myPlugins = plugins + let myPlugins = plugins - const pluginFolders = {} + const pluginFolders = {} - const routesOptions = { - security: { - hsts: { - maxAge: 15768000, - includeSubDomains: true, - preload: true - }, - xframe: 'sameorigin' - } - } + const routesOptions = { + security: { + hsts: { + maxAge: 15768000, + includeSubDomains: true, + preload: true + }, + xframe: 'sameorigin' + } + } - plugins.reduce((obj, plugin) => { - obj[plugin.name] = plugin.folder - return obj - }, pluginFolders) + plugins.reduce((obj, plugin) => { + obj[plugin.name] = plugin.folder + return obj + }, pluginFolders) - routes.push( - { - method: 'GET', - path: '/', - handler: (request, reply) => { - return reply.redirect('/app') - }, - options: routesOptions - }, - { - method: 'GET', - path: '/{path*}', - handler: (request, h) => { - const filePath = path.join(__dirname, '../../public/index.html') - const response = h.file(filePath, { - confine: true - }) - response.header('Access-Control-Allow-Origin', request.info.host) - return response - }, - options: routesOptions - }, - { - method: 'GET', - path: '/getPlugins', - handler: (request, h) => { - return { plugins: myPlugins.map(p => p.name) } - }, - options: routesOptions - }, - { - method: 'GET', - path: '/build/{param*}', - handler: { - directory: { - path: config.build.options.outputDir, - redirectToSlash: true, - index: true - } - }, - options: routesOptions - }, - { - method: 'GET', - path: '/src/{param*}', - handler: { - directory: { - path: path.join(__dirname, '../../src'), - redirectToSlash: true, - index: true - } - }, - options: routesOptions - }, - { - method: 'GET', - path: '/plugin/{path*}', - handler: (request, h) => { + routes.push( + { + method: 'GET', + path: '/', + handler: (request, reply) => { + return reply.redirect('/app') + }, + options: routesOptions + }, + { + method: 'GET', + path: '/{path*}', + handler: (request, h) => { + const filePath = path.join(__dirname, '../../public/index.html') + const response = h.file(filePath, { + confine: true + }) + response.header('Access-Control-Allow-Origin', request.info.host) + return response + }, + options: routesOptions + }, + { + method: 'GET', + path: '/getPlugins', + handler: (request, h) => { + return { plugins: myPlugins.map(p => p.name) } + }, + options: routesOptions + }, + { + method: 'GET', + path: '/build/{param*}', + handler: { + directory: { + path: config.build.options.outputDir, + redirectToSlash: true, + index: true + } + }, + options: routesOptions + }, + { + method: 'GET', + path: '/src/{param*}', + handler: { + directory: { + path: path.join(__dirname, '../../src'), + redirectToSlash: true, + index: true + } + }, + options: routesOptions + }, + { + method: 'GET', + path: '/plugin/{path*}', + handler: (request, h) => { - const plugin = request.params.path.split('/')[0] - const filePath = path.join(pluginFolders[plugin], '../', request.params.path) + const plugin = request.params.path.split('/')[0] + const filePath = path.join(pluginFolders[plugin], '../', request.params.path) - const response = h.file(filePath, { - confine: false - }) - response.header('Access-Control-Allow-Origin', request.info.host) - return response - }, - options: routesOptions - }, - { - method: 'GET', - path: '/plugin/404', - handler: (request, h) => { - const response = h.file(path.join(config.server.primary.page404)) - response.header('Access-Control-Allow-Origin', request.info.host) - return response - }, - options: routesOptions - }, - { - method: 'GET', - path: '/qortal-components/plugin-mainjs-loader.html', - handler: (request, h) => { - const response = h.file(path.join(__dirname, '../../src/plugins/plugin-mainjs-loader.html'), { - confine: false - }) - response.header('Access-Control-Allow-Origin', request.info.host) - return response - }, - options: routesOptions - }, - { - method: 'GET', - path: '/qortal-components/plugin-mainjs-loader.js', - handler: (request, h) => { - const file = path.join(config.build.options.outputDir, '/plugins/plugin-mainjs-loader.js') + const response = h.file(filePath, { + confine: false + }) + response.header('Access-Control-Allow-Origin', request.info.host) + return response + }, + options: routesOptions + }, + { + method: 'GET', + path: '/plugin/404', + handler: (request, h) => { + const response = h.file(path.join(config.server.primary.page404)) + response.header('Access-Control-Allow-Origin', request.info.host) + return response + }, + options: routesOptions + }, + { + method: 'GET', + path: '/qortal-components/plugin-mainjs-loader.html', + handler: (request, h) => { + const response = h.file(path.join(__dirname, '../../src/plugins/plugin-mainjs-loader.html'), { + confine: false + }) + response.header('Access-Control-Allow-Origin', request.info.host) + return response + }, + options: routesOptions + }, + { + method: 'GET', + path: '/qortal-components/plugin-mainjs-loader.js', + handler: (request, h) => { + const file = path.join(config.build.options.outputDir, '/plugins/plugin-mainjs-loader.js') - const response = h.file(file, { - confine: false - }) - response.header('Access-Control-Allow-Origin', request.info.host) - return response - }, - options: routesOptions - }, + const response = h.file(file, { + confine: false + }) + response.header('Access-Control-Allow-Origin', request.info.host) + return response + }, + options: routesOptions + } - ) + ) - return routes + return routes } -module.exports = createPrimaryRoutes +module.exports = createPrimaryRoutes \ No newline at end of file diff --git a/core/server/server.js b/core/server/server.js index 5ccf2618..2a562b55 100644 --- a/core/server/server.js +++ b/core/server/server.js @@ -3,22 +3,20 @@ const ServerFactory = require('./ServerFactory.js') const createPrimaryRoutes = require('./routes/createPrimaryRoutes.js') const createServer = (config, plugins) => { - this.start = async function () { - const primaryServer = new ServerFactory(createPrimaryRoutes(config, plugins), config.user.server.primary.host, config.user.server.primary.port, config.user.tls.enabled ? config.user.tls.options : void 0) - primaryServer.startServer() - .then(server => { - console.log(`Qortal UI Server started at ${server.info.uri} and listening on ${server.info.address}`) - }) - .catch(e => { - console.error(e) - }) - } - return this -} + this.start = async function () { + const primaryServer = new ServerFactory(createPrimaryRoutes(config, plugins), config.user.server.primary.host, config.user.server.primary.port, config.user.tls.enabled ? config.user.tls.options : void 0) + primaryServer.startServer().then(server => { + console.log(`Qortal UI Server started at ${server.info.uri} and listening on ${server.info.address}`) + }).catch(e => { + console.error(e) + }) + } + return this +} const serverExports = { - createServer + createServer } -module.exports = serverExports +module.exports = serverExports \ No newline at end of file diff --git a/core/src/apiKeyUtils.js b/core/src/apiKeyUtils.js index e65772b0..08d23ce1 100644 --- a/core/src/apiKeyUtils.js +++ b/core/src/apiKeyUtils.js @@ -1,54 +1,55 @@ import * as api from 'qortal-ui-crypto' -import mykey from './functional-components/mykey-page.js' - -'use strict' +import mykey from './functional-components/mykey-page' export const checkApiKey = async (nodeConfig) => { + let selectedNode = nodeConfig.knownNodes[nodeConfig.node] + let apiKey = selectedNode.apiKey - let selectedNode = nodeConfig.knownNodes[nodeConfig.node]; - let apiKey = selectedNode.apiKey; + // Attempt to generate an API key + const generateUrl = '/admin/apikey/generate' - // Attempt to generate an API key - const generateUrl = "/admin/apikey/generate"; - let generateRes = await api.request(generateUrl, { - method: "POST" - }); + let generateRes = await api.request(generateUrl, { + method: 'POST' + }) - if (generateRes != null && generateRes.error == null && generateRes.length >= 8) { - console.log("Generated API key"); - apiKey = generateRes; + if (generateRes != null && generateRes.error == null && generateRes.length >= 8) { + console.log('Generated API key') - // Store the generated API key - selectedNode.apiKey = apiKey; - nodeConfig.knownNodes[nodeConfig.node] = selectedNode; - localStorage.setItem('myQortalNodes', JSON.stringify(nodeConfig.knownNodes)); - } - else { - console.log("Unable to generate API key"); - } + apiKey = generateRes - // Now test the API key - let testResult = await testApiKey(apiKey); - if (testResult === true) { - console.log("API key test passed"); - } - else { - console.log("API key test failed"); - mykey.show(); - this.dispatchEvent( + // Store the generated API key + selectedNode.apiKey = apiKey + nodeConfig.knownNodes[nodeConfig.node] = selectedNode + localStorage.setItem('myQortalNodes', JSON.stringify(nodeConfig.knownNodes)) + } else { + console.log("Unable to generate API key") + } + + // Now test the API key + let testResult = await testApiKey(apiKey) + + if (testResult === true) { + console.log('API key test passed') + } else { + console.log('API key test failed') + + mykey.show() + + this.dispatchEvent( new CustomEvent('disable-tour', { - bubbles: true, - composed: true - }), - ); - } + bubbles: true, + composed: true + }) + ) + } } export const testApiKey = async (apiKey) => { - const testUrl = "/admin/apikey/test?apiKey=" + apiKey; - let testRes = await api.request(testUrl, { - method: "GET" - }); - return testRes === true; + const testUrl = '/admin/apikey/test?apiKey=' + apiKey -} + let testRes = await api.request(testUrl, { + method: 'GET' + }) + + return testRes === true +} \ No newline at end of file diff --git a/core/src/components/WebWorkerFile.js b/core/src/components/WebWorkerFile.js index 3b8c2b87..ab699e69 100644 --- a/core/src/components/WebWorkerFile.js +++ b/core/src/components/WebWorkerFile.js @@ -1,5 +1,3 @@ -import WebWorker from 'web-worker:./computePowWorkerFile.js'; +import WebWorker from 'web-worker:./computePowWorkerFile.js' -// You can add any initialization or configuration for the Web Worker here - -export default WebWorker; \ No newline at end of file +export default WebWorker \ No newline at end of file diff --git a/core/src/components/app-info.js b/core/src/components/app-info.js index 46aacbbe..d05fa7ca 100644 --- a/core/src/components/app-info.js +++ b/core/src/components/app-info.js @@ -1,147 +1,107 @@ -import {css, html, LitElement} from 'lit' -import {connect} from 'pwa-helpers' -import {store} from '../store.js' -import {translate} from '../../translate' +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../store' +import { appInfoStyles } from '../styles/core-css' + +// Multi language support +import { translate } from '../../translate' class AppInfo extends connect(store)(LitElement) { - static get properties() { - return { - nodeInfo: { type: Array }, - coreInfo: { type: Array }, - nodeConfig: { type: Object }, - theme: { type: String, reflect: true } - } - } + static get properties() { + return { + nodeInfo: { type: Array }, + coreInfo: { type: Array }, + nodeConfig: { type: Object }, + theme: { type: String, reflect: true } + } + } - static get styles() { - return css` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --paper-input-container-focus-color: var(--mdc-theme-primary); - } + static get styles() { + return [appInfoStyles] + } - .normal { - --mdc-theme-primary: rgb(3, 169, 244); - } + constructor() { + super() + this.nodeInfo = [] + this.coreInfo = [] + this.nodeConfig = {} + this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' + } - #profileInMenu { - flex: 0 0 100px; - padding:12px; - border-top: 1px solid var(--border); - background: var(--sidetopbar); - } + render() { + return html` +
+ ${translate("appinfo.uiversion")}: ${this.nodeConfig.version ? this.nodeConfig.version : ''} + ${this._renderCoreVersion()} + ${translate("appinfo.blockheight")}: ${this.nodeInfo.height ? this.nodeInfo.height : ''} ${this._renderStatus()} + ${translate("appinfo.peers")}: ${this.nodeInfo.numberOfConnections ? this.nodeInfo.numberOfConnections : ''} +
+ ` + } - .info { - margin: 0; - font-size: 14px; - font-weight: 100; - display: inline-block; - width: 100%; - padding-bottom: 8px; - color: var(--black); - } + firstUpdated() { + this.getNodeInfo() + this.getCoreInfo() - .blue { - color: #03a9f4; - margin: 0; - font-size: 14px; - font-weight: 200; - display: inline; - } + setInterval(() => { + this.getNodeInfo() + this.getCoreInfo() + }, 60000) + } - .black { - color: var(--black); - margin: 0; - font-size: 14px; - font-weight: 200; - display: inline; - } - ` - } + async getNodeInfo() { + const appinfoNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + const appinfoUrl = appinfoNode.protocol + '://' + appinfoNode.domain + ':' + appinfoNode.port + const url = `${appinfoUrl}/admin/status` - constructor() { - super() - this.nodeInfo = [] - this.coreInfo = [] - this.nodeConfig = {} - this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' - } + await fetch(url).then(response => { + return response.json() + }).then(data => { + this.nodeInfo = data + }).catch(err => { + console.error('Request failed', err) + }) + } - render() { - return html` -
- ${translate("appinfo.uiversion")}: ${this.nodeConfig.version ? this.nodeConfig.version : ''} - ${this._renderCoreVersion()} - ${translate("appinfo.blockheight")}: ${this.nodeInfo.height ? this.nodeInfo.height : ''} ${this._renderStatus()} - ${translate("appinfo.peers")}: ${this.nodeInfo.numberOfConnections ? this.nodeInfo.numberOfConnections : ''} - -
- ` - } + async getCoreInfo() { + const appinfoNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + const appinfoUrl = appinfoNode.protocol + '://' + appinfoNode.domain + ':' + appinfoNode.port + const url = `${appinfoUrl}/admin/info` - firstUpdated() { - this.getNodeInfo() - this.getCoreInfo() + await fetch(url).then(response => { + return response.json() + }).then(data => { + this.coreInfo = data + }).catch(err => { + console.error('Request failed', err) + }) + } - setInterval(() => { - this.getNodeInfo() - this.getCoreInfo() - }, 60000) - } + _renderStatus() { + if (this.nodeInfo.isMintingPossible === true && this.nodeInfo.isSynchronizing === true) { + this.cssStatus = 'blue' + return html`${translate("appinfo.minting")}` + } else if (this.nodeInfo.isMintingPossible === true && this.nodeInfo.isSynchronizing === false) { + this.cssStatus = 'blue' + return html`${translate("appinfo.minting")}` + } else if (this.nodeInfo.isMintingPossible === false && this.nodeInfo.isSynchronizing === true) { + this.cssStatus = 'black' + return html`(${translate("appinfo.synchronizing")}... ${this.nodeInfo.syncPercent !== undefined ? this.nodeInfo.syncPercent + '%' : ''})` + } else if (this.nodeInfo.isMintingPossible === false && this.nodeInfo.isSynchronizing === false) { + this.cssStatus = 'black' + return '' + } else { + return '' + } + } - async getNodeInfo() { - const appinfoNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] - const appinfoUrl = appinfoNode.protocol + '://' + appinfoNode.domain + ':' + appinfoNode.port - const url = `${appinfoUrl}/admin/status` + _renderCoreVersion() { + return html`${translate("appinfo.coreversion")}: ${this.coreInfo.buildVersion ? this.coreInfo.buildVersion : ''}` + } - await fetch(url).then(response => { - return response.json() - }).then(data => { - this.nodeInfo = data - }).catch(err => { - console.error('Request failed', err) - }) - } - - async getCoreInfo() { - const appinfoNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] - const appinfoUrl = appinfoNode.protocol + '://' + appinfoNode.domain + ':' + appinfoNode.port - const url = `${appinfoUrl}/admin/info` - - await fetch(url).then(response => { - return response.json() - }).then(data => { - this.coreInfo = data - }).catch(err => { - console.error('Request failed', err) - }) - } - - _renderStatus() { - if (this.nodeInfo.isMintingPossible === true && this.nodeInfo.isSynchronizing === true) { - this.cssStatus = 'blue' - return html`${translate("appinfo.minting")}` - } else if (this.nodeInfo.isMintingPossible === true && this.nodeInfo.isSynchronizing === false) { - this.cssStatus = 'blue' - return html`${translate("appinfo.minting")}` - } else if (this.nodeInfo.isMintingPossible === false && this.nodeInfo.isSynchronizing === true) { - this.cssStatus = 'black' - return html`(${translate("appinfo.synchronizing")}... ${this.nodeInfo.syncPercent !== undefined ? this.nodeInfo.syncPercent + '%' : ''})` - } else if (this.nodeInfo.isMintingPossible === false && this.nodeInfo.isSynchronizing === false) { - this.cssStatus = 'black' - return '' - } else { - return '' - } - } - - _renderCoreVersion() { - return html`${translate("appinfo.coreversion")}: ${this.coreInfo.buildVersion ? this.coreInfo.buildVersion : ''}` - } - - stateChanged(state) { - this.nodeConfig = state.app.nodeConfig - } + stateChanged(state) { + this.nodeConfig = state.app.nodeConfig + } } -window.customElements.define('app-info', AppInfo) +window.customElements.define('app-info', AppInfo) \ No newline at end of file diff --git a/core/src/components/app-view.js b/core/src/components/app-view.js index 612d3a2a..d458a54e 100644 --- a/core/src/components/app-view.js +++ b/core/src/components/app-view.js @@ -1,20 +1,43 @@ -import {css, html, LitElement} from 'lit' -import {connect} from 'pwa-helpers' -import {store} from '../store.js' -import {Epml} from '../epml.js' -import {addTradeBotRoutes} from '../tradebot/addTradeBotRoutes.js' -import {get, translate} from '../../translate' -import localForage from 'localforage' -import {decryptData, encryptData} from '../lockScreen.js' -import {setChatLastSeen} from '../redux/app/app-actions.js' +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../store' +import { Epml } from '../epml' +import { addTradeBotRoutes } from '../tradebot/addTradeBotRoutes' +import { get, translate } from '../../translate' +import { decryptData, encryptData } from '../lockScreen' +import { setChatLastSeen } from '../redux/app/app-actions' +import { appViewStyles } from '../styles/core-css' import isElectron from 'is-electron' +import localForage from 'localforage' +import './app-info' +import './check-for-update' +import './new-selector' +import './search-modal' +import './show-plugin' +import './theme-toggle' +import './wallet-profile' +import './controllers/coin-balances-controller' +import './beginner-tour/tour-component' +import './beginner-tour/sync-indicator' +import './friends-view/beginner-checklist' +import './friends-view/core-sync-status' +import './friends-view/friends-side-panel-parent' +import './friends-view/profile' +import './friends-view/save-settings-qdn' +import './logout-view/logout-view' +import './notification-view/notification-bell' +import './notification-view/notification-bell-general' +import './settings-view/user-settings' +import './user-info-view/user-info-view' +import '../functional-components/side-menu' +import '../functional-components/side-menu-item' import '@material/mwc-button' import '@material/mwc-icon' -import '@polymer/paper-icon-button/paper-icon-button.js' -import '@polymer/paper-progress/paper-progress.js' -import '@polymer/paper-dialog/paper-dialog.js' -import '@polymer/iron-icons/iron-icons.js' import '@polymer/app-layout/app-layout.js' +import '@polymer/iron-icons/iron-icons.js' +import '@polymer/paper-icon-button/paper-icon-button.js' +import '@polymer/paper-dialog/paper-dialog.js' +import '@polymer/paper-progress/paper-progress.js' import '@polymer/paper-ripple' import '@vaadin/button' import '@vaadin/icon' @@ -23,3326 +46,3042 @@ import '@vaadin/password-field' import '@vaadin/text-field' import '@vaadin/tooltip' -import './wallet-profile.js' -import './app-info.js' -import './show-plugin.js' -import './theme-toggle.js' -import './new-selector.js' -import './settings-view/user-settings.js' -import './logout-view/logout-view.js' -import './check-for-update.js' -import './search-modal.js' -import './user-info-view/user-info-view.js' -import '../functional-components/side-menu.js' -import '../functional-components/side-menu-item.js' -import './notification-view/notification-bell.js' -import './notification-view/notification-bell-general.js' -import './friends-view/friends-side-panel-parent.js' -import './friends-view/save-settings-qdn.js' -import './friends-view/core-sync-status.js' -import './friends-view/profile.js' -import './beginner-tour/tour-component.js' -import './beginner-tour/sync-indicator.js' -import './friends-view/beginner-checklist.js' -import './controllers/coin-balances-controller.js' - const chatLastSeen = localForage.createInstance({ - name: "chat-last-seen", + name: 'chat-last-seen' }) const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) class AppView extends connect(store)(LitElement) { - static get properties() { - return { - config: { type: Object }, - urls: { type: Object }, - nodeType: { type: String, reflect: true }, - theme: { type: String, reflect: true }, - addressInfo: { type: Object }, - botQortWallet: { type: String }, - botBtcWallet: { type: String }, - botLtcWallet: { type: String }, - botDogeWallet: { type: String }, - botDgbWallet: { type: String }, - botRvnWallet: { type: String }, - botArrrWallet: { type: String }, - arrrWalletAddress: { type: String }, - qortWalletBalance: { type: Number }, - btcWalletBalance: { type: Number }, - ltcWalletBalance: { type: Number }, - dogeWalletBalance: { type: Number }, - dgbWalletBalance: { type: Number }, - rvnWalletBalance: { type: Number }, - arrrWalletBalance: { type: Number }, - failedTradesList: { type: Array }, - tradesOpenBtcQortal: { type: Array }, - myTradesOpenLtcQortal: { type: Array }, - tradesFailedBtcQortal: { type: Array }, - tradesOpenBtcQortalCleaned: { type: Array }, - tradesOpenLtcQortal: { type: Array }, - tradesFailedLtcQortal: { type: Array }, - tradesOpenLtcQortalCleaned: { type: Array }, - tradesOpenDogeQortal: { type: Array }, - tradesFailedDogeQortal: { type: Array }, - tradesOpenDogeQortalCleaned: { type: Array }, - tradesOpenDgbQortal: { type: Array }, - tradesFailedDgbQortal: { type: Array }, - tradesOpenDgbQortalCleaned: { type: Array }, - tradesOpenRvnQortal: { type: Array }, - tradesFailedRvnQortal: { type: Array }, - tradesOpenRvnQortalCleaned: { type: Array }, - tradesOpenArrrQortal: { type: Array }, - tradesFailedArrrQortal: { type: Array }, - tradesOpenArrrQortalCleaned: { type: Array }, - tradeBotBtcBook: { type: Array }, - tradeBotLtcBook: { type: Array }, - tradeBotDogeBook: { type: Array }, - tradeBotDgbBook: { type: Array }, - tradeBotRvnBook: { type: Array }, - tradeBotArrrBook: { type: Array }, - tradeBotBtcAt: { type: Array }, - tradeBotLtcAt: { type: Array }, - tradeBotDogeAt: { type: Array }, - tradeBotDgbAt: { type: Array }, - tradeBotRvnAt: { type: Array }, - tradeBotArrrAt: { type: Array }, - tradeBotAvailableBtcQortal: { type: Array }, - tradeBotAvailableLtcQortal: { type: Array }, - tradeBotAvailableDogeQortal: { type: Array }, - tradeBotAvailableDgbQortal: { type: Array }, - tradeBotAvailableRvnQortal: { type: Array }, - tradeBotAvailableArrrQortal: { type: Array }, - checkBtcAlice: { type: String }, - checkLtcAlice: { type: String }, - checkDogeAlice: { type: String }, - checkDgbAlice: { type: String }, - checkRvnAlice: { type: String }, - checkArrrAlice: { type: String }, - reAddBtcAmount: { type: Number }, - reAddLtcAmount: { type: Number }, - reAddDogeAmount: { type: Number }, - reAddDgbAmount: { type: Number }, - reAddRvnAmount: { type: Number }, - reAddArrrAmount: { type: Number }, - reAddBtcPrice: { type: Number }, - reAddLtcPrice: { type: Number }, - reAddDogePrice: { type: Number }, - reAddDgbPrice: { type: Number }, - reAddRvnPrice: { type: Number }, - reAddArrrPrice: { type: Number }, - botBtcBuyAtAddress: { type: String }, - botLtcBuyAtAddress: { type: String }, - botDogeBuyAtAddress: { type: String }, - botDgbBuyAtAddress: { type: String }, - botRvnBuyAtAddress: { type: String }, - botArrrBuyAtAddress: { type: String }, - balanceTicker: { type: String }, - salt: { type: String }, - storageData: { type: String }, - lockScreenPass: { type: String }, - lockScreenSet: { type: String }, - lockPass: { type: String }, - lockSet: { type: String }, - myLockScreenPass: { type: String }, - myLockScreenSet: { type: String }, - helperMessage: { type: String }, - showSyncMessages: { type: Boolean } - } - } + static get properties() { + return { + config: { type: Object }, + urls: { type: Object }, + nodeType: { type: String, reflect: true }, + theme: { type: String, reflect: true }, + addressInfo: { type: Object }, + botQortWallet: { type: String }, + botBtcWallet: { type: String }, + botLtcWallet: { type: String }, + botDogeWallet: { type: String }, + botDgbWallet: { type: String }, + botRvnWallet: { type: String }, + botArrrWallet: { type: String }, + arrrWalletAddress: { type: String }, + qortWalletBalance: { type: Number }, + btcWalletBalance: { type: Number }, + ltcWalletBalance: { type: Number }, + dogeWalletBalance: { type: Number }, + dgbWalletBalance: { type: Number }, + rvnWalletBalance: { type: Number }, + arrrWalletBalance: { type: Number }, + failedTradesList: { type: Array }, + tradesOpenBtcQortal: { type: Array }, + myTradesOpenLtcQortal: { type: Array }, + tradesFailedBtcQortal: { type: Array }, + tradesOpenBtcQortalCleaned: { type: Array }, + tradesOpenLtcQortal: { type: Array }, + tradesFailedLtcQortal: { type: Array }, + tradesOpenLtcQortalCleaned: { type: Array }, + tradesOpenDogeQortal: { type: Array }, + tradesFailedDogeQortal: { type: Array }, + tradesOpenDogeQortalCleaned: { type: Array }, + tradesOpenDgbQortal: { type: Array }, + tradesFailedDgbQortal: { type: Array }, + tradesOpenDgbQortalCleaned: { type: Array }, + tradesOpenRvnQortal: { type: Array }, + tradesFailedRvnQortal: { type: Array }, + tradesOpenRvnQortalCleaned: { type: Array }, + tradesOpenArrrQortal: { type: Array }, + tradesFailedArrrQortal: { type: Array }, + tradesOpenArrrQortalCleaned: { type: Array }, + tradeBotBtcBook: { type: Array }, + tradeBotLtcBook: { type: Array }, + tradeBotDogeBook: { type: Array }, + tradeBotDgbBook: { type: Array }, + tradeBotRvnBook: { type: Array }, + tradeBotArrrBook: { type: Array }, + tradeBotBtcAt: { type: Array }, + tradeBotLtcAt: { type: Array }, + tradeBotDogeAt: { type: Array }, + tradeBotDgbAt: { type: Array }, + tradeBotRvnAt: { type: Array }, + tradeBotArrrAt: { type: Array }, + tradeBotAvailableBtcQortal: { type: Array }, + tradeBotAvailableLtcQortal: { type: Array }, + tradeBotAvailableDogeQortal: { type: Array }, + tradeBotAvailableDgbQortal: { type: Array }, + tradeBotAvailableRvnQortal: { type: Array }, + tradeBotAvailableArrrQortal: { type: Array }, + checkBtcAlice: { type: String }, + checkLtcAlice: { type: String }, + checkDogeAlice: { type: String }, + checkDgbAlice: { type: String }, + checkRvnAlice: { type: String }, + checkArrrAlice: { type: String }, + reAddBtcAmount: { type: Number }, + reAddLtcAmount: { type: Number }, + reAddDogeAmount: { type: Number }, + reAddDgbAmount: { type: Number }, + reAddRvnAmount: { type: Number }, + reAddArrrAmount: { type: Number }, + reAddBtcPrice: { type: Number }, + reAddLtcPrice: { type: Number }, + reAddDogePrice: { type: Number }, + reAddDgbPrice: { type: Number }, + reAddRvnPrice: { type: Number }, + reAddArrrPrice: { type: Number }, + botBtcBuyAtAddress: { type: String }, + botLtcBuyAtAddress: { type: String }, + botDogeBuyAtAddress: { type: String }, + botDgbBuyAtAddress: { type: String }, + botRvnBuyAtAddress: { type: String }, + botArrrBuyAtAddress: { type: String }, + salt: { type: String }, + storageData: { type: String }, + lockScreenPass: { type: String }, + lockScreenSet: { type: String }, + lockPass: { type: String }, + lockSet: { type: String }, + myLockScreenPass: { type: String }, + myLockScreenSet: { type: String }, + helperMessage: { type: String }, + showSyncMessages: { type: Boolean } + } + } - static get styles() { - return [ - css` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --mdc-theme-error: rgb(255, 89, 89); - --lumo-primary-text-color: rgb(0, 167, 245); - --lumo-primary-color-50pct: rgba(0, 167, 245, 0.5); - --lumo-primary-color-10pct: rgba(0, 167, 245, 0.1); - --lumo-primary-color: hsl(199, 100%, 48%); - --lumo-base-color: var(--white); - --lumo-body-text-color: var(--black); - --lumo-secondary-text-color: var(--sectxt); - --lumo-contrast-60pct: var(--vdicon); - --item-selected-color: var(--nav-selected-color); - --item-selected-color-text: var(--nav-selected-color-text); - --item-color-active: var(--nav-color-active); - --item-color-hover: var(--nav-color-hover); - --item-text-color: var(--nav-text-color); - --item-icon-color: var(--nav-icon-color); - --item-border-color: var(--nav-border-color); - --item-border-selected-color: var(--nav-border-selected-color); - } + static get styles() { + return [appViewStyles] + } - :host { - --app-drawer-width: 260px; - } + constructor() { + super() + this.urls = [] + this.nodeType = '' + this.addressInfo = {} + this.botQortWallet = '' + this.botBtcWallet = '' + this.botLtcWallet = '' + this.botDogeWallet = '' + this.botDgbWallet = '' + this.botRvnWallet = '' + this.botArrrWallet = '' + this.arrrWalletAddress = '' + this.qortWalletBalance = 0 + this.btcWalletBalance = 0 + this.ltcWalletBalance = 0 + this.dogeWalletBalance = 0 + this.dgbWalletBalance = 0 + this.rvnWalletBalance = 0 + this.arrrWalletBalance = 0 + this.failedTradesList = [] + this.tradesOpenBtcQortal = [] + this.myTradesOpenLtcQortal = [] + this.tradesFailedBtcQortal = [] + this.tradesOpenBtcQortalCleaned = [] + this.tradesOpenLtcQortal = [] + this.tradesFailedLtcQortal = [] + this.tradesOpenLtcQortalCleaned = [] + this.tradesOpenDogeQortal = [] + this.tradesFailedDogeQortal = [] + this.tradesOpenDogeQortalCleaned = [] + this.tradesOpenDgbQortal = [] + this.tradesFailedDgbQortal = [] + this.tradesOpenDgbQortalCleaned = [] + this.tradesOpenRvnQortal = [] + this.tradesFailedRvnQortal = [] + this.tradesOpenRvnQortalCleaned = [] + this.tradesOpenArrrQortal = [] + this.tradesFailedArrrQortal = [] + this.tradesOpenArrrQortalCleaned = [] + this.tradeBotBtcBook = [] + this.tradeBotLtcBook = [] + this.tradeBotDogeBook = [] + this.tradeBotDgbBook = [] + this.tradeBotRvnBook = [] + this.tradeBotArrrBook = [] + this.tradeBotBtcAt = [] + this.tradeBotLtcAt = [] + this.tradeBotDogeAt = [] + this.tradeBotDgbAt = [] + this.tradeBotRvnAt = [] + this.tradeBotArrrAt = [] + this.tradeBotAvailableBtcQortal = [] + this.tradeBotAvailableLtcQortal = [] + this.tradeBotAvailableDogeQortal = [] + this.tradeBotAvailableDgbQortal = [] + this.tradeBotAvailableRvnQortal = [] + this.tradeBotAvailableArrrQortal = [] + this.checkBtcAlice = '' + this.checkLtcAlice = '' + this.checkDogeAlice = '' + this.checkDgbAlice = '' + this.checkRvnAlice = '' + this.checkArrrAlice = '' + this.reAddBtcAmount = 0 + this.reAddLtcAmount = 0 + this.reAddDogeAmount = 0 + this.reAddDgbAmount = 0 + this.reAddRvnAmount = 0 + this.reAddArrrAmount = 0 + this.reAddBtcPrice = 0 + this.reAddLtcPrice = 0 + this.reAddDogePrice = 0 + this.reAddDgbPrice = 0 + this.reAddRvnPrice = 0 + this.reAddArrrPrice = 0 + this.botBtcBuyAtAddress = '' + this.botLtcBuyAtAddress = '' + this.botDogeBuyAtAddress = '' + this.botDgbBuyAtAddress = '' + this.botRvnBuyAtAddress = '' + this.botArrrBuyAtAddress = '' + this.salt = '' + this.storageData = '' + this.lockScreenPass = '' + this.lockScreenSet = '' + this.lockPass = '' + this.lockSet = '' + this.myLockScreenPass = '' + this.myLockScreenSet = '' + this.helperMessage = '' + this.getTourElements = this.getTourElements.bind(this) + this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' + } - app-drawer-layout:not([narrow]) [drawer-toggle]:not(side-menu-item) { - display: none; - } + render() { + return html` + + + + + + + + + + +
+ + + +
+
+ + + + + + +
+
 
+ +
     
+ +
   
+ +
  
+ ${this.renderLockButton()} +
  
+ +
  
+
+ this.openSettings()} title="${translate("settings.settings")}"> +
+
  
+ +
 
+
+ this.openLogout()} title="${translate("logout.logout")}"> +
+
  
+
+
+ + + ${!this.showSyncMessages ? html` + + ` : html``} +
+
+ + + + +
+

Qortal UI ${translate("login.lp1")}

+
+
+
+

${translate("login.lp2")}

+

${translate("login.lp3")}

+
+
+ password + +
+
+ password + +
+
+ ${translate("login.lp4")} + ${translate("login.lp5")} +
+
+ +
+

Qortal UI ${translate("login.lp1")}

+
+
+
+

${translate("login.lessthen8")}

+
+
+ ${translate("login.lp4")} + ${translate("login.lp5")} +
+
+ +
+ UI
+ ${translate("login.lp9")} + ${translate("login.lp10")} +
+
+ password + +
+ ${this.helperMessage} +
+
+
+
+ +
+
+ + ` + } - app-drawer { - box-shadow: var(--shadow-2); - } + async firstUpdated() { + addTradeBotRoutes(parentEpml) - app-header { - box-shadow: var(--shadow-2); - } + parentEpml.imReady() - app-toolbar { - background: var(--sidetopbar); - color: var(--black); - border-top: var(--border); - height: 48px; - padding: 3px; - } + this.clearTheCache() + this.helperMessage = this.renderHelperPass() + this.showSyncMessages = store.getState().app.showSyncIndicator + this.salt = '' + this.salt = Base58.encode(store.getState().app.wallet._addresses[0].keyPair.privateKey) + this.storageData = '' + this.storageData = store.getState().app.selectedAddress.address + this.lockScreenPass = '' + this.lockScreenPass = 'lockScreenPass-' + this.storageData + this.lockScreenSet = '' + this.lockScreenSet = 'lockScreenSet-' + this.storageData + this.lockPass = '' + this.lockPass = encryptData(false, this.salt) + this.lockSet = '' + this.lockSet = encryptData(false, this.salt) - paper-progress { - --paper-progress-active-color: var(--mdc-theme-primary); - } + if (localStorage.getItem(this.lockScreenPass) === null && localStorage.getItem(this.lockScreenSet) === null) { + localStorage.setItem(this.lockScreenPass, this.lockPass) + localStorage.setItem(this.lockScreenSet, this.lockSet) - .s-menu { - list-style: none; - padding: 0px 0px; - background: var(--sidetopbar); - border-radius: 2px; - width: 100%; - border-top: 1px solid var(--border); - outline: none; - } - - .search { - display: inline; - width: 50%; - align-items: center; - } - - #sideBar { - height: 100vh; - display: flex; - flex-direction: column; - background: var(--sidetopbar); - } - - .sideBarMenu { - overflow-y: auto; - flex: 1 1; - } - - .sideBarMenu::-webkit-scrollbar-track { - background-color: whitesmoke; - border-radius: 7px; - } - - .sideBarMenu::-webkit-scrollbar { - width: 6px; - border-radius: 7px; - background-color: whitesmoke; - } - - .sideBarMenu::-webkit-scrollbar-thumb { - background-color: rgb(180, 176, 176); - border-radius: 7px; - transition: all 0.3s ease-in-out; - } - - #balanceheader { - flex: 0 0 24px; - padding: 12px 12px 45px 12px; - border-bottom: 1px solid var(--border); - background: var(--sidetopbar); - } - - .balanceheadertext { - position: absolute; - margin: auto; - font-size: 14px; - font-weight: 400; - width: 250px; - display: inline; - padding-top: 5px; - padding-bottom: 5px; - color: var(--nav-text-color); - } - - #balances { - flex: 0 0 24px; - padding: 12px; - background: var(--sidetopbar); - } - - .balancelist { - align-items: center; - float: left; - opacity: 1; - position: relative; - } - - .balanceinfo { - position: absolute; - margin: auto; - font-size: 14px; - font-weight: 100; - width: 250px; - display: inline; - padding-top: 5px; - padding-bottom: 5px; - color: var(--black); - } - - .qort { - animation: animate1 4s 2s 1 ease-in-out ; - color: var(--black); - opacity: 0; - } - - .btc { - animation: animate2 4s 8s 1 ease-in-out ; - color: var(--black); - opacity: 0; - } - - .ltc { - animation: animate3 4s 14s 1 ease-in-out ; - color: var(--black); - opacity: 0; - } - - .doge { - animation: animate4 4s 20s 1 ease-in-out ; - color: var(--black); - opacity: 0; - } - - .dgb { - animation: animate5 4s 26s 1 ease-in-out ; - color: var(--black); - opacity: 0; - } - - .rvn { - animation: animate6 4s 32s 1 ease-in-out ; - color: var(--black); - opacity: 0; - } - - .arrr { - animation: animate7 4s 38s 1 ease-in-out ; - color: var(--black); - opacity: 0; - } - - @keyframes animate1 { - 0%,100% { opacity: 0; } - 50% { opacity: 10; } - } - - @keyframes animate2 { - 0%,100% { opacity: 0; } - 50% { opacity: 10; } - } - - @keyframes animate3 { - 0%,100% { opacity: 0; } - 50% { opacity: 10; } - } - - @keyframes animate4 { - 0%,100% { opacity: 0; } - 50% { opacity: 10; } - } - - @keyframes animate5 { - 0%,100% { opacity: 0; } - 50% { opacity: 10; } - } - - @keyframes animate6 { - 0%,100% { opacity: 0; } - 50% { opacity: 10; } - } - - @keyframes animate7 { - 0%,100% { opacity: 0; } - 50% { opacity: 10; } - } - - .sideBarMenu::-webkit-scrollbar-thumb:hover { - background-color: rgb(148, 146, 146); - cursor: pointer; - } - - .balanceButton { - background-color: #03a9f4; - color: #ffffff; - margin-left: 12px; - margin-right: 12px; - padding-top: 5px; - padding-bottom: 5px; - } - - .red { - --mdc-theme-primary: #C6011F; - } - - .setpass-wrapper { - width: 100%; - min-width: 400px; - max-width: 450px; - text-align: center; - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - padding: 10px 10px 0px; - box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1); + this.myLockScreenPass = '' + this.myLockScreenPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt) + this.myLockScreenSet = '' + this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt) + } else { + this.myLockScreenPass = '' + this.myLockScreenPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt) + this.myLockScreenSet = '' + this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt) } - .lock-wrapper { - width: 100%; - height: 100%; - min-width: 600px; - max-width: 600px; - min-height: 400px; - max-height: 400px; - text-align: center; - background: url("/img/qortal-lock.jpg"); - border: 1px solid var(--black); - border-radius: 25px; - padding: 10px 10px 0px; + if (this.myLockScreenSet === true) { + this.shadowRoot.getElementById('lockScreenActive').open() } - .text-wrapper { - width: 100%; - height: 100%; - min-width: 280px; - max-width: 280px; - min-height: 64px; - max-height: 64px; - text-align: center; - margin-left: 35px; - margin-top: 125px; - overflow: hidden; + var drawerTog = this.shadowRoot.getElementById('mb') + var drawerOut = this.shadowRoot.getElementById('appsidebar') + + drawerTog.addEventListener('mouseover', function () { + drawerTog.click() + }) + + drawerOut.addEventListener('mouseleave', function () { + drawerTog.click() + }) + + await this.getNodeType() + + const myAppNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + const nodeAppUrl = myAppNode.protocol + '://' + myAppNode.domain + ':' + myAppNode.port + const appDelay = ms => new Promise(res => setTimeout(res, ms)) + + await appDelay(3000) + + this.botQortWallet = store.getState().app.selectedAddress.address + this.botBtcWallet = store.getState().app.selectedAddress.btcWallet.address + this.botLtcWallet = store.getState().app.selectedAddress.ltcWallet.address + this.botDogeWallet = store.getState().app.selectedAddress.dogeWallet.address + this.botDgbWallet = store.getState().app.selectedAddress.dgbWallet.address + this.botRvnWallet = store.getState().app.selectedAddress.rvnWallet.address + this.botArrrWallet = store.getState().app.selectedAddress.arrrWallet.address + + await this.botBtcTradebook() + await this.botLtcTradebook() + await this.botDogeTradebook() + await this.botDgbTradebook() + await this.botRvnTradebook() + await this.botArrrTradebook() + + window.addEventListener('storage', async () => { + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || '[]') + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || '[]') + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || '[]') + this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || '[]') + this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || '[]') + this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || '[]') + }) + + if (localStorage.getItem('failedTrades') === null) { + localStorage.setItem('failedTrades', '') + + var oldFailedTrades = JSON.parse(localStorage.getItem('failedTrades') || '[]') + + const addFixedFail = { + timestamp: 1699792400000, + recipient: 'QSMfgUCXahYHg38RidZ4FuWbVV8KGngDjP' + } + + oldFailedTrades.push(addFixedFail) + + localStorage.setItem('failedTrades', JSON.stringify(oldFailedTrades)) + + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + } else { + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') } - .lock-title-white { - font-family: 'magistralbold'; - font-weight: 700; - font-size: 26px; - line-height: 32px; - color: #ffffff; + const unconfirmedTransactions = async () => { + const unconfirmedTransactionslUrl = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` + var addFailedTrades = JSON.parse(localStorage.getItem('failedTrades') || '[]') + await fetch(unconfirmedTransactionslUrl).then(response => { + return response.json() + }).then(data => { + data.map(item => { + const unconfirmedNessageTimeDiff = Date.now() - item.timestamp + const timeOneHour = 60 * 60 * 1000 + if (Number(unconfirmedNessageTimeDiff) > Number(timeOneHour)) { + const addIt = { + timestamp: item.timestamp, + recipient: item.recipient + } + addFailedTrades.push(addIt) + } + }) + + localStorage.setItem('failedTrades', JSON.stringify(addFailedTrades)) + + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + }) } - .lock-title-red { - font-family: 'magistralbold'; - font-weight: 700; - font-size: 26px; - line-height: 32px; - color: #df3636; + await unconfirmedTransactions() + + const filterUnconfirmedTransactions = async () => { + let cleanFailedTrades = this.failedTradesList.reduce((newArray, cut) => { + if (!newArray.some(obj => obj.recipient === cut.recipient)) { + newArray.push(cut) + } + + return newArray + }, []) + + localStorage.setItem('failedTrades', JSON.stringify(cleanFailedTrades)) + + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') } - ` - ] - } - constructor() { - super() - this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' - this.urls = [] - this.nodeType = '' - this.addressInfo = {} - this.botQortWallet = '' - this.botBtcWallet = '' - this.botLtcWallet = '' - this.botDogeWallet = '' - this.botDgbWallet = '' - this.botRvnWallet = '' - this.botArrrWallet = '' - this.arrrWalletAddress = '' - this.qortWalletBalance = 0 - this.btcWalletBalance = 0 - this.ltcWalletBalance = 0 - this.dogeWalletBalance = 0 - this.dgbWalletBalance = 0 - this.rvnWalletBalance = 0 - this.arrrWalletBalance = 0 - this.failedTradesList = [] - this.tradesOpenBtcQortal = [] - this.myTradesOpenLtcQortal = [] - this.tradesFailedBtcQortal = [] - this.tradesOpenBtcQortalCleaned = [] - this.tradesOpenLtcQortal = [] - this.tradesFailedLtcQortal = [] - this.tradesOpenLtcQortalCleaned = [] - this.tradesOpenDogeQortal = [] - this.tradesFailedDogeQortal = [] - this.tradesOpenDogeQortalCleaned = [] - this.tradesOpenDgbQortal = [] - this.tradesFailedDgbQortal = [] - this.tradesOpenDgbQortalCleaned = [] - this.tradesOpenRvnQortal = [] - this.tradesFailedRvnQortal = [] - this.tradesOpenRvnQortalCleaned = [] - this.tradesOpenArrrQortal = [] - this.tradesFailedArrrQortal = [] - this.tradesOpenArrrQortalCleaned = [] - this.tradeBotBtcBook = [] - this.tradeBotLtcBook = [] - this.tradeBotDogeBook = [] - this.tradeBotDgbBook = [] - this.tradeBotRvnBook = [] - this.tradeBotArrrBook = [] - this.tradeBotBtcAt = [] - this.tradeBotLtcAt = [] - this.tradeBotDogeAt = [] - this.tradeBotDgbAt = [] - this.tradeBotRvnAt = [] - this.tradeBotArrrAt = [] - this.tradeBotAvailableBtcQortal = [] - this.tradeBotAvailableLtcQortal = [] - this.tradeBotAvailableDogeQortal = [] - this.tradeBotAvailableDgbQortal = [] - this.tradeBotAvailableRvnQortal = [] - this.tradeBotAvailableArrrQortal = [] - this.checkBtcAlice = '' - this.checkLtcAlice = '' - this.checkDogeAlice = '' - this.checkDgbAlice = '' - this.checkRvnAlice = '' - this.checkArrrAlice = '' - this.reAddBtcAmount = 0 - this.reAddLtcAmount = 0 - this.reAddDogeAmount = 0 - this.reAddDgbAmount = 0 - this.reAddRvnAmount = 0 - this.reAddArrrAmount = 0 - this.reAddBtcPrice = 0 - this.reAddLtcPrice = 0 - this.reAddDogePrice = 0 - this.reAddDgbPrice = 0 - this.reAddRvnPrice = 0 - this.reAddArrrPrice = 0 - this.botBtcBuyAtAddress = '' - this.botLtcBuyAtAddress = '' - this.botDogeBuyAtAddress = '' - this.botDgbBuyAtAddress = '' - this.botRvnBuyAtAddress = '' - this.botArrrBuyAtAddress = '' - this.balanceTicker = html` -
-
-
- ` - this.salt = '' - this.storageData = '' - this.lockScreenPass = '' - this.lockScreenSet = '' - this.lockPass = '' - this.lockSet = '' - this.myLockScreenPass = '' - this.myLockScreenSet = '' - this.helperMessage = '' - this.getTourElements = this.getTourElements.bind(this) - } + await filterUnconfirmedTransactions() - getTourElements(){ - let els = {} - const el1 = this.shadowRoot.querySelector("core-sync-status").shadowRoot.getElementById("core-sync-status-id") - const el2 = this.shadowRoot.querySelector("show-plugin").shadowRoot.getElementById("showPluginId") - const el3 = this.shadowRoot.querySelector("beginner-checklist").shadowRoot.getElementById("popover-notification") - if(el1) { - els['core-sync-status-id'] = el1 - } - if(el2) { - els['tab'] = el2 - } - if(el3) { - els['checklist'] = el3 - } + const getOpenTradesBTC = async () => { + let timerBTC - return els - } + if (this.isEmptyArray(this.tradeBotBtcBook) === true) { + clearTimeout(timerBTC) + timerBTC = setTimeout(getOpenTradesBTC, 150000) + } else { + await this.updateBtcWalletBalance() + const tradesOpenBtcQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=BITCOIN&limit=0` - render() { - return html` - - - - - - - - - - -
- - - -
-
- - - - - - -
-
 
- -
     
- -
   
- -
  
- ${this.renderLockButton()} -
  
- -
  
-
- this.openSettings()} title="${translate("settings.settings")}"> -
-
  
- -
 
-
- this.openLogout()} title="${translate("logout.logout")}"> -
-
  
-
-
- - - ${!this.showSyncMessages ? html`` : html``} -
-
- - - - -
-

Qortal UI ${translate("login.lp1")}

-
-
-
-

${translate("login.lp2")}

-

${translate("login.lp3")}

-
-
- password - -
-
- password - -
-
- ${translate("login.lp4")} - ${translate("login.lp5")} -
-
- -
-

Qortal UI ${translate("login.lp1")}

-
-
-
-

${translate("login.lessthen8")}

-
-
- ${translate("login.lp4")} - ${translate("login.lp5")} -
-
- -
- UI
- ${translate("login.lp9")} - ${translate("login.lp10")} -
-
- password - -
- ${this.helperMessage} -
-
-
-
- -
-
-
- - ` - } + const tradesOpenBtcQortal = await fetch(tradesOpenBtcQortalUrl).then(response => { + return response.json() + }) - async firstUpdated() { + this.tradesOpenBtcQortal = tradesOpenBtcQortal.map(item => { + const expiryTime = item.creatorPresenceExpiry + if (Number(expiryTime) > Date.now()) { + const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) + const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) + return { + qortAmount: item.qortAmount, + price: roundedPrice, + foreignAmount: item.expectedForeignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - addTradeBotRoutes(parentEpml) - parentEpml.imReady() + const unconfirmedTransactionsBTC = async () => { + const unconfirmedTransactionsUrlBTC = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` + var addFailedTradesBTC = JSON.parse(localStorage.getItem('failedTrades') || '[]') - this.clearTheCache() + await fetch(unconfirmedTransactionsUrlBTC).then(response => { + return response.json() + }).then(data => { + data.map(item => { + const unconfirmedNessageTimeDiffBTC = Date.now() - item.timestamp + const timeOneHourBTC = 60 * 60 * 1000 + if (Number(unconfirmedNessageTimeDiffBTC) > Number(timeOneHourBTC)) { + const addItBTC = { + timestamp: item.timestamp, + recipient: item.recipient + } + addFailedTradesBTC.push(addItBTC) + } + }) - this.helperMessage = this.renderHelperPass() + localStorage.setItem('failedTrades', JSON.stringify(addFailedTradesBTC)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + }) + } - this.showSyncMessages = store.getState().app.showSyncIndicator + await unconfirmedTransactionsBTC() - this.salt = '' - this.salt = Base58.encode(store.getState().app.wallet._addresses[0].keyPair.privateKey) + const filterUnconfirmedTransactionsBTC = async () => { + let cleanFailedTradesBTC = this.failedTradesList.reduce((newArray, cut) => { + if (!newArray.some(obj => obj.recipient === cut.recipient)) { + newArray.push(cut) + } - this.storageData = '' - this.storageData = store.getState().app.selectedAddress.address + return newArray + }, []) - this.lockScreenPass = '' - this.lockScreenPass = 'lockScreenPass-' + this.storageData + localStorage.setItem('failedTrades', JSON.stringify(cleanFailedTradesBTC)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + } - this.lockScreenSet = '' - this.lockScreenSet = 'lockScreenSet-' + this.storageData + await filterUnconfirmedTransactionsBTC() - this.lockPass = '' - this.lockPass = encryptData(false, this.salt) + this.tradesOpenBtcQortalCleaned = this.tradesOpenBtcQortal - this.lockSet = '' - this.lockSet = encryptData(false, this.salt) + const filterOpenOfferBTC = async () => { + this.failedTradesList.forEach(item => { + const recipientToRemove = item.recipient - if (localStorage.getItem(this.lockScreenPass) === null && localStorage.getItem(this.lockScreenSet) === null) { - localStorage.setItem(this.lockScreenPass, this.lockPass) - localStorage.setItem(this.lockScreenSet, this.lockSet) - this.myLockScreenPass = '' - this.myLockScreenPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt) - this.myLockScreenSet = '' - this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt) - } else { - this.myLockScreenPass = '' - this.myLockScreenPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt) - this.myLockScreenSet = '' - this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt) - } + this.tradesOpenBtcQortalCleaned = this.tradesOpenBtcQortalCleaned.filter(obj => { + return obj.qortalCreatorTradeAddress !== recipientToRemove + }) + }) + } - if (this.myLockScreenSet === true) { - this.shadowRoot.getElementById('lockScreenActive').open() - } + await filterOpenOfferBTC() + await appDelay(1000) + await filterMyBotPriceTradesBTC() - var drawerTog = this.shadowRoot.getElementById("mb") - var drawerOut = this.shadowRoot.getElementById("appsidebar") + setTimeout(getOpenTradesBTC, 150000) + } + } - drawerTog.addEventListener('mouseover', function () { - drawerTog.click() - }) - - drawerOut.addEventListener('mouseleave', function () { - drawerTog.click() - }) - - await this.getNodeType() - - const myAppNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] - const nodeAppUrl = myAppNode.protocol + '://' + myAppNode.domain + ':' + myAppNode.port - const appDelay = ms => new Promise(res => setTimeout(res, ms)) - - await appDelay(3000) - - this.botQortWallet = store.getState().app.selectedAddress.address - this.botBtcWallet = store.getState().app.selectedAddress.btcWallet.address - this.botLtcWallet = store.getState().app.selectedAddress.ltcWallet.address - this.botDogeWallet = store.getState().app.selectedAddress.dogeWallet.address - this.botDgbWallet = store.getState().app.selectedAddress.dgbWallet.address - this.botRvnWallet = store.getState().app.selectedAddress.rvnWallet.address - this.botArrrWallet = store.getState().app.selectedAddress.arrrWallet.address - - await this.botBtcTradebook() - await this.botLtcTradebook() - await this.botDogeTradebook() - await this.botDgbTradebook() - await this.botRvnTradebook() - await this.botArrrTradebook() - - window.addEventListener('storage', async () => { - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || "[]") - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || "[]") - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || "[]") - this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || "[]") - this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || "[]") - this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || "[]") - }) - - if (localStorage.getItem("failedTrades") === null) { - localStorage.setItem("failedTrades", "") - - var oldFailedTrades = JSON.parse(localStorage.getItem("failedTrades") || "[]") - - const addFixedFail = { - timestamp: 1699792400000, - recipient: 'QSMfgUCXahYHg38RidZ4FuWbVV8KGngDjP' - } - - oldFailedTrades.push(addFixedFail) - - localStorage.setItem("failedTrades", JSON.stringify(oldFailedTrades)) - - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } else { - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } - - const unconfirmedTransactions = async () => { - const unconfirmedTransactionslUrl = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` - var addFailedTrades = JSON.parse(localStorage.getItem("failedTrades") || "[]") - await fetch(unconfirmedTransactionslUrl).then(response => { - return response.json() - }).then(data => { - data.map(item => { - const unconfirmedNessageTimeDiff = Date.now() - item.timestamp - const timeOneHour = 60 * 60 * 1000 - if (Number(unconfirmedNessageTimeDiff) > Number(timeOneHour)) { - const addIt = { - timestamp: item.timestamp, - recipient: item.recipient - } - addFailedTrades.push(addIt) - } - }) - localStorage.setItem("failedTrades", JSON.stringify(addFailedTrades)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - }) - } - - await unconfirmedTransactions() - - const filterUnconfirmedTransactions = async () => { - let cleanFailedTrades = this.failedTradesList.reduce((newArray, cut) => { - if(!newArray.some(obj => obj.recipient === cut.recipient)) { - newArray.push(cut) - } - return newArray - },[]) - localStorage.setItem("failedTrades", JSON.stringify(cleanFailedTrades)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } - - await filterUnconfirmedTransactions() - - const getOpenTradesBTC = async () => { - let timerBTC - - if (this.isEmptyArray(this.tradeBotBtcBook) === true) { - clearTimeout(timerBTC) - timerBTC = setTimeout(getOpenTradesBTC, 150000) - } else { - await this.updateBtcWalletBalance() - const tradesOpenBtcQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=BITCOIN&limit=0` - - const tradesOpenBtcQortal = await fetch(tradesOpenBtcQortalUrl).then(response => { - return response.json() - }) - - this.tradesOpenBtcQortal = tradesOpenBtcQortal.map(item => { - const expiryTime = item.creatorPresenceExpiry - if (Number(expiryTime) > Date.now()) { - const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) - const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) - return { - qortAmount: item.qortAmount, - price: roundedPrice, - foreignAmount: item.expectedForeignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) - - const unconfirmedTransactionsBTC = async () => { - const unconfirmedTransactionsUrlBTC = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` - var addFailedTradesBTC = JSON.parse(localStorage.getItem("failedTrades") || "[]") - await fetch(unconfirmedTransactionsUrlBTC).then(response => { - return response.json() - }).then(data => { - data.map(item => { - const unconfirmedNessageTimeDiffBTC = Date.now() - item.timestamp - const timeOneHourBTC = 60 * 60 * 1000 - if (Number(unconfirmedNessageTimeDiffBTC) > Number(timeOneHourBTC)) { - const addItBTC = { - timestamp: item.timestamp, - recipient: item.recipient - } - addFailedTradesBTC.push(addItBTC) - } - }) - localStorage.setItem("failedTrades", JSON.stringify(addFailedTradesBTC)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - }) - } - - await unconfirmedTransactionsBTC() - - const filterUnconfirmedTransactionsBTC = async () => { - let cleanFailedTradesBTC = this.failedTradesList.reduce((newArray, cut) => { - if(!newArray.some(obj => obj.recipient === cut.recipient)) { - newArray.push(cut) - } - return newArray - },[]) - localStorage.setItem("failedTrades", JSON.stringify(cleanFailedTradesBTC)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } - - await filterUnconfirmedTransactionsBTC() - - this.tradesOpenBtcQortalCleaned = this.tradesOpenBtcQortal - - const filterOpenOfferBTC = async () => { - this.failedTradesList.forEach(item => { - const recipientToRemove = item.recipient - this.tradesOpenBtcQortalCleaned = this.tradesOpenBtcQortalCleaned.filter(obj => { - return obj.qortalCreatorTradeAddress !== recipientToRemove - }) - }) - } - - await filterOpenOfferBTC() - await appDelay(1000) - await filterMyBotPriceTradesBTC() - setTimeout(getOpenTradesBTC, 150000) - } - } - - const filterMyBotPriceTradesBTC = async () => { - const tradeBotBtcUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=BITCOIN&apiKey=${this.getApiKey()}` + const filterMyBotPriceTradesBTC = async () => { + const tradeBotBtcUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=BITCOIN&apiKey=${this.getApiKey()}` this.tradeBotBtcAt = await fetch(tradeBotBtcUrl).then(response => { return response.json() }) - await appDelay(1000) + await appDelay(1000) - this.tradeBotAvailableBtcQortal = this.tradesOpenBtcQortalCleaned.map(item => { - const listprice = parseFloat(item.price) - const listamount = parseFloat(item.qortAmount) - const checkprice = parseFloat(this.tradeBotBtcBook[0].botBtcPrice) - const checkamount = parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount) - if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { - return { - qortAmount: item.qortAmount, - price: item.price, - foreignAmount: item.foreignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) + this.tradeBotAvailableBtcQortal = this.tradesOpenBtcQortalCleaned.map(item => { + const listprice = parseFloat(item.price) + const listamount = parseFloat(item.qortAmount) + const checkprice = parseFloat(this.tradeBotBtcBook[0].botBtcPrice) + const checkamount = parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount) - this.tradeBotAvailableBtcQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) + if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { + return { + qortAmount: item.qortAmount, + price: item.price, + foreignAmount: item.foreignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - if (this.isEmptyArray(this.tradeBotAvailableBtcQortal) === true) { - return - } else { - this.checkBtcAlice = this.tradeBotAvailableBtcQortal[0].qortalAtAddress - } + this.tradeBotAvailableBtcQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) - await appDelay(1000) + if (this.isEmptyArray(this.tradeBotAvailableBtcQortal) === true) { + return + } else { + this.checkBtcAlice = this.tradeBotAvailableBtcQortal[0].qortalAtAddress + } - if (this.tradeBotBtcAt.some(item => item.atAddress === this.checkBtcAlice)) { - return - } + await appDelay(1000) - await appDelay(1000) + if (this.tradeBotBtcAt.some(item => item.atAddress === this.checkBtcAlice)) { + return + } - if (this.isEmptyArray(this.tradeBotAvailableBtcQortal) === true) { + await appDelay(1000) - } else { - const botbtcprice = this.round(parseFloat(this.tradeBotBtcBook[0].botBtcPrice)) - const changebtcamount = parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount) - const reducebtcamount = parseFloat(this.tradeBotAvailableBtcQortal[0].qortAmount) - const tradebtcataddress = this.tradeBotAvailableBtcQortal[0].qortalAtAddress - const newbtcamount = this.round(parseFloat(changebtcamount - reducebtcamount)) + if (this.isEmptyArray(this.tradeBotAvailableBtcQortal) === true) { - this.reAddBtcAmount = this.round(parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount)) - this.reAddBtcPrice = this.round(parseFloat(this.tradeBotBtcBook[0].botBtcPrice)) + } else { + const botbtcprice = this.round(parseFloat(this.tradeBotBtcBook[0].botBtcPrice)) + const changebtcamount = parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount) + const reducebtcamount = parseFloat(this.tradeBotAvailableBtcQortal[0].qortAmount) + const tradebtcataddress = this.tradeBotAvailableBtcQortal[0].qortalAtAddress + const newbtcamount = this.round(parseFloat(changebtcamount - reducebtcamount)) - localStorage.removeItem(this.botBtcWallet) - localStorage.setItem(this.botBtcWallet, "") + this.reAddBtcAmount = this.round(parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount)) + this.reAddBtcPrice = this.round(parseFloat(this.tradeBotBtcBook[0].botBtcPrice)) - var oldBtcTradebook = JSON.parse(localStorage.getItem(this.botBtcWallet) || "[]") + localStorage.removeItem(this.botBtcWallet) + localStorage.setItem(this.botBtcWallet, '') - const newBtcTradebookItem = { - botBtcQortAmount: newbtcamount, - botBtcPrice: botbtcprice - } + var oldBtcTradebook = JSON.parse(localStorage.getItem(this.botBtcWallet) || '[]') - oldBtcTradebook.push(newBtcTradebookItem) + const newBtcTradebookItem = { + botBtcQortAmount: newbtcamount, + botBtcPrice: botbtcprice + } - localStorage.setItem(this.botBtcWallet, JSON.stringify(oldBtcTradebook)) + oldBtcTradebook.push(newBtcTradebookItem) - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || "[]") + localStorage.setItem(this.botBtcWallet, JSON.stringify(oldBtcTradebook)) - this.botBtcBuyAtAddress = tradebtcataddress + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || '[]') - await appDelay(1000) + this.botBtcBuyAtAddress = tradebtcataddress - await this.buyBtcAction() + await appDelay(1000) - if (this.isEmptyArray(this.tradeBotBtcBook) === true) { - return - } else { - const botamount = parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount) + await this.buyBtcAction() - if (Number(botamount) === 0) { - this.removeBotBTCTradebook() - } - } + if (this.isEmptyArray(this.tradeBotBtcBook) === true) { + return + } else { + const botamount = parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount) - if (this.isEmptyArray(this.tradeBotBtcBook) === true) { + if (Number(botamount) === 0) { + this.removeBotBTCTradebook() + } + } - } else { - const checkBotBtcFunds = this.round(parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount) * parseFloat(this.tradeBotBtcBook[0].botBtcPrice)) - const myBotBtcFunds = this.round(parseFloat(this.btcWalletBalance)) + if (this.isEmptyArray(this.tradeBotBtcBook) === true) { - if (Number(myBotBtcFunds) < Number(checkBotBtcFunds)) { - this.removeBotBTCTradebook() - } - } - } - } + } else { + const checkBotBtcFunds = this.round(parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount) * parseFloat(this.tradeBotBtcBook[0].botBtcPrice)) + const myBotBtcFunds = this.round(parseFloat(this.btcWalletBalance)) - const getOpenTradesLTC = async () => { - let timerLTC + if (Number(myBotBtcFunds) < Number(checkBotBtcFunds)) { + this.removeBotBTCTradebook() + } + } + } + } - if (this.isEmptyArray(this.tradeBotLtcBook) === true) { - clearTimeout(timerLTC) - timerLTC = setTimeout(getOpenTradesLTC, 150000) - } else { - await this.updateLtcWalletBalance() + const getOpenTradesLTC = async () => { + let timerLTC - const getTradesOpenLtcQortal = async () => { - const tradesOpenLtcQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=LITECOIN&limit=0` + if (this.isEmptyArray(this.tradeBotLtcBook) === true) { + clearTimeout(timerLTC) + timerLTC = setTimeout(getOpenTradesLTC, 150000) + } else { + await this.updateLtcWalletBalance() - await fetch(tradesOpenLtcQortalUrl).then(response => { - return response.json() - }).then(data => { - this.myTradesOpenLtcQortal = data - }) - } + const getTradesOpenLtcQortal = async () => { + const tradesOpenLtcQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=LITECOIN&limit=0` - await getTradesOpenLtcQortal() + await fetch(tradesOpenLtcQortalUrl).then(response => { + return response.json() + }).then(data => { + this.myTradesOpenLtcQortal = data + }) + } - const filterTradesOpenLtcQortal = async () => { - this.tradesOpenLtcQortal = this.myTradesOpenLtcQortal.map(item => { - const expiryTime = item.creatorPresenceExpiry - if (Number(expiryTime) > Date.now()) { - const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) - const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) - return { - qortAmount: item.qortAmount, - price: roundedPrice, - foreignAmount: item.expectedForeignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) - } + await getTradesOpenLtcQortal() - await filterTradesOpenLtcQortal() + const filterTradesOpenLtcQortal = async () => { + this.tradesOpenLtcQortal = this.myTradesOpenLtcQortal.map(item => { + const expiryTime = item.creatorPresenceExpiry + if (Number(expiryTime) > Date.now()) { + const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) + const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) + return { + qortAmount: item.qortAmount, + price: roundedPrice, + foreignAmount: item.expectedForeignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) + } - const unconfirmedTransactionsLTC = async () => { - const unconfirmedTransactionsUrlLTC = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` - var addFailedTradesLTC = JSON.parse(localStorage.getItem("failedTrades") || "[]") - await fetch(unconfirmedTransactionsUrlLTC).then(response => { - return response.json() - }).then(data => { - data.map(item => { - const unconfirmedNessageTimeDiffLTC = Date.now() - item.timestamp - const timeOneHourLTC = 60 * 60 * 1000 - if (Number(unconfirmedNessageTimeDiffLTC) > Number(timeOneHourLTC)) { - const addItLTC = { - timestamp: item.timestamp, - recipient: item.recipient - } - addFailedTradesLTC.push(addItLTC) - } - }) - localStorage.setItem("failedTrades", JSON.stringify(addFailedTradesLTC)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - }) - } + await filterTradesOpenLtcQortal() - await unconfirmedTransactionsLTC() + const unconfirmedTransactionsLTC = async () => { + const unconfirmedTransactionsUrlLTC = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` + var addFailedTradesLTC = JSON.parse(localStorage.getItem('failedTrades') || '[]') - const filterUnconfirmedTransactionsLTC = async () => { - let cleanFailedTradesLTC = this.failedTradesList.reduce((newArray, cut) => { - if(!newArray.some(obj => obj.recipient === cut.recipient)) { - newArray.push(cut) - } - return newArray - },[]) - localStorage.setItem("failedTrades", JSON.stringify(cleanFailedTradesLTC)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } + await fetch(unconfirmedTransactionsUrlLTC).then(response => { + return response.json() + }).then(data => { + data.map(item => { + const unconfirmedNessageTimeDiffLTC = Date.now() - item.timestamp + const timeOneHourLTC = 60 * 60 * 1000 + if (Number(unconfirmedNessageTimeDiffLTC) > Number(timeOneHourLTC)) { + const addItLTC = { + timestamp: item.timestamp, + recipient: item.recipient + } + addFailedTradesLTC.push(addItLTC) + } + }) - await filterUnconfirmedTransactionsLTC() + localStorage.setItem('failedTrades', JSON.stringify(addFailedTradesLTC)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + }) + } - this.tradesOpenLtcQortalCleaned = this.tradesOpenLtcQortal + await unconfirmedTransactionsLTC() - const filterOpenOfferLTC = async () => { - this.failedTradesList.forEach(item => { - const recipientToRemove = item.recipient - this.tradesOpenLtcQortalCleaned = this.tradesOpenLtcQortalCleaned.filter(obj => { - return obj.qortalCreatorTradeAddress !== recipientToRemove - }) - }) - } + const filterUnconfirmedTransactionsLTC = async () => { + let cleanFailedTradesLTC = this.failedTradesList.reduce((newArray, cut) => { + if (!newArray.some(obj => obj.recipient === cut.recipient)) { + newArray.push(cut) + } - await filterOpenOfferLTC() - await appDelay(1000) - await filterMyBotPriceTradesLTC() - setTimeout(getOpenTradesLTC, 150000) - } - } + return newArray + }, []) - const filterMyBotPriceTradesLTC = async () => { - const tradeBotLtcUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=LITECOIN&apiKey=${this.getApiKey()}` + localStorage.setItem('failedTrades', JSON.stringify(cleanFailedTradesLTC)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + } + + await filterUnconfirmedTransactionsLTC() + + this.tradesOpenLtcQortalCleaned = this.tradesOpenLtcQortal + + const filterOpenOfferLTC = async () => { + this.failedTradesList.forEach(item => { + const recipientToRemove = item.recipient + this.tradesOpenLtcQortalCleaned = this.tradesOpenLtcQortalCleaned.filter(obj => { + return obj.qortalCreatorTradeAddress !== recipientToRemove + }) + }) + } + + await filterOpenOfferLTC() + await appDelay(1000) + await filterMyBotPriceTradesLTC() + + setTimeout(getOpenTradesLTC, 150000) + } + } + + const filterMyBotPriceTradesLTC = async () => { + const tradeBotLtcUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=LITECOIN&apiKey=${this.getApiKey()}` this.tradeBotLtcAt = await fetch(tradeBotLtcUrl).then(response => { return response.json() }) - await appDelay(1000) + await appDelay(1000) - this.tradeBotAvailableLtcQortal = this.tradesOpenLtcQortalCleaned.map(item => { - const listprice = parseFloat(item.price) - const listamount = parseFloat(item.qortAmount) - const checkprice = parseFloat(this.tradeBotLtcBook[0].botLtcPrice) - const checkamount = parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount) - if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { - return { - qortAmount: item.qortAmount, - price: item.price, - foreignAmount: item.foreignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) + this.tradeBotAvailableLtcQortal = this.tradesOpenLtcQortalCleaned.map(item => { + const listprice = parseFloat(item.price) + const listamount = parseFloat(item.qortAmount) + const checkprice = parseFloat(this.tradeBotLtcBook[0].botLtcPrice) + const checkamount = parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount) - this.tradeBotAvailableLtcQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) + if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { + return { + qortAmount: item.qortAmount, + price: item.price, + foreignAmount: item.foreignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - if (this.isEmptyArray(this.tradeBotAvailableLtcQortal) === true) { - return - } else { - this.checkLtcAlice = this.tradeBotAvailableLtcQortal[0].qortalAtAddress - } + this.tradeBotAvailableLtcQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) - await appDelay(1000) + if (this.isEmptyArray(this.tradeBotAvailableLtcQortal) === true) { + return + } else { + this.checkLtcAlice = this.tradeBotAvailableLtcQortal[0].qortalAtAddress + } - if (this.tradeBotLtcAt.some(item => item.atAddress === this.checkLtcAlice)) { - return - } + await appDelay(1000) - await appDelay(1000) + if (this.tradeBotLtcAt.some(item => item.atAddress === this.checkLtcAlice)) { + return + } - if (this.isEmptyArray(this.tradeBotAvailableLtcQortal) === true) { + await appDelay(1000) - } else { - const botltcprice = this.round(parseFloat(this.tradeBotLtcBook[0].botLtcPrice)) - const changeltcamount = parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount) - const reduceltcamount = parseFloat(this.tradeBotAvailableLtcQortal[0].qortAmount) - const tradeltcataddress = this.tradeBotAvailableLtcQortal[0].qortalAtAddress - const newltcamount = this.round(parseFloat(changeltcamount - reduceltcamount)) + if (this.isEmptyArray(this.tradeBotAvailableLtcQortal) === true) { - this.reAddLtcAmount = this.round(parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount)) - this.reAddLtcPrice = this.round(parseFloat(this.tradeBotLtcBook[0].botLtcPrice)) + } else { + const botltcprice = this.round(parseFloat(this.tradeBotLtcBook[0].botLtcPrice)) + const changeltcamount = parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount) + const reduceltcamount = parseFloat(this.tradeBotAvailableLtcQortal[0].qortAmount) + const tradeltcataddress = this.tradeBotAvailableLtcQortal[0].qortalAtAddress + const newltcamount = this.round(parseFloat(changeltcamount - reduceltcamount)) - localStorage.removeItem(this.botLtcWallet) - localStorage.setItem(this.botLtcWallet, "") + this.reAddLtcAmount = this.round(parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount)) + this.reAddLtcPrice = this.round(parseFloat(this.tradeBotLtcBook[0].botLtcPrice)) - var oldLtcTradebook = JSON.parse(localStorage.getItem(this.botLtcWallet) || "[]") + localStorage.removeItem(this.botLtcWallet) + localStorage.setItem(this.botLtcWallet, '') - const newLtcTradebookItem = { - botLtcQortAmount: newltcamount, - botLtcPrice: botltcprice - } + var oldLtcTradebook = JSON.parse(localStorage.getItem(this.botLtcWallet) || '[]') - oldLtcTradebook.push(newLtcTradebookItem) + const newLtcTradebookItem = { + botLtcQortAmount: newltcamount, + botLtcPrice: botltcprice + } - localStorage.setItem(this.botLtcWallet, JSON.stringify(oldLtcTradebook)) + oldLtcTradebook.push(newLtcTradebookItem) - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || "[]") + localStorage.setItem(this.botLtcWallet, JSON.stringify(oldLtcTradebook)) - this.botLtcBuyAtAddress = tradeltcataddress + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || '[]') - await appDelay(1000) + this.botLtcBuyAtAddress = tradeltcataddress - await this.buyLtcAction() + await appDelay(1000) - if (this.isEmptyArray(this.tradeBotLtcBook) === true) { - return - } else { - const botamount = parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount) + await this.buyLtcAction() - if (Number(botamount) === 0) { - this.removeBotLTCTradebook() - } - } + if (this.isEmptyArray(this.tradeBotLtcBook) === true) { + return + } else { + const botamount = parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount) - if (this.isEmptyArray(this.tradeBotLtcBook) === true) { + if (Number(botamount) === 0) { + this.removeBotLTCTradebook() + } + } - } else { - const checkBotLtcFunds = this.round(parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount) * parseFloat(this.tradeBotLtcBook[0].botLtcPrice)) - const myBotLtcFunds = this.round(parseFloat(this.ltcWalletBalance)) + if (this.isEmptyArray(this.tradeBotLtcBook) === true) { - if (Number(myBotLtcFunds) < Number(checkBotLtcFunds)) { - this.removeBotLTCTradebook() - } - } - } - } + } else { + const checkBotLtcFunds = this.round(parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount) * parseFloat(this.tradeBotLtcBook[0].botLtcPrice)) + const myBotLtcFunds = this.round(parseFloat(this.ltcWalletBalance)) - const getOpenTradesDOGE = async () => { - let timerDOGE + if (Number(myBotLtcFunds) < Number(checkBotLtcFunds)) { + this.removeBotLTCTradebook() + } + } + } + } - if (this.isEmptyArray(this.tradeBotDogeBook) === true) { - clearTimeout(timerDOGE) - timerDOGE = setTimeout(getOpenTradesDOGE, 150000) - } else { - await this.updateDogeWalletBalance() - const tradesOpenDogeQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=DOGECOIN&limit=0` + const getOpenTradesDOGE = async () => { + let timerDOGE - const tradesOpenDogeQortal = await fetch(tradesOpenDogeQortalUrl).then(response => { - return response.json() - }) + if (this.isEmptyArray(this.tradeBotDogeBook) === true) { + clearTimeout(timerDOGE) + timerDOGE = setTimeout(getOpenTradesDOGE, 150000) + } else { + await this.updateDogeWalletBalance() + const tradesOpenDogeQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=DOGECOIN&limit=0` - this.tradesOpenDogeQortal = tradesOpenDogeQortal.map(item => { - const expiryTime = item.creatorPresenceExpiry - if (Number(expiryTime) > Date.now()) { - const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) - const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) - return { - qortAmount: item.qortAmount, - price: roundedPrice, - foreignAmount: item.expectedForeignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) + const tradesOpenDogeQortal = await fetch(tradesOpenDogeQortalUrl).then(response => { + return response.json() + }) - const unconfirmedTransactionsDOGE = async () => { - const unconfirmedTransactionsUrlDOGE = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` - var addFailedTradesDOGE = JSON.parse(localStorage.getItem("failedTrades") || "[]") - await fetch(unconfirmedTransactionsUrlDOGE).then(response => { - return response.json() - }).then(data => { - data.map(item => { - const unconfirmedNessageTimeDiffDOGE = Date.now() - item.timestamp - const timeOneHourDOGE = 60 * 60 * 1000 - if (Number(unconfirmedNessageTimeDiffDOGE) > Number(timeOneHourDOGE)) { - const addItDOGE = { - timestamp: item.timestamp, - recipient: item.recipient - } - addFailedTradesDOGE.push(addItDOGE) - } - }) - localStorage.setItem("failedTrades", JSON.stringify(addFailedTradesDOGE)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - }) - } + this.tradesOpenDogeQortal = tradesOpenDogeQortal.map(item => { + const expiryTime = item.creatorPresenceExpiry + if (Number(expiryTime) > Date.now()) { + const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) + const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) + return { + qortAmount: item.qortAmount, + price: roundedPrice, + foreignAmount: item.expectedForeignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - await unconfirmedTransactionsDOGE() + const unconfirmedTransactionsDOGE = async () => { + const unconfirmedTransactionsUrlDOGE = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` + var addFailedTradesDOGE = JSON.parse(localStorage.getItem('failedTrades') || '[]') - const filterUnconfirmedTransactionsDOGE = async () => { - let cleanFailedTradesDOGE = this.failedTradesList.reduce((newArray, cut) => { - if(!newArray.some(obj => obj.recipient === cut.recipient)) { - newArray.push(cut) - } - return newArray - },[]) - localStorage.setItem("failedTrades", JSON.stringify(cleanFailedTradesDOGE)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } + await fetch(unconfirmedTransactionsUrlDOGE).then(response => { + return response.json() + }).then(data => { + data.map(item => { + const unconfirmedNessageTimeDiffDOGE = Date.now() - item.timestamp + const timeOneHourDOGE = 60 * 60 * 1000 + if (Number(unconfirmedNessageTimeDiffDOGE) > Number(timeOneHourDOGE)) { + const addItDOGE = { + timestamp: item.timestamp, + recipient: item.recipient + } + addFailedTradesDOGE.push(addItDOGE) + } + }) - await filterUnconfirmedTransactionsDOGE() + localStorage.setItem('failedTrades', JSON.stringify(addFailedTradesDOGE)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + }) + } - this.tradesOpenDogeQortalCleaned = this.tradesOpenDogeQortal + await unconfirmedTransactionsDOGE() - const filterOpenOfferDOGE = async () => { - this.failedTradesList.forEach(item => { - const recipientToRemove = item.recipient - this.tradesOpenDogeQortalCleaned = this.tradesOpenDogeQortalCleaned.filter(obj => { - return obj.qortalCreatorTradeAddress !== recipientToRemove - }) - }) - } + const filterUnconfirmedTransactionsDOGE = async () => { + let cleanFailedTradesDOGE = this.failedTradesList.reduce((newArray, cut) => { + if (!newArray.some(obj => obj.recipient === cut.recipient)) { + newArray.push(cut) + } - await filterOpenOfferDOGE() - await appDelay(1000) - await filterMyBotPriceTradesDOGE() - setTimeout(getOpenTradesDOGE, 150000) - } - } + return newArray + }, []) - const filterMyBotPriceTradesDOGE = async () => { - const tradeBotDogeUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=DOGECOIN&apiKey=${this.getApiKey()}` + localStorage.setItem('failedTrades', JSON.stringify(cleanFailedTradesDOGE)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + } + + await filterUnconfirmedTransactionsDOGE() + + this.tradesOpenDogeQortalCleaned = this.tradesOpenDogeQortal + + const filterOpenOfferDOGE = async () => { + this.failedTradesList.forEach(item => { + const recipientToRemove = item.recipient + this.tradesOpenDogeQortalCleaned = this.tradesOpenDogeQortalCleaned.filter(obj => { + return obj.qortalCreatorTradeAddress !== recipientToRemove + }) + }) + } + + await filterOpenOfferDOGE() + await appDelay(1000) + await filterMyBotPriceTradesDOGE() + + setTimeout(getOpenTradesDOGE, 150000) + } + } + + const filterMyBotPriceTradesDOGE = async () => { + const tradeBotDogeUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=DOGECOIN&apiKey=${this.getApiKey()}` this.tradeBotDogeAt = await fetch(tradeBotDogeUrl).then(response => { return response.json() }) - await appDelay(1000) + await appDelay(1000) - this.tradeBotAvailableDogeQortal = this.tradesOpenDogeQortalCleaned.map(item => { - const listprice = parseFloat(item.price) - const listamount = parseFloat(item.qortAmount) - const checkprice = parseFloat(this.tradeBotDogeBook[0].botDogePrice) - const checkamount = parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount) - if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { - return { - qortAmount: item.qortAmount, - price: item.price, - foreignAmount: item.foreignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) + this.tradeBotAvailableDogeQortal = this.tradesOpenDogeQortalCleaned.map(item => { + const listprice = parseFloat(item.price) + const listamount = parseFloat(item.qortAmount) + const checkprice = parseFloat(this.tradeBotDogeBook[0].botDogePrice) + const checkamount = parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount) - this.tradeBotAvailableDogeQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) + if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { + return { + qortAmount: item.qortAmount, + price: item.price, + foreignAmount: item.foreignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - if (this.isEmptyArray(this.tradeBotAvailableDogeQortal) === true) { - return - } else { - this.checkDogeAlice = this.tradeBotAvailableDogeQortal[0].qortalAtAddress - } + this.tradeBotAvailableDogeQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) - await appDelay(1000) + if (this.isEmptyArray(this.tradeBotAvailableDogeQortal) === true) { + return + } else { + this.checkDogeAlice = this.tradeBotAvailableDogeQortal[0].qortalAtAddress + } - if (this.tradeBotDogeAt.some(item => item.atAddress === this.checkDogeAlice)) { - return - } + await appDelay(1000) - await appDelay(1000) + if (this.tradeBotDogeAt.some(item => item.atAddress === this.checkDogeAlice)) { + return + } - if (this.isEmptyArray(this.tradeBotAvailableDogeQortal) === true) { + await appDelay(1000) - } else { - const botdogeprice = this.round(parseFloat(this.tradeBotDogeBook[0].botDogePrice)) - const changedogeamount = parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount) - const reducedogeamount = parseFloat(this.tradeBotAvailableDogeQortal[0].qortAmount) - const tradedogeataddress = this.tradeBotAvailableDogeQortal[0].qortalAtAddress - const newdogeamount = this.round(parseFloat(changedogeamount - reducedogeamount)) + if (this.isEmptyArray(this.tradeBotAvailableDogeQortal) === true) { - this.reAddDogeAmount = this.round(parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount)) - this.reAddDogePrice = this.round(parseFloat(this.tradeBotDogeBook[0].botDogePrice)) + } else { + const botdogeprice = this.round(parseFloat(this.tradeBotDogeBook[0].botDogePrice)) + const changedogeamount = parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount) + const reducedogeamount = parseFloat(this.tradeBotAvailableDogeQortal[0].qortAmount) + const tradedogeataddress = this.tradeBotAvailableDogeQortal[0].qortalAtAddress + const newdogeamount = this.round(parseFloat(changedogeamount - reducedogeamount)) - localStorage.removeItem(this.botDogeWallet) - localStorage.setItem(this.botDogeWallet, "") + this.reAddDogeAmount = this.round(parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount)) + this.reAddDogePrice = this.round(parseFloat(this.tradeBotDogeBook[0].botDogePrice)) - var oldDogeTradebook = JSON.parse(localStorage.getItem(this.botDogeWallet) || "[]") + localStorage.removeItem(this.botDogeWallet) + localStorage.setItem(this.botDogeWallet, '') - const newDogeTradebookItem = { - botDogeQortAmount: newdogeamount, - botDogePrice: botdogeprice - } + var oldDogeTradebook = JSON.parse(localStorage.getItem(this.botDogeWallet) || '[]') - oldDogeTradebook.push(newDogeTradebookItem) + const newDogeTradebookItem = { + botDogeQortAmount: newdogeamount, + botDogePrice: botdogeprice + } - localStorage.setItem(this.botDogeWallet, JSON.stringify(oldDogeTradebook)) + oldDogeTradebook.push(newDogeTradebookItem) - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || "[]") + localStorage.setItem(this.botDogeWallet, JSON.stringify(oldDogeTradebook)) - this.botDogeBuyAtAddress = tradedogeataddress + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || '[]') - await appDelay(1000) + this.botDogeBuyAtAddress = tradedogeataddress - await this.buyDogeAction() + await appDelay(1000) - if (this.isEmptyArray(this.tradeBotDogeBook) === true) { - return - } else { - const botamount = parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount) + await this.buyDogeAction() - if (Number(botamount) === 0) { - this.removeBotDOGETradebook() - } - } + if (this.isEmptyArray(this.tradeBotDogeBook) === true) { + return + } else { + const botamount = parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount) - if (this.isEmptyArray(this.tradeBotDogeBook) === true) { + if (Number(botamount) === 0) { + this.removeBotDOGETradebook() + } + } - } else { - const checkBotDogeFunds = this.round(parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount) * parseFloat(this.tradeBotDogeBook[0].botDogePrice)) - const myBotDogeFunds = this.round(parseFloat(this.dogeWalletBalance)) + if (this.isEmptyArray(this.tradeBotDogeBook) === true) { - if (Number(myBotDogeFunds) < Number(checkBotDogeFunds)) { - this.removeBotDOGETradebook() - } - } - } - } + } else { + const checkBotDogeFunds = this.round(parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount) * parseFloat(this.tradeBotDogeBook[0].botDogePrice)) + const myBotDogeFunds = this.round(parseFloat(this.dogeWalletBalance)) - const getOpenTradesDGB = async () => { - let timerDGB + if (Number(myBotDogeFunds) < Number(checkBotDogeFunds)) { + this.removeBotDOGETradebook() + } + } + } + } - if (this.isEmptyArray(this.tradeBotDgbBook) === true) { - clearTimeout(timerDGB) - timerDGB = setTimeout(getOpenTradesDGB, 150000) - } else { - await this.updateDgbWalletBalance() - const tradesOpenDgbQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=DIGIYBYTE&limit=0` + const getOpenTradesDGB = async () => { + let timerDGB - const tradesOpenDgbQortal = await fetch(tradesOpenDgbQortalUrl).then(response => { - return response.json() - }) + if (this.isEmptyArray(this.tradeBotDgbBook) === true) { + clearTimeout(timerDGB) + timerDGB = setTimeout(getOpenTradesDGB, 150000) + } else { + await this.updateDgbWalletBalance() + const tradesOpenDgbQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=DIGIYBYTE&limit=0` - this.tradesOpenDgbQortal = tradesOpenDgbQortal.map(item => { - const expiryTime = item.creatorPresenceExpiry - if (Number(expiryTime) > Date.now()) { - const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) - const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) - return { - qortAmount: item.qortAmount, - price: roundedPrice, - foreignAmount: item.expectedForeignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) + const tradesOpenDgbQortal = await fetch(tradesOpenDgbQortalUrl).then(response => { + return response.json() + }) - const unconfirmedTransactionsDGB = async () => { - const unconfirmedTransactionsUrlDGB = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` - var addFailedTradesDGB = JSON.parse(localStorage.getItem("failedTrades") || "[]") - await fetch(unconfirmedTransactionsUrlDGB).then(response => { - return response.json() - }).then(data => { - data.map(item => { - const unconfirmedNessageTimeDiffDGB = Date.now() - item.timestamp - const timeOneHourDGB = 60 * 60 * 1000 - if (Number(unconfirmedNessageTimeDiffDGB) > Number(timeOneHourDGB)) { - const addItDGB = { - timestamp: item.timestamp, - recipient: item.recipient - } - addFailedTradesDGB.push(addItDGB) - } - }) - localStorage.setItem("failedTrades", JSON.stringify(addFailedTradesDGB)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - }) - } + this.tradesOpenDgbQortal = tradesOpenDgbQortal.map(item => { + const expiryTime = item.creatorPresenceExpiry + if (Number(expiryTime) > Date.now()) { + const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) + const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) + return { + qortAmount: item.qortAmount, + price: roundedPrice, + foreignAmount: item.expectedForeignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - await unconfirmedTransactionsDGB() + const unconfirmedTransactionsDGB = async () => { + const unconfirmedTransactionsUrlDGB = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` + var addFailedTradesDGB = JSON.parse(localStorage.getItem('failedTrades') || '[]') - const filterUnconfirmedTransactionsDGB = async () => { - let cleanFailedTradesDGB = this.failedTradesList.reduce((newArray, cut) => { - if(!newArray.some(obj => obj.recipient === cut.recipient)) { - newArray.push(cut) - } - return newArray - },[]) - localStorage.setItem("failedTrades", JSON.stringify(cleanFailedTradesDGB)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } + await fetch(unconfirmedTransactionsUrlDGB).then(response => { + return response.json() + }).then(data => { + data.map(item => { + const unconfirmedNessageTimeDiffDGB = Date.now() - item.timestamp + const timeOneHourDGB = 60 * 60 * 1000 + if (Number(unconfirmedNessageTimeDiffDGB) > Number(timeOneHourDGB)) { + const addItDGB = { + timestamp: item.timestamp, + recipient: item.recipient + } + addFailedTradesDGB.push(addItDGB) + } + }) - await filterUnconfirmedTransactionsDGB() + localStorage.setItem('failedTrades', JSON.stringify(addFailedTradesDGB)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + }) + } - this.tradesOpenDgbQortalCleaned = this.tradesOpenDgbQortal + await unconfirmedTransactionsDGB() - const filterOpenOfferDGB = async () => { - this.failedTradesList.forEach(item => { - const recipientToRemove = item.recipient - this.tradesOpenDgbQortalCleaned = this.tradesOpenDgbQortalCleaned.filter(obj => { - return obj.qortalCreatorTradeAddress !== recipientToRemove - }) - }) - } + const filterUnconfirmedTransactionsDGB = async () => { + let cleanFailedTradesDGB = this.failedTradesList.reduce((newArray, cut) => { + if (!newArray.some(obj => obj.recipient === cut.recipient)) { + newArray.push(cut) + } - await filterOpenOfferDGB() - await appDelay(1000) - await filterMyBotPriceTradesDGB() - setTimeout(getOpenTradesDGB, 150000) - } - } + return newArray + }, []) - const filterMyBotPriceTradesDGB = async () => { - const tradeBotDgbUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=DIGIBYTE&apiKey=${this.getApiKey()}` + localStorage.setItem('failedTrades', JSON.stringify(cleanFailedTradesDGB)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + } + + await filterUnconfirmedTransactionsDGB() + + this.tradesOpenDgbQortalCleaned = this.tradesOpenDgbQortal + + const filterOpenOfferDGB = async () => { + this.failedTradesList.forEach(item => { + const recipientToRemove = item.recipient + this.tradesOpenDgbQortalCleaned = this.tradesOpenDgbQortalCleaned.filter(obj => { + return obj.qortalCreatorTradeAddress !== recipientToRemove + }) + }) + } + + await filterOpenOfferDGB() + await appDelay(1000) + await filterMyBotPriceTradesDGB() + + setTimeout(getOpenTradesDGB, 150000) + } + } + + const filterMyBotPriceTradesDGB = async () => { + const tradeBotDgbUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=DIGIBYTE&apiKey=${this.getApiKey()}` this.tradeBotDgbAt = await fetch(tradeBotDgbUrl).then(response => { return response.json() }) - await appDelay(1000) + await appDelay(1000) - this.tradeBotAvailableDgbQortal = this.tradesOpenDgbQortalCleaned.map(item => { - const listprice = parseFloat(item.price) - const listamount = parseFloat(item.qortAmount) - const checkprice = parseFloat(this.tradeBotDgbBook[0].botDgbPrice) - const checkamount = parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount) - if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { - return { - qortAmount: item.qortAmount, - price: item.price, - foreignAmount: item.foreignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) + this.tradeBotAvailableDgbQortal = this.tradesOpenDgbQortalCleaned.map(item => { + const listprice = parseFloat(item.price) + const listamount = parseFloat(item.qortAmount) + const checkprice = parseFloat(this.tradeBotDgbBook[0].botDgbPrice) + const checkamount = parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount) - this.tradeBotAvailableDgbQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) + if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { + return { + qortAmount: item.qortAmount, + price: item.price, + foreignAmount: item.foreignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - if (this.isEmptyArray(this.tradeBotAvailableDgbQortal) === true) { - return - } else { - this.checkDgbAlice = this.tradeBotAvailableDgbQortal[0].qortalAtAddress - } + this.tradeBotAvailableDgbQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) - await appDelay(1000) + if (this.isEmptyArray(this.tradeBotAvailableDgbQortal) === true) { + return + } else { + this.checkDgbAlice = this.tradeBotAvailableDgbQortal[0].qortalAtAddress + } - if (this.tradeBotDgbAt.some(item => item.atAddress === this.checkDgbAlice)) { - return - } + await appDelay(1000) - await appDelay(1000) + if (this.tradeBotDgbAt.some(item => item.atAddress === this.checkDgbAlice)) { + return + } - if (this.isEmptyArray(this.tradeBotAvailableDgbQortal) === true) { + await appDelay(1000) - } else { - const botdgbprice = this.round(parseFloat(this.tradeBotDgbBook[0].botDgbPrice)) - const changedgbamount = parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount) - const reducedgbamount = parseFloat(this.tradeBotAvailableDgbQortal[0].qortAmount) - const tradedgbataddress = this.tradeBotAvailableDgbQortal[0].qortalAtAddress - const newdgbamount = this.round(parseFloat(changedgbamount - reducedgbamount)) + if (this.isEmptyArray(this.tradeBotAvailableDgbQortal) === true) { - this.reAddDgbAmount = this.round(parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount)) - this.reAddDgbPrice = this.round(parseFloat(this.tradeBotDgbBook[0].botDgbPrice)) + } else { + const botdgbprice = this.round(parseFloat(this.tradeBotDgbBook[0].botDgbPrice)) + const changedgbamount = parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount) + const reducedgbamount = parseFloat(this.tradeBotAvailableDgbQortal[0].qortAmount) + const tradedgbataddress = this.tradeBotAvailableDgbQortal[0].qortalAtAddress + const newdgbamount = this.round(parseFloat(changedgbamount - reducedgbamount)) - localStorage.removeItem(this.botDgbWallet) - localStorage.setItem(this.botDgbWallet, "") + this.reAddDgbAmount = this.round(parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount)) + this.reAddDgbPrice = this.round(parseFloat(this.tradeBotDgbBook[0].botDgbPrice)) - var oldDgbTradebook = JSON.parse(localStorage.getItem(this.botDgbWallet) || "[]") + localStorage.removeItem(this.botDgbWallet) + localStorage.setItem(this.botDgbWallet, '') - const newDgbTradebookItem = { - botDgbQortAmount: newdgbamount, - botDgbPrice: botdgbprice - } + var oldDgbTradebook = JSON.parse(localStorage.getItem(this.botDgbWallet) || '[]') - oldDgbTradebook.push(newDgbTradebookItem) + const newDgbTradebookItem = { + botDgbQortAmount: newdgbamount, + botDgbPrice: botdgbprice + } - localStorage.setItem(this.botDgbWallet, JSON.stringify(oldDgbTradebook)) + oldDgbTradebook.push(newDgbTradebookItem) - this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || "[]") + localStorage.setItem(this.botDgbWallet, JSON.stringify(oldDgbTradebook)) - this.botDgbBuyAtAddress = tradedgbataddress + this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || '[]') - await appDelay(1000) + this.botDgbBuyAtAddress = tradedgbataddress - await this.buyDgbAction() + await appDelay(1000) - if (this.isEmptyArray(this.tradeBotDgbBook) === true) { - return - } else { - const botamount = parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount) + await this.buyDgbAction() - if (Number(botamount) === 0) { - this.removeBotDGBTradebook() - } - } + if (this.isEmptyArray(this.tradeBotDgbBook) === true) { + return + } else { + const botamount = parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount) - if (this.isEmptyArray(this.tradeBotDgbBook) === true) { + if (Number(botamount) === 0) { + this.removeBotDGBTradebook() + } + } - } else { - const checkBotDgbFunds = this.round(parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount) * parseFloat(this.tradeBotDgbBook[0].botDgbPrice)) - const myBotDgbFunds = this.round(parseFloat(this.dgbWalletBalance)) + if (this.isEmptyArray(this.tradeBotDgbBook) === true) { - if (Number(myBotDgbFunds) < Number(checkBotDgbFunds)) { - this.removeBotDGBTradebook() - } - } - } - } + } else { + const checkBotDgbFunds = this.round(parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount) * parseFloat(this.tradeBotDgbBook[0].botDgbPrice)) + const myBotDgbFunds = this.round(parseFloat(this.dgbWalletBalance)) - const getOpenTradesRVN = async () => { - let timerRVN + if (Number(myBotDgbFunds) < Number(checkBotDgbFunds)) { + this.removeBotDGBTradebook() + } + } + } + } - if (this.isEmptyArray(this.tradeBotRvnBook) === true) { - clearTimeout(timerRVN) - timerRVN = setTimeout(getOpenTradesRVN, 150000) - } else { - await this.updateRvnWalletBalance() - const tradesOpenRvnQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=RAVENCOIN&limit=0` + const getOpenTradesRVN = async () => { + let timerRVN - const tradesOpenRvnQortal = await fetch(tradesOpenRvnQortalUrl).then(response => { - return response.json() - }) + if (this.isEmptyArray(this.tradeBotRvnBook) === true) { + clearTimeout(timerRVN) + timerRVN = setTimeout(getOpenTradesRVN, 150000) + } else { + await this.updateRvnWalletBalance() + const tradesOpenRvnQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=RAVENCOIN&limit=0` - this.tradesOpenRvnQortal = tradesOpenRvnQortal.map(item => { - const expiryTime = item.creatorPresenceExpiry - if (Number(expiryTime) > Date.now()) { - const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) - const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) - return { - qortAmount: item.qortAmount, - price: roundedPrice, - foreignAmount: item.expectedForeignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) + const tradesOpenRvnQortal = await fetch(tradesOpenRvnQortalUrl).then(response => { + return response.json() + }) - const unconfirmedTransactionsRVN = async () => { - const unconfirmedTransactionsUrlRVN = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` - var addFailedTradesRVN = JSON.parse(localStorage.getItem("failedTrades") || "[]") - await fetch(unconfirmedTransactionsUrlRVN).then(response => { - return response.json() - }).then(data => { - data.map(item => { - const unconfirmedNessageTimeDiffRVN = Date.now() - item.timestamp - const timeOneHourRVN = 60 * 60 * 1000 - if (Number(unconfirmedNessageTimeDiffRVN) > Number(timeOneHourRVN)) { - const addItRVN = { - timestamp: item.timestamp, - recipient: item.recipient - } - addFailedTradesRVN.push(addItRVN) - } - }) - localStorage.setItem("failedTrades", JSON.stringify(addFailedTradesRVN)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - }) - } + this.tradesOpenRvnQortal = tradesOpenRvnQortal.map(item => { + const expiryTime = item.creatorPresenceExpiry + if (Number(expiryTime) > Date.now()) { + const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) + const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) + return { + qortAmount: item.qortAmount, + price: roundedPrice, + foreignAmount: item.expectedForeignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - await unconfirmedTransactionsRVN() + const unconfirmedTransactionsRVN = async () => { + const unconfirmedTransactionsUrlRVN = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` + var addFailedTradesRVN = JSON.parse(localStorage.getItem('failedTrades') || '[]') - const filterUnconfirmedTransactionsRVN = async () => { - let cleanFailedTradesRVN = this.failedTradesList.reduce((newArray, cut) => { - if(!newArray.some(obj => obj.recipient === cut.recipient)) { - newArray.push(cut) - } - return newArray - },[]) - localStorage.setItem("failedTrades", JSON.stringify(cleanFailedTradesRVN)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } + await fetch(unconfirmedTransactionsUrlRVN).then(response => { + return response.json() + }).then(data => { + data.map(item => { + const unconfirmedNessageTimeDiffRVN = Date.now() - item.timestamp + const timeOneHourRVN = 60 * 60 * 1000 + if (Number(unconfirmedNessageTimeDiffRVN) > Number(timeOneHourRVN)) { + const addItRVN = { + timestamp: item.timestamp, + recipient: item.recipient + } + addFailedTradesRVN.push(addItRVN) + } + }) - await filterUnconfirmedTransactionsRVN() + localStorage.setItem('failedTrades', JSON.stringify(addFailedTradesRVN)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + }) + } - this.tradesOpenRvnQortalCleaned = this.tradesOpenRvnQortal + await unconfirmedTransactionsRVN() - const filterOpenOfferRVN = async () => { - this.failedTradesList.forEach(item => { - const recipientToRemove = item.recipient - this.tradesOpenRvnQortalCleaned = this.tradesOpenRvnQortalCleaned.filter(obj => { - return obj.qortalCreatorTradeAddress !== recipientToRemove - }) - }) - } + const filterUnconfirmedTransactionsRVN = async () => { + let cleanFailedTradesRVN = this.failedTradesList.reduce((newArray, cut) => { + if (!newArray.some(obj => obj.recipient === cut.recipient)) { + newArray.push(cut) + } - await filterOpenOfferRVN() - await appDelay(1000) - await filterMyBotPriceTradesRVN() - setTimeout(getOpenTradesRVN, 150000) - } - } + return newArray + }, []) - const filterMyBotPriceTradesRVN = async () => { - const tradeBotRvnUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=RAVENCOIN&apiKey=${this.getApiKey()}` + localStorage.setItem('failedTrades', JSON.stringify(cleanFailedTradesRVN)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + } + + await filterUnconfirmedTransactionsRVN() + + this.tradesOpenRvnQortalCleaned = this.tradesOpenRvnQortal + + const filterOpenOfferRVN = async () => { + this.failedTradesList.forEach(item => { + const recipientToRemove = item.recipient + this.tradesOpenRvnQortalCleaned = this.tradesOpenRvnQortalCleaned.filter(obj => { + return obj.qortalCreatorTradeAddress !== recipientToRemove + }) + }) + } + + await filterOpenOfferRVN() + await appDelay(1000) + await filterMyBotPriceTradesRVN() + + setTimeout(getOpenTradesRVN, 150000) + } + } + + const filterMyBotPriceTradesRVN = async () => { + const tradeBotRvnUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=RAVENCOIN&apiKey=${this.getApiKey()}` this.tradeBotRvnAt = await fetch(tradeBotRvnUrl).then(response => { return response.json() }) - await appDelay(1000) + await appDelay(1000) - this.tradeBotAvailableRvnQortal = this.tradesOpenRvnQortalCleaned.map(item => { - const listprice = parseFloat(item.price) - const listamount = parseFloat(item.qortAmount) - const checkprice = parseFloat(this.tradeBotRvnBook[0].botRvnPrice) - const checkamount = parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount) - if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { - return { - qortAmount: item.qortAmount, - price: item.price, - foreignAmount: item.foreignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) + this.tradeBotAvailableRvnQortal = this.tradesOpenRvnQortalCleaned.map(item => { + const listprice = parseFloat(item.price) + const listamount = parseFloat(item.qortAmount) + const checkprice = parseFloat(this.tradeBotRvnBook[0].botRvnPrice) + const checkamount = parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount) + if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { + return { + qortAmount: item.qortAmount, + price: item.price, + foreignAmount: item.foreignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - this.tradeBotAvailableRvnQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) + this.tradeBotAvailableRvnQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) - if (this.isEmptyArray(this.tradeBotAvailableRvnQortal) === true) { - return - } else { - this.checkRvnAlice = this.tradeBotAvailableRvnQortal[0].qortalAtAddress - } + if (this.isEmptyArray(this.tradeBotAvailableRvnQortal) === true) { + return + } else { + this.checkRvnAlice = this.tradeBotAvailableRvnQortal[0].qortalAtAddress + } - await appDelay(1000) + await appDelay(1000) - if (this.tradeBotRvnAt.some(item => item.atAddress === this.checkRvnAlice)) { - return - } + if (this.tradeBotRvnAt.some(item => item.atAddress === this.checkRvnAlice)) { + return + } - await appDelay(1000) + await appDelay(1000) - if (this.isEmptyArray(this.tradeBotAvailableRvnQortal) === true) { + if (this.isEmptyArray(this.tradeBotAvailableRvnQortal) === true) { - } else { - const botrvnprice = this.round(parseFloat(this.tradeBotRvnBook[0].botRvnPrice)) - const changervnamount = parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount) - const reducervnamount = parseFloat(this.tradeBotAvailableRvnQortal[0].qortAmount) - const tradervnataddress = this.tradeBotAvailableRvnQortal[0].qortalAtAddress - const newrvnamount = this.round(parseFloat(changervnamount - reducervnamount)) + } else { + const botrvnprice = this.round(parseFloat(this.tradeBotRvnBook[0].botRvnPrice)) + const changervnamount = parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount) + const reducervnamount = parseFloat(this.tradeBotAvailableRvnQortal[0].qortAmount) + const tradervnataddress = this.tradeBotAvailableRvnQortal[0].qortalAtAddress + const newrvnamount = this.round(parseFloat(changervnamount - reducervnamount)) - this.reAddRvnAmount = this.round(parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount)) - this.reAddRvnPrice = this.round(parseFloat(this.tradeBotRvnBook[0].botRvnPrice)) + this.reAddRvnAmount = this.round(parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount)) + this.reAddRvnPrice = this.round(parseFloat(this.tradeBotRvnBook[0].botRvnPrice)) - localStorage.removeItem(this.botRvnWallet) - localStorage.setItem(this.botRvnWallet, "") + localStorage.removeItem(this.botRvnWallet) + localStorage.setItem(this.botRvnWallet, '') - var oldRvnTradebook = JSON.parse(localStorage.getItem(this.botRvnWallet) || "[]") + var oldRvnTradebook = JSON.parse(localStorage.getItem(this.botRvnWallet) || '[]') - const newRvnTradebookItem = { - botRvnQortAmount: newrvnamount, - botRvnPrice: botrvnprice - } + const newRvnTradebookItem = { + botRvnQortAmount: newrvnamount, + botRvnPrice: botrvnprice + } - oldRvnTradebook.push(newRvnTradebookItem) + oldRvnTradebook.push(newRvnTradebookItem) - localStorage.setItem(this.botRvnWallet, JSON.stringify(oldRvnTradebook)) + localStorage.setItem(this.botRvnWallet, JSON.stringify(oldRvnTradebook)) - this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || "[]") + this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || '[]') - this.botRvnBuyAtAddress = tradervnataddress + this.botRvnBuyAtAddress = tradervnataddress - await appDelay(1000) + await appDelay(1000) - await this.buyRvnAction() + await this.buyRvnAction() - if (this.isEmptyArray(this.tradeBotRvnBook) === true) { - return - } else { - const botamount = parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount) + if (this.isEmptyArray(this.tradeBotRvnBook) === true) { + return + } else { + const botamount = parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount) - if (Number(botamount) === 0) { - this.removeBotRVNTradebook() - } - } + if (Number(botamount) === 0) { + this.removeBotRVNTradebook() + } + } - if (this.isEmptyArray(this.tradeBotRvnBook) === true) { + if (this.isEmptyArray(this.tradeBotRvnBook) === true) { - } else { - const checkBotRvnFunds = this.round(parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount) * parseFloat(this.tradeBotRvnBook[0].botRvnPrice)) - const myBotRvnFunds = this.round(parseFloat(this.rvnWalletBalance)) + } else { + const checkBotRvnFunds = this.round(parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount) * parseFloat(this.tradeBotRvnBook[0].botRvnPrice)) + const myBotRvnFunds = this.round(parseFloat(this.rvnWalletBalance)) - if (Number(myBotRvnFunds) < Number(checkBotRvnFunds)) { - this.removeBotRVNTradebook() - } - } - } - } + if (Number(myBotRvnFunds) < Number(checkBotRvnFunds)) { + this.removeBotRVNTradebook() + } + } + } + } - const getOpenTradesARRR = async () => { - let timerARRR + const getOpenTradesARRR = async () => { + let timerARRR - if (this.isEmptyArray(this.tradeBotArrrBook) === true) { - clearTimeout(timerARRR) - timerARRR = setTimeout(getOpenTradesARRR, 150000) - } else { - await this.updateArrrWalletBalance() - const tradesOpenArrrQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=PIRATECHAIN&limit=0` + if (this.isEmptyArray(this.tradeBotArrrBook) === true) { + clearTimeout(timerARRR) + timerARRR = setTimeout(getOpenTradesARRR, 150000) + } else { + await this.updateArrrWalletBalance() + const tradesOpenArrrQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=PIRATECHAIN&limit=0` - const tradesOpenArrrQortal = await fetch(tradesOpenArrrQortalUrl).then(response => { - return response.json() - }) + const tradesOpenArrrQortal = await fetch(tradesOpenArrrQortalUrl).then(response => { + return response.json() + }) - this.tradesOpenArrrQortal = tradesOpenArrrQortal.map(item => { - const expiryTime = item.creatorPresenceExpiry - if (Number(expiryTime) > Date.now()) { - const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) - const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) - return { - qortAmount: item.qortAmount, - price: roundedPrice, - foreignAmount: item.expectedForeignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) + this.tradesOpenArrrQortal = tradesOpenArrrQortal.map(item => { + const expiryTime = item.creatorPresenceExpiry + if (Number(expiryTime) > Date.now()) { + const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) + const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) + return { + qortAmount: item.qortAmount, + price: roundedPrice, + foreignAmount: item.expectedForeignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - const unconfirmedTransactionsARRR = async () => { - const unconfirmedTransactionsUrlARRR = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` - var addFailedTradesARRR = JSON.parse(localStorage.getItem("failedTrades") || "[]") - await fetch(unconfirmedTransactionsUrlARRR).then(response => { - return response.json() - }).then(data => { - data.map(item => { - const unconfirmedNessageTimeDiffARRR = Date.now() - item.timestamp - const timeOneHourARRR = 60 * 60 * 1000 - if (Number(unconfirmedNessageTimeDiffARRR) > Number(timeOneHourARRR)) { - const addItARRR = { - timestamp: item.timestamp, - recipient: item.recipient - } - addFailedTradesARRR.push(addItARRR) - } - }) - localStorage.setItem("failedTrades", JSON.stringify(addFailedTradesARRR)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - }) - } + const unconfirmedTransactionsARRR = async () => { + const unconfirmedTransactionsUrlARRR = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` + var addFailedTradesARRR = JSON.parse(localStorage.getItem('failedTrades') || '[]') - await unconfirmedTransactionsARRR() + await fetch(unconfirmedTransactionsUrlARRR).then(response => { + return response.json() + }).then(data => { + data.map(item => { + const unconfirmedNessageTimeDiffARRR = Date.now() - item.timestamp + const timeOneHourARRR = 60 * 60 * 1000 + if (Number(unconfirmedNessageTimeDiffARRR) > Number(timeOneHourARRR)) { + const addItARRR = { + timestamp: item.timestamp, + recipient: item.recipient + } + addFailedTradesARRR.push(addItARRR) + } + }) - const filterUnconfirmedTransactionsARRR = async () => { - let cleanFailedTradesARRR = this.failedTradesList.reduce((newArray, cut) => { - if(!newArray.some(obj => obj.recipient === cut.recipient)) { - newArray.push(cut) - } - return newArray - },[]) - localStorage.setItem("failedTrades", JSON.stringify(cleanFailedTradesARRR)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } + localStorage.setItem('failedTrades', JSON.stringify(addFailedTradesARRR)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + }) + } - await filterUnconfirmedTransactionsARRR() + await unconfirmedTransactionsARRR() - this.tradesOpenArrrQortalCleaned = this.tradesOpenArrrQortal + const filterUnconfirmedTransactionsARRR = async () => { + let cleanFailedTradesARRR = this.failedTradesList.reduce((newArray, cut) => { + if (!newArray.some(obj => obj.recipient === cut.recipient)) { + newArray.push(cut) + } - const filterOpenOfferARRR = async () => { - this.failedTradesList.forEach(item => { - const recipientToRemove = item.recipient - this.tradesOpenArrrQortalCleaned = this.tradesOpenArrrQortalCleaned.filter(obj => { - return obj.qortalCreatorTradeAddress !== recipientToRemove - }) - }) - } + return newArray + }, []) - await filterOpenOfferARRR() - await appDelay(1000) - await filterMyBotPriceTradesARRR() - setTimeout(getOpenTradesARRR, 150000) - } - } + localStorage.setItem('failedTrades', JSON.stringify(cleanFailedTradesARRR)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + } - const filterMyBotPriceTradesARRR = async () => { - const tradeBotArrrUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=PIRATECHAIN&apiKey=${this.getApiKey()}` + await filterUnconfirmedTransactionsARRR() + + this.tradesOpenArrrQortalCleaned = this.tradesOpenArrrQortal + + const filterOpenOfferARRR = async () => { + this.failedTradesList.forEach(item => { + const recipientToRemove = item.recipient + this.tradesOpenArrrQortalCleaned = this.tradesOpenArrrQortalCleaned.filter(obj => { + return obj.qortalCreatorTradeAddress !== recipientToRemove + }) + }) + } + + await filterOpenOfferARRR() + await appDelay(1000) + await filterMyBotPriceTradesARRR() + + setTimeout(getOpenTradesARRR, 150000) + } + } + + const filterMyBotPriceTradesARRR = async () => { + const tradeBotArrrUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=PIRATECHAIN&apiKey=${this.getApiKey()}` this.tradeBotArrrAt = await fetch(tradeBotArrrUrl).then(response => { return response.json() }) - await appDelay(1000) + await appDelay(1000) - this.tradeBotAvailableArrrQortal = this.tradesOpenArrrQortalCleaned.map(item => { - const listprice = parseFloat(item.price) - const listamount = parseFloat(item.qortAmount) - const checkprice = parseFloat(this.tradeBotArrrBook[0].botArrrPrice) - const checkamount = parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount) - if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { - return { - qortAmount: item.qortAmount, - price: item.price, - foreignAmount: item.foreignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) - - this.tradeBotAvailableArrrQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) - - if (this.isEmptyArray(this.tradeBotAvailableArrrQortal) === true) { - return - } else { - this.checkArrrAlice = this.tradeBotAvailableArrrQortal[0].qortalAtAddress - } - - await appDelay(1000) - - if (this.tradeBotArrrAt.some(item => item.atAddress === this.checkArrrAlice)) { - return - } - - await appDelay(1000) - - if (this.isEmptyArray(this.tradeBotAvailableArrrQortal) === true) { - - } else { - const botarrrprice = this.round(parseFloat(this.tradeBotArrrBook[0].botArrrPrice)) - const changearrramount = parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount) - const reducearrramount = parseFloat(this.tradeBotAvailableArrrQortal[0].qortAmount) - const tradearrrataddress = this.tradeBotAvailableArrrQortal[0].qortalAtAddress - const newarrramount = this.round(parseFloat(changearrramount - reducearrramount)) - - this.reAddArrrAmount = this.round(parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount)) - this.reAddArrrPrice = this.round(parseFloat(this.tradeBotArrrBook[0].botArrrPrice)) - - localStorage.removeItem(this.botArrrWallet) - localStorage.setItem(this.botArrrWallet, "") - - var oldArrrTradebook = JSON.parse(localStorage.getItem(this.botArrrWallet) || "[]") - - const newArrrTradebookItem = { - botArrrQortAmount: newarrramount, - botArrrPrice: botarrrprice - } - - oldArrrTradebook.push(newArrrTradebookItem) - - localStorage.setItem(this.botArrrWallet, JSON.stringify(oldArrrTradebook)) - - this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || "[]") - - this.botArrrBuyAtAddress = tradearrrataddress - - await appDelay(1000) - - await this.buyArrrAction() - - if (this.isEmptyArray(this.tradeBotArrrBook) === true) { - return - } else { - const botamount = parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount) - - if (Number(botamount) === 0) { - this.removeBotARRRTradebook() - } - } - - if (this.isEmptyArray(this.tradeBotArrrBook) === true) { - - } else { - const checkBotArrrFunds = this.round(parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount) * parseFloat(this.tradeBotArrrBook[0].botArrrPrice)) - const myBotArrrFunds = this.round(parseFloat(this.arrrWalletBalance)) - - if (Number(myBotArrrFunds) < Number(checkBotArrrFunds)) { - this.removeBotARRRTradebook() - } - } - } - } - - const getChatLastSeen = async () => { - let items = [] - - await chatLastSeen.iterate(function (value, key, iterationNumber) { - items.push({ key, timestamp: value }) - }) - - store.dispatch(setChatLastSeen(items)) - return items - } - - await getOpenTradesBTC() - await appDelay(1000) - await getOpenTradesLTC() - await appDelay(1000) - await getOpenTradesDOGE() - await appDelay(1000) - await getOpenTradesDGB() - await appDelay(1000) - await getOpenTradesRVN() - await appDelay(1000) - await getOpenTradesARRR() - await getChatLastSeen() - setInterval(() => { - this.clearTheCache() - }, 60000) - } - - clearTheCache() { - if (!isElectron()) { - } else { - console.clear() - window.parent.electronAPI.clearMyCache() - window.parent.electronAPI.clearCache() - } - } - - async getNodeType() { - const myAppNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] - const nodeAppUrl = myAppNode.protocol + '://' + myAppNode.domain + ':' + myAppNode.port - const url = `${nodeAppUrl}/admin/info` - await fetch(url).then((response) => { - return response.json() - }).then((data) => { - this.nodeType = data.type - }) - } - - renderNodeTypeMenu() { - const addressInfo = this.addressInfo - const isMinter = addressInfo?.error !== 124 && +addressInfo?.level > 0 - const isSponsor = +addressInfo?.level >= 5 - - if (this.nodeType === 'lite') { - return html` - - - - - - - - - - - - - - - - - ${this.renderNodeManagement()} - ` - } else { - return html` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${this.renderNodeManagement()} - - ` - } - } - - renderLockButton() { - if (this.myLockScreenPass === false && this.myLockScreenSet === false) { - return html` -
- this.openSetScreenLockPass()} title="${translate("login.lp11")}"> -
- ` - } else if (this.myLockScreenSet === false) { - return html` -
- this.setLockQortal()} title="${translate("login.lp11")}"> -
- ` - } else if (this.myLockScreenSet === true) { - return html` -
- -
- ` - } - } - - openSetScreenLockPass() { - this.shadowRoot.getElementById('lockPassword').value = '' - this.shadowRoot.getElementById('lockPasswordConfirm').value = '' - this.shadowRoot.getElementById('setLockScreenPass').open() - } - - closeSetScreenLockPass() { - this.shadowRoot.getElementById('setLockScreenPass').close() - } - - checkPass() { - const password = this.shadowRoot.getElementById('lockPassword').value - const rePassword = this.shadowRoot.getElementById('lockPasswordConfirm').value - - if (password === '') { - let snackbar1string = get("login.pleaseenter") - parentEpml.request('showSnackBar', `${snackbar1string}`) - return - } - - if (password != rePassword) { - let snackbar2string = get("login.notmatch") - parentEpml.request('showSnackBar', `${snackbar2string}`) - return - } - - if (password.length < 8) { - let snackbar3string = get("login.lessthen8") - parentEpml.request('showSnackBar', `${snackbar3string}`) - this.lowPass = '' - this.lowPass = password - this.extraConfirm() - } - - if (password.length >= 8) { - this.setNewScreenPass() - let snackbar4string = get("login.lp6") - parentEpml.request('showSnackBar', `${snackbar4string}`) - } - } - - extraConfirm() { - this.shadowRoot.getElementById('setLockScreenPass').close() - this.shadowRoot.getElementById('extraConfirmPass').open() - } - - closExtraConfirmPass() { - this.shadowRoot.getElementById('extraConfirmPass').close() - this.shadowRoot.getElementById('lockPassword').value = '' - this.shadowRoot.getElementById('lockPasswordConfirm').value = '' - } - - setNewScreenPass() { - const rawPassword = this.shadowRoot.getElementById('lockPassword').value - const cryptPassword = encryptData(rawPassword, this.salt) - localStorage.setItem(this.lockScreenPass, cryptPassword) - this.myLockScreenPass = '' - this.myLockScreenPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt) - this.shadowRoot.getElementById('setLockScreenPass').close() - this.shadowRoot.getElementById('extraConfirmPass').close() - this.shadowRoot.getElementById('lockPassword').value = '' - this.shadowRoot.getElementById('lockPasswordConfirm').value = '' - } - - setLockQortal() { - this.helperMessage = this.renderHelperPass() - this.lockSet = '' - this.lockSet = encryptData(true, this.salt) - localStorage.setItem(this.lockScreenSet, this.lockSet) - this.myLockScreenSet = '' - this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt) - this.shadowRoot.getElementById('lockScreenActive').open() - } - - passKeyListener(e) { - if (e.key === 'Enter') { - this.closeLockScreenActive() - } - } - - async closeLockScreenActive() { - const myPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt) - const checkPass = this.shadowRoot.getElementById('unlockPassword').value - const errDelay = ms => new Promise(res => setTimeout(res, ms)) - - if (checkPass === myPass) { - this.lockSet = '' - this.lockSet = encryptData(false, this.salt) - localStorage.setItem(this.lockScreenSet, this.lockSet) - this.myLockScreenSet = '' - this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt) - this.shadowRoot.getElementById('lockScreenActive').close() - this.shadowRoot.getElementById('unlockPassword').value = '' - this.helperMessage = this.renderHelperPass() - } else { - this.shadowRoot.getElementById('unlockPassword').value = '' - this.helperMessage = this.renderHelperErr() - await errDelay(3000) - this.helperMessage = this.renderHelperPass() - - } - } - - renderHelperPass() { - return html`${translate("login.pleaseenter")}` - } - - renderHelperErr() { - return html`${translate("login.lp8")}` - } - - renderNodeManagement() { - const checkNodeManagement = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] - if ((checkNodeManagement.enableManagement = true)) { - return html` - - - - ` - } else { - return html`` - } - } - - async updateQortWalletBalance() { - let qortAddress = store.getState().app.selectedAddress.address - - await parentEpml.request('apiCall', { - url: `/addresses/balance/${qortAddress}?apiKey=${this.getApiKey()}`, - }).then((res) => { - this.qortWalletBalance = res - }) - } - - async updateBtcWalletBalance() { - let _url = `/crosschain/btc/walletbalance?apiKey=${this.getApiKey()}` - let _body = store.getState().app.selectedAddress.btcWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.btcWalletBalance = (Number(res) / 1e8).toFixed(8) - } - }) - } - - async updateLtcWalletBalance() { - let _url = `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}` - let _body = store.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.ltcWalletBalance = (Number(res) / 1e8).toFixed(8) - } - }) - } - - async updateDogeWalletBalance() { - let _url = `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}` - let _body = store.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.dogeWalletBalance = (Number(res) / 1e8).toFixed(8) - } - }) - } - - async updateDgbWalletBalance() { - let _url = `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}` - let _body = store.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.dgbWalletBalance = (Number(res) / 1e8).toFixed(8) - } - }) - } - - async updateRvnWalletBalance() { - let _url = `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}` - let _body = store.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.rvnWalletBalance = (Number(res) / 1e8).toFixed(8) - } - }) - } - - async updateArrrWalletBalance() { - let _url = `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}` - let _body = store.getState().app.selectedAddress.arrrWallet.seed58 - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.arrrWalletBalance = (Number(res) / 1e8).toFixed(8) - } - }) - } - - botBtcTradebook() { - if (localStorage.getItem(this.botBtcWallet) === null) { - localStorage.setItem(this.botBtcWallet, "") - } else { - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || "[]") - } - } - - removeBotBTCTradebook() { - localStorage.removeItem(this.botBtcWallet) - localStorage.setItem(this.botBtcWallet, "") - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || "[]") - this.tradeBotAvailableBtcQortal = [] - } - - botLtcTradebook() { - if (localStorage.getItem(this.botLtcWallet) === null) { - localStorage.setItem(this.botLtcWallet, "") - } else { - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || "[]") - } - } - - removeBotLTCTradebook() { - localStorage.removeItem(this.botLtcWallet) - localStorage.setItem(this.botLtcWallet, "") - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || "[]") - this.tradeBotAvailableLtcQortal = [] - } - - botDogeTradebook() { - if (localStorage.getItem(this.botDogeWallet) === null) { - localStorage.setItem(this.botDogeWallet, "") - } else { - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || "[]") - } - } - - removeBotDOGETradebook() { - localStorage.removeItem(this.botDogeWallet) - localStorage.setItem(this.botDogeWallet, "") - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || "[]") - this.tradeBotAvailableDogeQortal = [] - } - - botDgbTradebook() { - if (localStorage.getItem(this.botDgbWallet) === null) { - localStorage.setItem(this.botDgbWallet, "") - } else { - this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || "[]") - } - } - - botRvnTradebook() { - if (localStorage.getItem(this.botRvnWallet) === null) { - localStorage.setItem(this.botRvnWallet, "") - } else { - this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || "[]") - } - } - - botArrrTradebook() { - if (localStorage.getItem(this.botArrrWallet) === null) { - localStorage.setItem(this.botArrrWallet, "") - } else { - this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || "[]") - } - } - - async buyBtcAction() { - const makeRequest = async () => { + this.tradeBotAvailableArrrQortal = this.tradesOpenArrrQortalCleaned.map(item => { + const listprice = parseFloat(item.price) + const listamount = parseFloat(item.qortAmount) + const checkprice = parseFloat(this.tradeBotArrrBook[0].botArrrPrice) + const checkamount = parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount) + + if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { + return { + qortAmount: item.qortAmount, + price: item.price, + foreignAmount: item.foreignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) + + this.tradeBotAvailableArrrQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) + + if (this.isEmptyArray(this.tradeBotAvailableArrrQortal) === true) { + return + } else { + this.checkArrrAlice = this.tradeBotAvailableArrrQortal[0].qortalAtAddress + } + + await appDelay(1000) + + if (this.tradeBotArrrAt.some(item => item.atAddress === this.checkArrrAlice)) { + return + } + + await appDelay(1000) + + if (this.isEmptyArray(this.tradeBotAvailableArrrQortal) === true) { + + } else { + const botarrrprice = this.round(parseFloat(this.tradeBotArrrBook[0].botArrrPrice)) + const changearrramount = parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount) + const reducearrramount = parseFloat(this.tradeBotAvailableArrrQortal[0].qortAmount) + const tradearrrataddress = this.tradeBotAvailableArrrQortal[0].qortalAtAddress + const newarrramount = this.round(parseFloat(changearrramount - reducearrramount)) + + this.reAddArrrAmount = this.round(parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount)) + this.reAddArrrPrice = this.round(parseFloat(this.tradeBotArrrBook[0].botArrrPrice)) + + localStorage.removeItem(this.botArrrWallet) + localStorage.setItem(this.botArrrWallet, '') + + var oldArrrTradebook = JSON.parse(localStorage.getItem(this.botArrrWallet) || '[]') + + const newArrrTradebookItem = { + botArrrQortAmount: newarrramount, + botArrrPrice: botarrrprice + } + + oldArrrTradebook.push(newArrrTradebookItem) + + localStorage.setItem(this.botArrrWallet, JSON.stringify(oldArrrTradebook)) + + this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || '[]') + + this.botArrrBuyAtAddress = tradearrrataddress + + await appDelay(1000) + + await this.buyArrrAction() + + if (this.isEmptyArray(this.tradeBotArrrBook) === true) { + return + } else { + const botamount = parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount) + + if (Number(botamount) === 0) { + this.removeBotARRRTradebook() + } + } + + if (this.isEmptyArray(this.tradeBotArrrBook) === true) { + + } else { + const checkBotArrrFunds = this.round(parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount) * parseFloat(this.tradeBotArrrBook[0].botArrrPrice)) + const myBotArrrFunds = this.round(parseFloat(this.arrrWalletBalance)) + + if (Number(myBotArrrFunds) < Number(checkBotArrrFunds)) { + this.removeBotARRRTradebook() + } + } + } + } + + const getChatLastSeen = async () => { + let items = [] + + await chatLastSeen.iterate(function (value, key, iterationNumber) { + items.push({ key, timestamp: value }) + }) + + store.dispatch(setChatLastSeen(items)) + return items + } + + await getOpenTradesBTC() + await appDelay(1000) + await getOpenTradesLTC() + await appDelay(1000) + await getOpenTradesDOGE() + await appDelay(1000) + await getOpenTradesDGB() + await appDelay(1000) + await getOpenTradesRVN() + await appDelay(1000) + await getOpenTradesARRR() + await getChatLastSeen() + + setInterval(() => { + this.clearTheCache() + }, 60000) + } + + getTourElements() { + let els = {} + + const el1 = this.shadowRoot.querySelector('core-sync-status').shadowRoot.getElementById('core-sync-status-id') + const el2 = this.shadowRoot.querySelector('show-plugin').shadowRoot.getElementById('showPluginId') + const el3 = this.shadowRoot.querySelector('beginner-checklist').shadowRoot.getElementById('popover-notification') + + if (el1) { + els['core-sync-status-id'] = el1 + } + + if (el2) { + els['tab'] = el2 + } + + if (el3) { + els['checklist'] = el3 + } + + return els + } + + clearTheCache() { + if (!isElectron()) { + } else { + console.clear() + + window.parent.electronAPI.clearMyCache() + window.parent.electronAPI.clearCache() + } + } + + async getNodeType() { + const myAppNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + const nodeAppUrl = myAppNode.protocol + '://' + myAppNode.domain + ':' + myAppNode.port + const url = `${nodeAppUrl}/admin/info` + + await fetch(url).then((response) => { + return response.json() + }).then((data) => { + this.nodeType = data.type + }) + } + + renderNodeTypeMenu() { + const addressInfo = this.addressInfo + const isMinter = addressInfo?.error !== 124 && +addressInfo?.level > 0 + const isSponsor = +addressInfo?.level >= 5 + + if (this.nodeType === 'lite') { + return html` + + + + + + + + + + + + + ${this.renderNodeManagement()} + ` + } else { + return html` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${this.renderNodeManagement()} + + ` + } + } + + renderLockButton() { + if (this.myLockScreenPass === false && this.myLockScreenSet === false) { + return html` +
+ this.openSetScreenLockPass()} title="${translate("login.lp11")}"> +
+ ` + } else if (this.myLockScreenSet === false) { + return html` +
+ this.setLockQortal()} title="${translate("login.lp11")}"> +
+ ` + } else if (this.myLockScreenSet === true) { + return html` +
+ +
+ ` + } + } + + openSetScreenLockPass() { + this.shadowRoot.getElementById('lockPassword').value = '' + this.shadowRoot.getElementById('lockPasswordConfirm').value = '' + this.shadowRoot.getElementById('setLockScreenPass').open() + } + + closeSetScreenLockPass() { + this.shadowRoot.getElementById('setLockScreenPass').close() + } + + checkPass() { + const password = this.shadowRoot.getElementById('lockPassword').value + const rePassword = this.shadowRoot.getElementById('lockPasswordConfirm').value + + if (password === '') { + let snackbar1string = get("login.pleaseenter") + parentEpml.request('showSnackBar', `${snackbar1string}`) + return + } + + if (password != rePassword) { + let snackbar2string = get("login.notmatch") + parentEpml.request('showSnackBar', `${snackbar2string}`) + return + } + + if (password.length < 8) { + let snackbar3string = get("login.lessthen8") + parentEpml.request('showSnackBar', `${snackbar3string}`) + this.lowPass = '' + this.lowPass = password + this.extraConfirm() + } + + if (password.length >= 8) { + this.setNewScreenPass() + let snackbar4string = get("login.lp6") + parentEpml.request('showSnackBar', `${snackbar4string}`) + } + } + + extraConfirm() { + this.shadowRoot.getElementById('setLockScreenPass').close() + this.shadowRoot.getElementById('extraConfirmPass').open() + } + + closExtraConfirmPass() { + this.shadowRoot.getElementById('extraConfirmPass').close() + this.shadowRoot.getElementById('lockPassword').value = '' + this.shadowRoot.getElementById('lockPasswordConfirm').value = '' + } + + setNewScreenPass() { + const rawPassword = this.shadowRoot.getElementById('lockPassword').value + const cryptPassword = encryptData(rawPassword, this.salt) + + localStorage.setItem(this.lockScreenPass, cryptPassword) + + this.myLockScreenPass = '' + this.myLockScreenPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt) + this.shadowRoot.getElementById('setLockScreenPass').close() + this.shadowRoot.getElementById('extraConfirmPass').close() + this.shadowRoot.getElementById('lockPassword').value = '' + this.shadowRoot.getElementById('lockPasswordConfirm').value = '' + } + + setLockQortal() { + this.helperMessage = this.renderHelperPass() + this.lockSet = '' + this.lockSet = encryptData(true, this.salt) + + localStorage.setItem(this.lockScreenSet, this.lockSet) + + this.myLockScreenSet = '' + this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt) + this.shadowRoot.getElementById('lockScreenActive').open() + } + + passKeyListener(e) { + if (e.key === 'Enter') { + this.closeLockScreenActive() + } + } + + async closeLockScreenActive() { + const myPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt) + const checkPass = this.shadowRoot.getElementById('unlockPassword').value + const errDelay = ms => new Promise(res => setTimeout(res, ms)) + + if (checkPass === myPass) { + this.lockSet = '' + this.lockSet = encryptData(false, this.salt) + + localStorage.setItem(this.lockScreenSet, this.lockSet) + + this.myLockScreenSet = '' + this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt) + this.shadowRoot.getElementById('lockScreenActive').close() + this.shadowRoot.getElementById('unlockPassword').value = '' + this.helperMessage = this.renderHelperPass() + } else { + this.shadowRoot.getElementById('unlockPassword').value = '' + this.helperMessage = this.renderHelperErr() + + await errDelay(3000) + + this.helperMessage = this.renderHelperPass() + } + } + + renderHelperPass() { + return html`${translate("login.pleaseenter")}` + } + + renderHelperErr() { + return html`${translate("login.lp8")}` + } + + renderNodeManagement() { + const checkNodeManagement = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + + if ((checkNodeManagement.enableManagement = true)) { + return html` + + + + ` + } else { + return html`` + } + } + + async updateQortWalletBalance() { + let qortAddress = store.getState().app.selectedAddress.address + + await parentEpml.request('apiCall', { + url: `/addresses/balance/${qortAddress}?apiKey=${this.getApiKey()}`, + }).then((res) => { + this.qortWalletBalance = res + }) + } + + async updateBtcWalletBalance() { + let _url = `/crosschain/btc/walletbalance?apiKey=${this.getApiKey()}` + let _body = store.getState().app.selectedAddress.btcWallet.derivedMasterPublicKey + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body, + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.btcWalletBalance = (Number(res) / 1e8).toFixed(8) + } + }) + } + + async updateLtcWalletBalance() { + let _url = `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}` + let _body = store.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body, + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.ltcWalletBalance = (Number(res) / 1e8).toFixed(8) + } + }) + } + + async updateDogeWalletBalance() { + let _url = `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}` + let _body = store.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body, + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.dogeWalletBalance = (Number(res) / 1e8).toFixed(8) + } + }) + } + + async updateDgbWalletBalance() { + let _url = `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}` + let _body = store.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body, + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.dgbWalletBalance = (Number(res) / 1e8).toFixed(8) + } + }) + } + + async updateRvnWalletBalance() { + let _url = `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}` + let _body = store.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body, + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.rvnWalletBalance = (Number(res) / 1e8).toFixed(8) + } + }) + } + + async updateArrrWalletBalance() { + let _url = `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}` + let _body = store.getState().app.selectedAddress.arrrWallet.seed58 + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body, + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.arrrWalletBalance = (Number(res) / 1e8).toFixed(8) + } + }) + } + + botBtcTradebook() { + if (localStorage.getItem(this.botBtcWallet) === null) { + localStorage.setItem(this.botBtcWallet, '') + } else { + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || '[]') + } + } + + removeBotBTCTradebook() { + localStorage.removeItem(this.botBtcWallet) + localStorage.setItem(this.botBtcWallet, '') + + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || '[]') + this.tradeBotAvailableBtcQortal = [] + } + + botLtcTradebook() { + if (localStorage.getItem(this.botLtcWallet) === null) { + localStorage.setItem(this.botLtcWallet, '') + } else { + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || '[]') + } + } + + removeBotLTCTradebook() { + localStorage.removeItem(this.botLtcWallet) + localStorage.setItem(this.botLtcWallet, '') + + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || '[]') + this.tradeBotAvailableLtcQortal = [] + } + + botDogeTradebook() { + if (localStorage.getItem(this.botDogeWallet) === null) { + localStorage.setItem(this.botDogeWallet, '') + } else { + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || '[]') + } + } + + removeBotDOGETradebook() { + localStorage.removeItem(this.botDogeWallet) + localStorage.setItem(this.botDogeWallet, '') + + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || '[]') + this.tradeBotAvailableDogeQortal = [] + } + + botDgbTradebook() { + if (localStorage.getItem(this.botDgbWallet) === null) { + localStorage.setItem(this.botDgbWallet, '') + } else { + this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || '[]') + } + } + + botRvnTradebook() { + if (localStorage.getItem(this.botRvnWallet) === null) { + localStorage.setItem(this.botRvnWallet, '') + } else { + this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || '[]') + } + } + + botArrrTradebook() { + if (localStorage.getItem(this.botArrrWallet) === null) { + localStorage.setItem(this.botArrrWallet, '') + } else { + this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || '[]') + } + } + + async buyBtcAction() { + const makeRequest = async () => { return await parentEpml.request('tradeBotRespondRequest', { atAddress: this.botBtcBuyAtAddress, foreignKey: store.getState().app.selectedAddress.btcWallet.derivedMasterPrivateKey, - receivingAddress: store.getState().app.selectedAddress.address, + receivingAddress: store.getState().app.selectedAddress.address }) - } + } - const manageResponse = (response) => { - if (response === true) { - let snack5string = get("tradepage.tchange23") - parentEpml.request('showSnackBar', `${snack5string}`) - } else if (response === false) { - localStorage.removeItem(this.botBtcWallet) - localStorage.setItem(this.botBtcWallet, "") + const manageResponse = (response) => { + if (response === true) { + let snack5string = get('tradepage.tchange23') + parentEpml.request('showSnackBar', `${snack5string}`) + } else if (response === false) { + localStorage.removeItem(this.botBtcWallet) + localStorage.setItem(this.botBtcWallet, '') - var oldBtcTradebook = JSON.parse(localStorage.getItem(this.botBtcWallet) || "[]") + var oldBtcTradebook = JSON.parse(localStorage.getItem(this.botBtcWallet) || '[]') - const newBtcTradebookItem = { - botBtcQortAmount: this.reAddBtcAmount, - botBtcPrice: this.reAddBtcPrice - } + const newBtcTradebookItem = { + botBtcQortAmount: this.reAddBtcAmount, + botBtcPrice: this.reAddBtcPrice + } - oldBtcTradebook.push(newBtcTradebookItem) + oldBtcTradebook.push(newBtcTradebookItem) - localStorage.setItem(this.botBtcWallet, JSON.stringify(oldBtcTradebook)) + localStorage.setItem(this.botBtcWallet, JSON.stringify(oldBtcTradebook)) - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || "[]") + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || '[]') - let snack6string = get("tradepage.tchange24") - parentEpml.request('showSnackBar', `${snack6string}`) - } else { - localStorage.removeItem(this.botBtcWallet) - localStorage.setItem(this.botBtcWallet, "") + let snack6string = get('tradepage.tchange24') + parentEpml.request('showSnackBar', `${snack6string}`) + } else { + localStorage.removeItem(this.botBtcWallet) + localStorage.setItem(this.botBtcWallet, '') - var oldBtcTradebook = JSON.parse(localStorage.getItem(this.botBtcWallet) || "[]") + var oldBtcTradebook = JSON.parse(localStorage.getItem(this.botBtcWallet) || '[]') - const newBtcTradebookItem = { - botBtcQortAmount: this.reAddBtcAmount, - botBtcPrice: this.reAddBtcPrice - } + const newBtcTradebookItem = { + botBtcQortAmount: this.reAddBtcAmount, + botBtcPrice: this.reAddBtcPrice + } - oldBtcTradebook.push(newBtcTradebookItem) + oldBtcTradebook.push(newBtcTradebookItem) - localStorage.setItem(this.botBtcWallet, JSON.stringify(oldBtcTradebook)) + localStorage.setItem(this.botBtcWallet, JSON.stringify(oldBtcTradebook)) - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || "[]") + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || '[]') - let snack7string = get("tradepage.tchange25") - parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) - } - } - const res = await makeRequest() - manageResponse(res) - } + let snack7string = get('tradepage.tchange25') + parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) + } + } - async buyLtcAction() { - const makeRequest = async () => { + const res = await makeRequest() + manageResponse(res) + } + + async buyLtcAction() { + const makeRequest = async () => { return await parentEpml.request('tradeBotRespondRequest', { atAddress: this.botLtcBuyAtAddress, foreignKey: store.getState().app.selectedAddress.ltcWallet.derivedMasterPrivateKey, - receivingAddress: store.getState().app.selectedAddress.address, + receivingAddress: store.getState().app.selectedAddress.address }) - } + } - const manageResponse = (response) => { - if (response === true) { - let snack5string = get("tradepage.tchange23") - parentEpml.request('showSnackBar', `${snack5string}`) - } else if (response === false) { - localStorage.removeItem(this.botLtcWallet) - localStorage.setItem(this.botLtcWallet, "") + const manageResponse = (response) => { + if (response === true) { + let snack5string = get('tradepage.tchange23') + parentEpml.request('showSnackBar', `${snack5string}`) + } else if (response === false) { + localStorage.removeItem(this.botLtcWallet) + localStorage.setItem(this.botLtcWallet, '') - var oldLtcTradebook = JSON.parse(localStorage.getItem(this.botLtcWallet) || "[]") + var oldLtcTradebook = JSON.parse(localStorage.getItem(this.botLtcWallet) || '[]') - const newLtcTradebookItem = { - botLtcQortAmount: this.reAddLtcAmount, - botLtcPrice: this.reAddLtcPrice - } + const newLtcTradebookItem = { + botLtcQortAmount: this.reAddLtcAmount, + botLtcPrice: this.reAddLtcPrice + } - oldLtcTradebook.push(newLtcTradebookItem) + oldLtcTradebook.push(newLtcTradebookItem) - localStorage.setItem(this.botLtcWallet, JSON.stringify(oldLtcTradebook)) + localStorage.setItem(this.botLtcWallet, JSON.stringify(oldLtcTradebook)) - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || "[]") + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || '[]') - let snack6string = get("tradepage.tchange24") - parentEpml.request('showSnackBar', `${snack6string}`) - } else { - localStorage.removeItem(this.botLtcWallet) - localStorage.setItem(this.botLtcWallet, "") + let snack6string = get('tradepage.tchange24') + parentEpml.request('showSnackBar', `${snack6string}`) + } else { + localStorage.removeItem(this.botLtcWallet) + localStorage.setItem(this.botLtcWallet, '') - var oldLtcTradebook = JSON.parse(localStorage.getItem(this.botLtcWallet) || "[]") + var oldLtcTradebook = JSON.parse(localStorage.getItem(this.botLtcWallet) || '[]') - const newLtcTradebookItem = { - botLtcQortAmount: this.reAddLtcAmount, - botLtcPrice: this.reAddLtcPrice - } + const newLtcTradebookItem = { + botLtcQortAmount: this.reAddLtcAmount, + botLtcPrice: this.reAddLtcPrice + } - oldLtcTradebook.push(newLtcTradebookItem) + oldLtcTradebook.push(newLtcTradebookItem) - localStorage.setItem(this.botLtcWallet, JSON.stringify(oldLtcTradebook)) + localStorage.setItem(this.botLtcWallet, JSON.stringify(oldLtcTradebook)) - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || "[]") + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || '[]') - let snack7string = get("tradepage.tchange25") - parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) - } - } - const res = await makeRequest() - manageResponse(res) - } + let snack7string = get('tradepage.tchange25') + parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) + } + } - async buyDogeAction() { - const makeRequest = async () => { + const res = await makeRequest() + manageResponse(res) + } + + async buyDogeAction() { + const makeRequest = async () => { return await parentEpml.request('tradeBotRespondRequest', { atAddress: this.botDogeBuyAtAddress, foreignKey: store.getState().app.selectedAddress.dogeWallet.derivedMasterPrivateKey, - receivingAddress: store.getState().app.selectedAddress.address, + receivingAddress: store.getState().app.selectedAddress.address }) - } + } - const manageResponse = (response) => { - if (response === true) { - let snack5string = get("tradepage.tchange23") - parentEpml.request('showSnackBar', `${snack5string}`) - } else if (response === false) { - localStorage.removeItem(this.botDogeWallet) - localStorage.setItem(this.botDogeWallet, "") + const manageResponse = (response) => { + if (response === true) { + let snack5string = get('tradepage.tchange23') + parentEpml.request('showSnackBar', `${snack5string}`) + } else if (response === false) { + localStorage.removeItem(this.botDogeWallet) + localStorage.setItem(this.botDogeWallet, '') - var oldDogeTradebook = JSON.parse(localStorage.getItem(this.botDogeWallet) || "[]") + var oldDogeTradebook = JSON.parse(localStorage.getItem(this.botDogeWallet) || '[]') - const newDogeTradebookItem = { - botDogeQortAmount: this.reAddDogeAmount, - botDogePrice: this.reAddDogePrice - } + const newDogeTradebookItem = { + botDogeQortAmount: this.reAddDogeAmount, + botDogePrice: this.reAddDogePrice + } - oldDogeTradebook.push(newDogeTradebookItem) + oldDogeTradebook.push(newDogeTradebookItem) - localStorage.setItem(this.botDogeWallet, JSON.stringify(oldDogeTradebook)) + localStorage.setItem(this.botDogeWallet, JSON.stringify(oldDogeTradebook)) - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || "[]") + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || '[]') - let snack6string = get("tradepage.tchange24") - parentEpml.request('showSnackBar', `${snack6string}`) - } else { - localStorage.removeItem(this.botDogeWallet) - localStorage.setItem(this.botDogeWallet, "") + let snack6string = get('tradepage.tchange24') + parentEpml.request('showSnackBar', `${snack6string}`) + } else { + localStorage.removeItem(this.botDogeWallet) + localStorage.setItem(this.botDogeWallet, '') - var oldDogeTradebook = JSON.parse(localStorage.getItem(this.botDogeWallet) || "[]") + var oldDogeTradebook = JSON.parse(localStorage.getItem(this.botDogeWallet) || '[]') - const newDogeTradebookItem = { - botDogeQortAmount: this.reAddDogeAmount, - botDogePrice: this.reAddDogePrice - } + const newDogeTradebookItem = { + botDogeQortAmount: this.reAddDogeAmount, + botDogePrice: this.reAddDogePrice + } - oldDogeTradebook.push(newDogeTradebookItem) + oldDogeTradebook.push(newDogeTradebookItem) - localStorage.setItem(this.botDogeWallet, JSON.stringify(oldDogeTradebook)) + localStorage.setItem(this.botDogeWallet, JSON.stringify(oldDogeTradebook)) - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || "[]") + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || '[]') - let snack7string = get("tradepage.tchange25") - parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) - } - } - const res = await makeRequest() - manageResponse(res) - } + let snack7string = get('tradepage.tchange25') + parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) + } + } - async buyDgbAction() { - const makeRequest = async () => { + const res = await makeRequest() + manageResponse(res) + } + + async buyDgbAction() { + const makeRequest = async () => { return await parentEpml.request('tradeBotRespondRequest', { atAddress: this.botDgbBuyAtAddress, foreignKey: store.getState().app.selectedAddress.dgbWallet.derivedMasterPrivateKey, - receivingAddress: store.getState().app.selectedAddress.address, + receivingAddress: store.getState().app.selectedAddress.address }) - } + } - const manageResponse = (response) => { - if (response === true) { - let snack5string = get("tradepage.tchange23") - parentEpml.request('showSnackBar', `${snack5string}`) - } else if (response === false) { - localStorage.removeItem(this.botDgbWallet) - localStorage.setItem(this.botDgbWallet, "") + const manageResponse = (response) => { + if (response === true) { + let snack5string = get('tradepage.tchange23') + parentEpml.request('showSnackBar', `${snack5string}`) + } else if (response === false) { + localStorage.removeItem(this.botDgbWallet) + localStorage.setItem(this.botDgbWallet, '') - var oldDgbTradebook = JSON.parse(localStorage.getItem(this.botDgbWallet) || "[]") + var oldDgbTradebook = JSON.parse(localStorage.getItem(this.botDgbWallet) || '[]') - const newDgbTradebookItem = { - botDgbQortAmount: this.reAddDgbAmount, - botDgbPrice: this.reAddDgbPrice - } + const newDgbTradebookItem = { + botDgbQortAmount: this.reAddDgbAmount, + botDgbPrice: this.reAddDgbPrice + } - oldDgbTradebook.push(newDgbTradebookItem) + oldDgbTradebook.push(newDgbTradebookItem) - localStorage.setItem(this.botDgbWallet, JSON.stringify(oldDgbTradebook)) + localStorage.setItem(this.botDgbWallet, JSON.stringify(oldDgbTradebook)) - this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || "[]") + this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || '[]') - let snack6string = get("tradepage.tchange24") - parentEpml.request('showSnackBar', `${snack6string}`) - } else { - localStorage.removeItem(this.botDgbWallet) - localStorage.setItem(this.botDgbWallet, "") + let snack6string = get('tradepage.tchange24') + parentEpml.request('showSnackBar', `${snack6string}`) + } else { + localStorage.removeItem(this.botDgbWallet) + localStorage.setItem(this.botDgbWallet, '') - var oldDgbTradebook = JSON.parse(localStorage.getItem(this.botDgbWallet) || "[]") + var oldDgbTradebook = JSON.parse(localStorage.getItem(this.botDgbWallet) || '[]') - const newDgbTradebookItem = { - botDgbQortAmount: this.reAddDgbAmount, - botDgbPrice: this.reAddDgbPrice - } + const newDgbTradebookItem = { + botDgbQortAmount: this.reAddDgbAmount, + botDgbPrice: this.reAddDgbPrice + } - oldDgbTradebook.push(newDgbTradebookItem) + oldDgbTradebook.push(newDgbTradebookItem) - localStorage.setItem(this.botDgbWallet, JSON.stringify(oldDgbTradebook)) + localStorage.setItem(this.botDgbWallet, JSON.stringify(oldDgbTradebook)) - this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || "[]") + this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || '[]') - let snack7string = get("tradepage.tchange25") - parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) - } - } - const res = await makeRequest() - manageResponse(res) - } + let snack7string = get('tradepage.tchange25') + parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) + } + } - async buyRvnAction() { - const makeRequest = async () => { + const res = await makeRequest() + manageResponse(res) + } + + async buyRvnAction() { + const makeRequest = async () => { return await parentEpml.request('tradeBotRespondRequest', { atAddress: this.botRvnBuyAtAddress, foreignKey: store.getState().app.selectedAddress.rvnWallet.derivedMasterPrivateKey, - receivingAddress: store.getState().app.selectedAddress.address, + receivingAddress: store.getState().app.selectedAddress.address }) - } + } - const manageResponse = (response) => { - if (response === true) { - let snack5string = get("tradepage.tchange23") - parentEpml.request('showSnackBar', `${snack5string}`) - } else if (response === false) { - localStorage.removeItem(this.botRvnWallet) - localStorage.setItem(this.botRvnWallet, "") + const manageResponse = (response) => { + if (response === true) { + let snack5string = get('tradepage.tchange23') + parentEpml.request('showSnackBar', `${snack5string}`) + } else if (response === false) { + localStorage.removeItem(this.botRvnWallet) + localStorage.setItem(this.botRvnWallet, '') - var oldRvnTradebook = JSON.parse(localStorage.getItem(this.botRvnWallet) || "[]") + var oldRvnTradebook = JSON.parse(localStorage.getItem(this.botRvnWallet) || '[]') - const newRvnTradebookItem = { - botRvnQortAmount: this.reAddRvnAmount, - botRvnPrice: this.reAddRvnPrice - } + const newRvnTradebookItem = { + botRvnQortAmount: this.reAddRvnAmount, + botRvnPrice: this.reAddRvnPrice + } - oldRvnTradebook.push(newRvnTradebookItem) + oldRvnTradebook.push(newRvnTradebookItem) - localStorage.setItem(this.botRvnWallet, JSON.stringify(oldRvnTradebook)) + localStorage.setItem(this.botRvnWallet, JSON.stringify(oldRvnTradebook)) - this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || "[]") + this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || '[]') - let snack6string = get("tradepage.tchange24") - parentEpml.request('showSnackBar', `${snack6string}`) - } else { - localStorage.removeItem(this.botRvnWallet) - localStorage.setItem(this.botRvnWallet, "") + let snack6string = get('tradepage.tchange24') + parentEpml.request('showSnackBar', `${snack6string}`) + } else { + localStorage.removeItem(this.botRvnWallet) + localStorage.setItem(this.botRvnWallet, '') - var oldRvnTradebook = JSON.parse(localStorage.getItem(this.botRvnWallet) || "[]") + var oldRvnTradebook = JSON.parse(localStorage.getItem(this.botRvnWallet) || '[]') - const newRvnTradebookItem = { - botRvnQortAmount: this.reAddRvnAmount, - botRvnPrice: this.reAddRvnPrice - } + const newRvnTradebookItem = { + botRvnQortAmount: this.reAddRvnAmount, + botRvnPrice: this.reAddRvnPrice + } - oldRvnTradebook.push(newRvnTradebookItem) + oldRvnTradebook.push(newRvnTradebookItem) - localStorage.setItem(this.botRvnWallet, JSON.stringify(oldRvnTradebook)) + localStorage.setItem(this.botRvnWallet, JSON.stringify(oldRvnTradebook)) - this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || "[]") + this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || '[]') - let snack7string = get("tradepage.tchange25") - parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) - } - } - const res = await makeRequest() - manageResponse(res) - } + let snack7string = get('tradepage.tchange25') + parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) + } + } - async buyArrrAction() { - const makeRequest = async () => { + const res = await makeRequest() + manageResponse(res) + } + + async buyArrrAction() { + const makeRequest = async () => { return await parentEpml.request('tradeBotRespondRequest', { atAddress: this.botArrrBuyAtAddress, foreignKey: store.getState().app.selectedAddress.arrrWallet.seed58, - receivingAddress: store.getState().app.selectedAddress.address, + receivingAddress: store.getState().app.selectedAddress.address }) - } + } - const manageResponse = (response) => { - if (response === true) { - let snack5string = get("tradepage.tchange23") - parentEpml.request('showSnackBar', `${snack5string}`) - } else if (response === false) { - localStorage.removeItem(this.botArrrWallet) - localStorage.setItem(this.botArrrWallet, "") + const manageResponse = (response) => { + if (response === true) { + let snack5string = get('tradepage.tchange23') + parentEpml.request('showSnackBar', `${snack5string}`) + } else if (response === false) { + localStorage.removeItem(this.botArrrWallet) + localStorage.setItem(this.botArrrWallet, '') - var oldArrrTradebook = JSON.parse(localStorage.getItem(this.botArrrWallet) || "[]") + var oldArrrTradebook = JSON.parse(localStorage.getItem(this.botArrrWallet) || '[]') - const newArrrTradebookItem = { - botArrrQortAmount: this.reAddArrrAmount, - botArrrPrice: this.reAddArrrPrice - } + const newArrrTradebookItem = { + botArrrQortAmount: this.reAddArrrAmount, + botArrrPrice: this.reAddArrrPrice + } - oldArrrTradebook.push(newArrrTradebookItem) + oldArrrTradebook.push(newArrrTradebookItem) - localStorage.setItem(this.botArrrWallet, JSON.stringify(oldArrrTradebook)) + localStorage.setItem(this.botArrrWallet, JSON.stringify(oldArrrTradebook)) - this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || "[]") + this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || '[]') - let snack6string = get("tradepage.tchange24") - parentEpml.request('showSnackBar', `${snack6string}`) - } else { - localStorage.removeItem(this.botArrrWallet) - localStorage.setItem(this.botArrrWallet, "") + let snack6string = get('tradepage.tchange24') + parentEpml.request('showSnackBar', `${snack6string}`) + } else { + localStorage.removeItem(this.botArrrWallet) + localStorage.setItem(this.botArrrWallet, '') - var oldArrrTradebook = JSON.parse(localStorage.getItem(this.botArrrWallet) || "[]") + var oldArrrTradebook = JSON.parse(localStorage.getItem(this.botArrrWallet) || '[]') - const newArrrTradebookItem = { - botArrrQortAmount: this.reAddArrrAmount, - botArrrPrice: this.reAddArrrPrice - } + const newArrrTradebookItem = { + botArrrQortAmount: this.reAddArrrAmount, + botArrrPrice: this.reAddArrrPrice + } - oldArrrTradebook.push(newArrrTradebookItem) + oldArrrTradebook.push(newArrrTradebookItem) - localStorage.setItem(this.botArrrWallet, JSON.stringify(oldArrrTradebook)) + localStorage.setItem(this.botArrrWallet, JSON.stringify(oldArrrTradebook)) - this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || "[]") + this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || '[]') - let snack7string = get("tradepage.tchange25") - parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) - } - } - const res = await makeRequest() - manageResponse(res) - } + let snack7string = get('tradepage.tchange25') + parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) + } + } - stateChanged(state) { - const split = state.app.url.split('/') - const sideurl = split[2] - this.config = state.config - this.urls = state.app.registeredUrls - this.addressInfo = state.app.accountInfo.addressInfo - this.showSyncMessages = state.app.showSyncIndicator + const res = await makeRequest() + manageResponse(res) + } - if (sideurl === "minting") { - this.shadowRoot.getElementById('qminter').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "become-minter") { - this.shadowRoot.getElementById('qbminter').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "sponsorship-list") { - this.shadowRoot.getElementById('qiminter').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "wallet") { - this.shadowRoot.getElementById('qwallet').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "trade-portal") { - this.shadowRoot.getElementById('qtrade').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "trade-bot-portal") { - this.shadowRoot.getElementById('qbot').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "reward-share") { - this.shadowRoot.getElementById('qrewardshare').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "q-chat") { - this.shadowRoot.getElementById('qchat').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "name-registration") { - this.shadowRoot.getElementById('qnamereg').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "names-market") { - this.shadowRoot.getElementById('qnamemarket').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "websites") { - this.shadowRoot.getElementById('qweb').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "qapps") { - this.shadowRoot.getElementById('qapp').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "group-management") { - this.shadowRoot.getElementById('qgroupmange').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "puzzles") { - this.shadowRoot.getElementById('qpuzzles').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "data-management") { - this.shadowRoot.getElementById('qdata').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "node-management") { - this.shadowRoot.getElementById('qnode').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } - } - } + stateChanged(state) { + const split = state.app.url.split('/') + const sideurl = split[2] + this.config = state.config + this.urls = state.app.registeredUrls + this.addressInfo = state.app.accountInfo.addressInfo + this.showSyncMessages = state.app.showSyncIndicator - openSettings() { - const settingsDialog = document.getElementById('main-app').shadowRoot.querySelector('app-view').shadowRoot.querySelector('user-settings') - settingsDialog.openSettings() - } + if (sideurl === 'minting') { + this.shadowRoot.getElementById('qminter').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'become-minter') { + this.shadowRoot.getElementById('qbminter').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'sponsorship-list') { + this.shadowRoot.getElementById('qiminter').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'wallet') { + this.shadowRoot.getElementById('qwallet').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'trade-portal') { + this.shadowRoot.getElementById('qtrade').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'trade-bot-portal') { + this.shadowRoot.getElementById('qbot').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'reward-share') { + this.shadowRoot.getElementById('qrewardshare').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'q-chat') { + this.shadowRoot.getElementById('qchat').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'name-registration') { + this.shadowRoot.getElementById('qnamereg').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'names-market') { + this.shadowRoot.getElementById('qnamemarket').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'websites') { + this.shadowRoot.getElementById('qweb').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'qapps') { + this.shadowRoot.getElementById('qapp').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'group-management') { + this.shadowRoot.getElementById('qgroupmange').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'puzzles') { + this.shadowRoot.getElementById('qpuzzles').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'data-management') { + this.shadowRoot.getElementById('qdata').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'node-management') { + this.shadowRoot.getElementById('qnode').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } + } + } - openLogout() { - const logoutDialog = document.getElementById('main-app').shadowRoot.querySelector('app-view').shadowRoot.querySelector('logout-view') - logoutDialog.openLogout() - } + openSettings() { + const settingsDialog = document.getElementById('main-app').shadowRoot.querySelector('app-view').shadowRoot.querySelector('user-settings') + settingsDialog.openSettings() + } - getApiKey() { - const apiNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + openLogout() { + const logoutDialog = document.getElementById('main-app').shadowRoot.querySelector('app-view').shadowRoot.querySelector('logout-view') + logoutDialog.openLogout() + } + + getApiKey() { + const apiNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] return apiNode.apiKey - } + } - isEmptyArray(arr) { - if (!arr) { - return true - } - return arr.length === 0 - } + isEmptyArray(arr) { + if (!arr) { + return true + } - round(number) { + return arr.length === 0 + } + + round(number) { return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) - } + } } window.customElements.define('app-view', AppView) diff --git a/core/src/components/base.js b/core/src/components/base.js index e5382038..1928cdf0 100644 --- a/core/src/components/base.js +++ b/core/src/components/base.js @@ -1,26 +1,11 @@ -import {css, html, LitElement} from 'lit' -import {connect} from 'pwa-helpers' -import {store} from '../store.js' +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../store' class MyElement extends connect(store)(LitElement) { - static get properties () { - return { - } - } - - static get styles () { - return css`` - } - - render () { - return html` - - ` - } - - stateChanged (state) { - } + render () { + return html`` + } } -window.customElements.define('my-element', MyElement) +window.customElements.define('my-element', MyElement) \ No newline at end of file diff --git a/core/src/components/beginner-tour/sync-indicator.js b/core/src/components/beginner-tour/sync-indicator.js index 520344b1..6071f535 100644 --- a/core/src/components/beginner-tour/sync-indicator.js +++ b/core/src/components/beginner-tour/sync-indicator.js @@ -1,11 +1,13 @@ -import {css, html, LitElement} from 'lit' -import {store} from '../../store' -import {connect} from 'pwa-helpers' -import {translate} from '../../../translate' -import {parentEpml} from '../show-plugin' - +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { parentEpml } from '../show-plugin' +import { syncIndicator2Styles } from '../../styles/core-css' import '@material/mwc-icon' +// Multi language support +import {translate} from '../../../translate' + class SyncIndicator extends connect(store)(LitElement) { static get properties() { return { @@ -18,6 +20,10 @@ class SyncIndicator extends connect(store)(LitElement) { } } + static get styles() { + return [syncIndicator2Styles] + } + constructor() { super() this.blocksBehind = 0 @@ -32,64 +38,6 @@ class SyncIndicator extends connect(store)(LitElement) { this.hasOpened = false } - static get styles() { - return css` - * { - --mdc-theme-text-primary-on-background: var(--black); - box-sizing: border-box; - } - - :host { - box-sizing: border-box; - position: fixed; - bottom: 50px; - right: 25px; - z-index: 50000; - } - - .parent { - width: 360px; - padding: 10px; - border-radius: 8px; - border: 1px solid var(--black); - display: flex; - align-items: center; - gap: 10px; - user-select: none; - background: var(--white); - } - - .row { - display: flex; - gap: 10px; - width: 100%; - } - - .column { - display: flex; - flex-direction: column; - gap: 10px; - width: 100%; - } - - .bootstrap-button { - font-family: Roboto, sans-serif; - font-size: 16px; - color: var(--mdc-theme-primary); - background-color: transparent; - padding: 8px 10px; - border-radius: 5px; - border: none; - transition: all 0.3s ease-in-out; - } - - .bootstrap-button:hover { - cursor: pointer; - background-color: #03a8f475; - } - ` - } - render() { return html` ${!this.hasCoreRunning ? html` @@ -225,7 +173,7 @@ class SyncIndicator extends connect(store)(LitElement) { this.dispatchEvent( new CustomEvent('open-welcome-modal-sync', { bubbles: true, - composed: true, + composed: true }) ) } @@ -257,4 +205,4 @@ class SyncIndicator extends connect(store)(LitElement) { } } -customElements.define('sync-indicator', SyncIndicator) \ No newline at end of file +window.customElements.define('sync-indicator', SyncIndicator) \ No newline at end of file diff --git a/core/src/components/beginner-tour/tour-component.js b/core/src/components/beginner-tour/tour-component.js index 26b16276..7496a16d 100644 --- a/core/src/components/beginner-tour/tour-component.js +++ b/core/src/components/beginner-tour/tour-component.js @@ -1,16 +1,19 @@ -import {css, html, LitElement} from 'lit'; -import {driver} from 'driver.js'; -import 'driver.js/dist/driver.css'; -import '@material/mwc-icon'; -import '@polymer/paper-spinner/paper-spinner-lite.js'; -import '@vaadin/tooltip'; -import '@material/mwc-button'; -import {get, translate} from '../../../translate'; -import '@polymer/paper-dialog/paper-dialog.js'; -import {setNewTab} from '../../redux/app/app-actions.js'; -import {store} from '../../store.js'; -import {connect} from 'pwa-helpers'; -import './tour.css'; +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { setNewTab } from '../../redux/app/app-actions' +import { tourComponentStyles } from '../../styles/core-css' +import { driver } from 'driver.js' +import 'driver.js/dist/driver.css' +import './tour.css' +import '@material/mwc-button' +import '@material/mwc-icon' +import '@polymer/paper-dialog/paper-dialog.js' +import '@polymer/paper-spinner/paper-spinner-lite.js' +import '@vaadin/tooltip' + +// Multi language support +import { get, translate } from '../../../translate' class TourComponent extends connect(store)(LitElement) { static get properties() { @@ -18,242 +21,112 @@ class TourComponent extends connect(store)(LitElement) { getElements: { attribute: false }, dialogOpenedCongrats: { type: Boolean }, hasViewedTour: { type: Boolean }, - disableTour: {type: Boolean} - }; + disableTour: { type: Boolean }, + nodeUrl: { type: String }, + address: { type: String } + } + } + + static get styles() { + return [tourComponentStyles] } constructor() { - super(); - this.dialogOpenedCongrats = false; - this._controlOpenWelcomeModal = - this._controlOpenWelcomeModal.bind(this); - this.hasName = false; - this.nodeUrl = this.getNodeUrl(); - this.myNode = this.getMyNode(); + super() + this.dialogOpenedCongrats = false + this._controlOpenWelcomeModal = this._controlOpenWelcomeModal.bind(this) + this.hasName = false + this.nodeUrl = '' + this.address = '' this._disableTour = this._disableTour.bind(this) this.disableTour = false } - static get styles() { - return css` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --mdc-theme-surface: var(--white); - --mdc-dialog-content-ink-color: var(--black); - box-sizing: border-box; - color: var(--black); - background: var(--white); - } - - :host { - box-sizing: border-box; - position: fixed; - bottom: 25px; - right: 25px; - z-index: 50000; - } - - .full-info-wrapper { - width: 100%; - min-width: 600px; - max-width: 600px; - text-align: center; - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - padding: 25px; - box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1); - display: block !important; - } - - .buttons { - display: inline; - } - .accept-button { - font-family: Roboto, sans-serif; - letter-spacing: 0.3px; - font-weight: 300; - padding: 8px 5px; - border-radius: 3px; - text-align: center; - color: var(--black); - transition: all 0.3s ease-in-out; - display: flex; - align-items: center; - gap: 10px; - font-size: 18px; - justify-content: center; - outline: 1px solid var(--black); - } - - .accept-button:hover { - cursor: pointer; - background-color: #03a8f485; - } - - .close-button { - font-family: Roboto, sans-serif; - letter-spacing: 0.3px; - font-weight: 300; - padding: 8px 5px; - border-radius: 3px; - text-align: center; - color: #f44336; - transition: all 0.3s ease-in-out; - display: flex; - align-items: center; - gap: 10px; - font-size: 18px; - width:auto; - } - - .close-button:hover { - cursor: pointer; - background-color: #f4433663; - } - `; + render() { + return html` + + ${this.dialogOpenedCongrats && this.hasViewedTour ? html` + +

Congratulations!

+
+ ${translate("tour.tour13")} +
+
+ ${translate("tour.tour14")} +
+
+ ${translate("tour.tour15")} +
+
+
{ this.onClose() }}> + ${translate("general.close")} +
+
+
+ ` : ''} + ` } - _controlOpenWelcomeModal() { - this.isSynced = true - - const seenWelcomeSync = JSON.parse( - localStorage.getItem('welcome-sync') || 'false' - ); - if (this.hasName) return; - if (seenWelcomeSync) return; - if(!this.hasViewedTour) return - this.dialogOpenedCongrats = true; - } - - openWelcomeModal() { - this.dispatchEvent( - new CustomEvent('send-tour-finished', { - bubbles: true, - composed: true, - }) - ); - const seenWelcomeSync = JSON.parse( - localStorage.getItem('welcome-sync') || 'false' - ); - if (this.hasName) return; - if (seenWelcomeSync) return; - if(!this.isSynced) return - this.dialogOpenedCongrats = true; - } - - _disableTour(){ - this.disableTour = true - driver.reset() - } - - connectedCallback() { - super.connectedCallback(); - window.addEventListener( - 'open-welcome-modal-sync', - this._controlOpenWelcomeModal - ); - window.addEventListener( - 'disable-tour', - this._disableTour - ); - } - - disconnectedCallback() { - window.removeEventListener( - 'open-welcome-modal-sync', - this._controlOpenWelcomeModal - ); - window.addEventListener( - 'disable-tour', - this._disableTour - ); - super.disconnectedCallback(); - } - - getNodeUrl() { - const myNode = - window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] - - return myNode.protocol + '://' + myNode.domain + ':' + myNode.port - } - getMyNode() { - return window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] - } - - async getName(recipient) { - try { - const endpoint = `${this.nodeUrl}/names/address/${recipient}`; - const res = await fetch(endpoint); - const getNames = await res.json(); - - if (Array.isArray(getNames) && getNames.length > 0) { - return getNames[0].name; - } else { - return ''; - } - } catch (error) { - return ''; - } - } async firstUpdated() { + this.getNodeUrl() this.address = store.getState().app.selectedAddress.address - const hasViewedTour = JSON.parse( - localStorage.getItem(`hasViewedTour-${this.address}`) || 'false' - ); - const name = await this.getName(this.address); + + const hasViewedTour = JSON.parse(localStorage.getItem(`hasViewedTour-${this.address}`) || 'false') + const name = await this.getName(this.address) + if (name) { - this.hasName = true; + this.hasName = true } - this.hasViewedTour = hasViewedTour; + + this.hasViewedTour = hasViewedTour + if (!hasViewedTour) { try { if (name) { - this.hasViewedTour = true; - this.hasName = true; + this.hasViewedTour = true + this.hasName = true localStorage.setItem(`hasViewedTour-${this.address}`, JSON.stringify(true)) } } catch (error) { - console.log({ error }); + console.log({ error }) } } + await new Promise((res) => { setTimeout(() => { - res(); - }, 1000); - }); + res() + }, 1000) + }) + if (!this.hasViewedTour && this.disableTour !== true) { - const elements = this.getElements(); - let steps = [ - { - popover: { - title: get("tour.tour6"), - description: ` -
- -
-
-

${get("tour.tour7")}

-
-
-

${get("tour.tour8")}

-
-
-

${get("tour.tour9")}

-
- `, - // ... other options - }, - }, - ]; - const step2 = elements['core-sync-status-id']; - const step3 = elements['tab']; - const step4 = elements['checklist']; + const elements = this.getElements() + + let steps = [{ + popover: { + title: get("tour.tour6"), + description: ` +
+ +
+
+
+

${get("tour.tour7")}

+
+
+
+

${get("tour.tour8")}

+
+
+
+

${get("tour.tour9")}

+
+ ` + } + }] + + const step2 = elements['core-sync-status-id'] + const step3 = elements['tab'] + const step4 = elements['checklist'] if (step2) { steps.push({ @@ -261,58 +134,54 @@ class TourComponent extends connect(store)(LitElement) { popover: { title: get("tour.tour5"), description: ` -
-

${get("tour.tour1")}

-
-
- -

${get("tour.tour2")}

-
-
- -

${get("tour.tour3")}

-
-
- -

${get("tour.tour4")}

-
+
+

${get("tour.tour1")}

+
+
+ +

${get("tour.tour2")}

+
+
+ +

${get("tour.tour3")}

+
+
+ +

${get("tour.tour4")}

+
- `, - }, - }); + ` + } + }) } + if (step3) { steps.push({ element: step3, popover: { title: 'Tab View', description: ` -
-

${get("tour.tour10")} -

-
-
- -

You can also bookmark other Q-Apps and Plugins by clicking on the ${get( - 'tabmenu.tm19' - )} button

-
- `, - }, - }); - } - if (step4) { - steps.push( - { - element: step4, - popover: { - title: get("tour.tour11"), - description: get("tour.tour12"), - }, +
+

${get("tour.tour10")}

+
+
+ +

+ You can also bookmark other Q-Apps and Plugins by clicking on the ${get('tabmenu.tm19')} button +

+
+ ` } - );this.hasViewedTour + }) } - let currentStepIndex = 0; + + if (step4) { + steps.push({ element: step4, popover: { title: get("tour.tour11"), description: get("tour.tour12")}}) + this.hasViewedTour + } + + let currentStepIndex = 0 + const driverObj = driver({ popoverClass: 'driverjs-theme', showProgress: true, @@ -321,25 +190,93 @@ class TourComponent extends connect(store)(LitElement) { allowClose: false, onDestroyed: () => { localStorage.setItem(`hasViewedTour-${this.address}`, JSON.stringify(true)) - this.hasViewedTour = true; - this.openWelcomeModal(); + this.hasViewedTour = true + this.openWelcomeModal() } - }); + }) - driverObj.drive(); + driverObj.drive() } else { this.dispatchEvent( new CustomEvent('send-tour-finished', { bubbles: true, - composed: true, + composed: true }) - ); + ) + } + } + + _controlOpenWelcomeModal() { + this.isSynced = true + + const seenWelcomeSync = JSON.parse(localStorage.getItem('welcome-sync') || 'false') + + if (this.hasName) return + if (seenWelcomeSync) return + if (!this.hasViewedTour) return + + this.dialogOpenedCongrats = true + } + + openWelcomeModal() { + this.dispatchEvent( + new CustomEvent('send-tour-finished', { + bubbles: true, + composed: true + }) + ) + + const seenWelcomeSync = JSON.parse(localStorage.getItem('welcome-sync') || 'false') + + if (this.hasName) return + if (seenWelcomeSync) return + if (!this.isSynced) return + + this.dialogOpenedCongrats = true + } + + _disableTour() { + this.disableTour = true + driver.reset() + } + + connectedCallback() { + super.connectedCallback() + window.addEventListener('open-welcome-modal-sync', this._controlOpenWelcomeModal) + window.addEventListener('disable-tour', this._disableTour) + } + + disconnectedCallback() { + window.removeEventListener('open-welcome-modal-sync', this._controlOpenWelcomeModal) + window.addEventListener('disable-tour', this._disableTour) + super.disconnectedCallback() + } + + getNodeUrl() { + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + const myNodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + this.nodeUrl = myNodeUrl + } + + async getName(recipient) { + try { + const endpoint = `${this.nodeUrl}/names/address/${recipient}` + const res = await fetch(endpoint) + const getNames = await res.json() + + if (Array.isArray(getNames) && getNames.length > 0) { + return getNames[0].name + } else { + return '' + } + } catch (error) { + return '' } } visitQtube() { - this.onClose(); - const query = `?service=APP&name=Q-Tube`; + this.onClose() + const query = `?service=APP&name=Q-Tube` store.dispatch( setNewTab({ url: `qdn/browser/index.html${query}`, @@ -350,59 +287,16 @@ class TourComponent extends connect(store)(LitElement) { page: `qdn/browser/index.html${query}`, title: 'Q-Tube', menus: [], - parent: false, - }, + parent: false + } }) - ); + ) } onClose() { localStorage.setItem(`welcome-sync-${this.address}`, JSON.stringify(true)) - this.dialogOpenedCongrats = false; - } - - render() { - return html` - - ${this.dialogOpenedCongrats && this.hasViewedTour - ? html` - -

Congratulations!

-
- ${translate("tour.tour13")} -
-
- ${translate("tour.tour14")} -
- -
- ${translate("tour.tour15")} -
-
-
{ - this.onClose() - - }} - > - ${translate("general.close")} -
-
-
- ` - : ''} - `; + this.dialogOpenedCongrats = false } } -customElements.define('tour-component', TourComponent); + +window.customElements.define('tour-component', TourComponent) \ No newline at end of file diff --git a/core/src/components/check-for-update.js b/core/src/components/check-for-update.js index 26a9a70e..4b9fcacb 100644 --- a/core/src/components/check-for-update.js +++ b/core/src/components/check-for-update.js @@ -1,10 +1,11 @@ -import {css, html, LitElement} from 'lit' -import {translate} from '../../translate' +import { html, LitElement } from 'lit' import isElectron from 'is-electron' - import '@polymer/paper-icon-button/paper-icon-button.js' import '@polymer/iron-icons/iron-icons.js' +// Multi language support +import { translate } from '../../translate' + class CheckForUpdate extends LitElement { static get properties() { return { @@ -17,11 +18,6 @@ class CheckForUpdate extends LitElement { this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' } - static styles = [ - css` - ` - ] - render() { return html` ${this.renderUpdateButton()} @@ -29,6 +25,7 @@ class CheckForUpdate extends LitElement { } firstUpdated() { + // ... } renderUpdateButton() { @@ -48,4 +45,4 @@ class CheckForUpdate extends LitElement { } } -window.customElements.define('check-for-update', CheckForUpdate) +window.customElements.define('check-for-update', CheckForUpdate) \ No newline at end of file diff --git a/core/src/components/computePowWorker.js b/core/src/components/computePowWorker.js index b89b9d84..37736224 100644 --- a/core/src/components/computePowWorker.js +++ b/core/src/components/computePowWorker.js @@ -1,82 +1,58 @@ -import {Sha256} from 'asmcrypto.js' +import { Sha256 } from 'asmcrypto.js' - -function sbrk(size, heap){ - let brk = 512 * 1024 // stack top - let old = brk - brk += size - - if (brk > heap.length) - throw new Error('heap exhausted') - - return old +function sbrk(size, heap) { + let brk = 512 * 1024 // stack top + let old = brk + brk += size + if (brk > heap.length) throw new Error('heap exhausted') + return old } self.addEventListener('message', async e => { - const response = await computePow(e.data.chatBytes, e.data.path, e.data.difficulty) - postMessage(response) + const response = await computePow(e.data.chatBytes, e.data.path, e.data.difficulty) + postMessage(response) }) - const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 }) const heap = new Uint8Array(memory.buffer) - - const computePow = async (chatBytes, path, difficulty) => { - - let response = null - - await new Promise((resolve, reject)=> { - - const _chatBytesArray = Object.keys(chatBytes).map(function (key) { return chatBytes[key]; }); - const chatBytesArray = new Uint8Array(_chatBytesArray); - const chatBytesHash = new Sha256().process(chatBytesArray).finish().result; - const hashPtr = sbrk(32, heap); - const hashAry = new Uint8Array(memory.buffer, hashPtr, 32); - hashAry.set(chatBytesHash); - - - const workBufferLength = 8 * 1024 * 1024; - const workBufferPtr = sbrk(workBufferLength, heap); - - - - const importObject = { - env: { - memory: memory - }, - }; - - function loadWebAssembly(filename, imports) { - // Fetch the file and compile it - return fetch(filename) - .then(response => response.arrayBuffer()) - .then(buffer => WebAssembly.compile(buffer)) - .then(module => { - - // Create the instance. - return new WebAssembly.Instance(module, importObject); - }); -} - - -loadWebAssembly(path) - .then(wasmModule => { - response = { - nonce : wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty), - chatBytesArray - } - - resolve() - - }); - - - }) - - return response -} + let response = null + await new Promise((resolve, reject) => { + const _chatBytesArray = Object.keys(chatBytes).map(function (key) { return chatBytes[key]; }) + const chatBytesArray = new Uint8Array(_chatBytesArray) + const chatBytesHash = new Sha256().process(chatBytesArray).finish().result + const hashPtr = sbrk(32, heap) + const hashAry = new Uint8Array(memory.buffer, hashPtr, 32) + hashAry.set(chatBytesHash) + const workBufferLength = 8 * 1024 * 1024 + const workBufferPtr = sbrk(workBufferLength, heap) + const importObject = { + env: { + memory: memory + } + } + function loadWebAssembly(filename, imports) { + // Fetch the file and compile it + return fetch(filename) + .then(response => response.arrayBuffer()) + .then(buffer => WebAssembly.compile(buffer)) + .then(module => { + // Create the instance. + return new WebAssembly.Instance(module, importObject) + }) + } + loadWebAssembly(path) + .then(wasmModule => { + response = { + nonce: wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty), + chatBytesArray + } + resolve() + }) + }) + return response +} \ No newline at end of file diff --git a/core/src/components/computePowWorkerFile.js b/core/src/components/computePowWorkerFile.js index d9f5f662..a13e6ec7 100644 --- a/core/src/components/computePowWorkerFile.js +++ b/core/src/components/computePowWorkerFile.js @@ -1,92 +1,68 @@ import { Sha256 } from 'asmcrypto.js' - - -function sbrk(size, heap){ - let brk = 512 * 1024 // stack top - let old = brk - brk += size - - if (brk > heap.length) - throw new Error('heap exhausted') - - return old +function sbrk(size, heap) { + let brk = 512 * 1024 // stack top + let old = brk + brk += size + if (brk > heap.length) throw new Error('heap exhausted') + return old } - - - self.addEventListener('message', async e => { - const response = await computePow(e.data.convertedBytes, e.data.path) - postMessage(response) - -}) + const response = await computePow(e.data.convertedBytes, e.data.path) + postMessage(response) +}) const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 }) const heap = new Uint8Array(memory.buffer) - - const computePow = async (convertedBytes, path) => { + let response = null + await new Promise((resolve, reject) => { + const _convertedBytesArray = Object.keys(convertedBytes).map( + function (key) { + return convertedBytes[key] + } + ) + const convertedBytesArray = new Uint8Array(_convertedBytesArray) + const convertedBytesHash = new Sha256() + .process(convertedBytesArray) + .finish().result + const hashPtr = sbrk(32, heap) + const hashAry = new Uint8Array( + memory.buffer, + hashPtr, + 32 + ) + hashAry.set(convertedBytesHash) + const difficulty = 14 + const workBufferLength = 8 * 1024 * 1024 + const workBufferPtr = sbrk( + workBufferLength, + heap + ) + const importObject = { + env: { + memory: memory + } + } + function loadWebAssembly(filename, imports) { + return fetch(filename) + .then(response => response.arrayBuffer()) + .then(buffer => WebAssembly.compile(buffer)) + .then(module => { + return new WebAssembly.Instance(module, importObject) + }) + } + loadWebAssembly(path) + .then(wasmModule => { + response = { + nonce: wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty), - - let response = null - - await new Promise((resolve, reject)=> { - - const _convertedBytesArray = Object.keys(convertedBytes).map( - function (key) { - return convertedBytes[key] - } -) -const convertedBytesArray = new Uint8Array(_convertedBytesArray) -const convertedBytesHash = new Sha256() - .process(convertedBytesArray) - .finish().result -const hashPtr = sbrk(32, heap) -const hashAry = new Uint8Array( - memory.buffer, - hashPtr, - 32 -) - -hashAry.set(convertedBytesHash) -const difficulty = 14 -const workBufferLength = 8 * 1024 * 1024 -const workBufferPtr = sbrk( - workBufferLength, - heap -) - - const importObject = { - env: { - memory: memory - }, - }; - - function loadWebAssembly(filename, imports) { - return fetch(filename) - .then(response => response.arrayBuffer()) - .then(buffer => WebAssembly.compile(buffer)) - .then(module => { - return new WebAssembly.Instance(module, importObject); - }); -} - - -loadWebAssembly(path) - .then(wasmModule => { - response = { - nonce : wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty), - - } - resolve() - - }); - - - }) - - return response + } + resolve() + }) + }) + return response } \ No newline at end of file diff --git a/core/src/components/controllers/coin-balances-controller.js b/core/src/components/controllers/coin-balances-controller.js index 7bcdabad..b5b8c483 100644 --- a/core/src/components/controllers/coin-balances-controller.js +++ b/core/src/components/controllers/coin-balances-controller.js @@ -1,320 +1,303 @@ -import {html, LitElement} from 'lit'; -import '@material/mwc-icon'; -import {store} from '../../store'; -import {connect} from 'pwa-helpers'; -import '@vaadin/tooltip'; -import {parentEpml} from '../show-plugin'; -import {setCoinBalances} from '../../redux/app/app-actions'; +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { parentEpml } from '../show-plugin' +import { setCoinBalances } from '../../redux/app/app-actions' class CoinBalancesController extends connect(store)(LitElement) { static get properties() { return { - coinList: { type: Object }, - }; + coinList: { type: Object } + } } constructor() { super(); this.coinList = {} - this.nodeUrl = this.getNodeUrl(); - this.myNode = this.getMyNode(); - this.fetchBalance = this.fetchBalance.bind(this) - this._updateCoinList = this._updateCoinList.bind(this) - this.stop = false + this.nodeUrl = this.getNodeUrl() + this.myNode = this.getMyNode() + this.fetchBalance = this.fetchBalance.bind(this) + this._updateCoinList = this._updateCoinList.bind(this) + this.stop = false } - getNodeUrl() { - const myNode = - store.getState().app.nodeConfig.knownNodes[ - store.getState().app.nodeConfig.node - ] + render() { + return html`` + } + getNodeUrl() { + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] return myNode.protocol + '://' + myNode.domain + ':' + myNode.port } + getMyNode() { - return store.getState().app.nodeConfig.knownNodes[ - store.getState().app.nodeConfig.node - ] + return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] } + async updateQortWalletBalance() { + let qortAddress = store.getState().app.selectedAddress.address - async updateArrrWalletBalance() { - let _url = `/crosschain/arrr/walletbalance?apiKey=${this.myNode.apiKey}` - let _body = store.getState().app.selectedAddress.arrrWallet.seed58 - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.arrrWalletBalance = (Number(res) / 1e8).toFixed(8) - store.dispatch( - setCoinBalances({ - type: 'arrr', - fullValue: Number(res) - }) - ); - } - }).catch(()=> { - console.log('error') - }) - } - async updateQortWalletBalance() { - let qortAddress = store.getState().app.selectedAddress.address - - await parentEpml.request('apiCall', { - url: `/addresses/balance/${qortAddress}?apiKey=${this.myNode.apiKey}`, - }).then((res) => { - this.qortWalletBalance = res - store.dispatch( - setCoinBalances({ - type: 'qort', - fullValue: Number(res) - }) - ); - }).catch(()=> { - console.log('error') - }) - } - - async updateRvnWalletBalance() { - let _url = `/crosschain/rvn/walletbalance?apiKey=${this.myNode.apiKey}` - let _body = store.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.rvnWalletBalance = (Number(res) / 1e8).toFixed(8) - store.dispatch( - setCoinBalances({ - type: 'rvn', - fullValue: Number(res) - }) - ); - } - }).catch(()=> { - console.log('error') - }) - } - - async updateDgbWalletBalance() { - let _url = `/crosschain/dgb/walletbalance?apiKey=${this.myNode.apiKey}` - let _body = store.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.dgbWalletBalance = (Number(res) / 1e8).toFixed(8) - store.dispatch( - setCoinBalances({ - type: 'dgb', - fullValue: Number(res) - }) - ); - } - }).catch(()=> { - console.log('error') - }) - } - - async updateDogeWalletBalance() { - let _url = `/crosschain/doge/walletbalance?apiKey=${this.myNode.apiKey}` - let _body = store.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.dogeWalletBalance = (Number(res) / 1e8).toFixed(8) - store.dispatch( - setCoinBalances({ - type: 'doge', - fullValue: Number(res) - }) - ); - } - }).catch(()=> { - console.log('error') - }) - } - - async updateBtcWalletBalance() { - let _url = `/crosschain/btc/walletbalance?apiKey=${this.myNode.apiKey}` - let _body = store.getState().app.selectedAddress.btcWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.btcWalletBalance = (Number(res) / 1e8).toFixed(8) - store.dispatch( - setCoinBalances({ - type: 'btc', - fullValue: Number(res) - }) - ); - } - }).catch(()=> { - console.log('error') - }) - } - - async updateLtcWalletBalance() { - let _url = `/crosschain/ltc/walletbalance?apiKey=${this.myNode.apiKey}` - let _body = store.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.ltcWalletBalance = (Number(res) / 1e8).toFixed(8) - store.dispatch( - setCoinBalances({ - type: 'ltc', - fullValue: Number(res) - }) - ); - - } - }).catch(()=> { - console.log('error') - }) - } - - _updateCoinList(event) { - const copyCoinList = {...this.coinList} - const coin = event.detail - if(!copyCoinList[coin]){ - try { - if(coin === 'ltc'){ - this.updateLtcWalletBalance() - } else if(coin === 'qort'){ - this.updateQortWalletBalance() - } else if(coin === 'doge'){ - this.updateDogeWalletBalance() - } else if(coin === 'btc'){ - this.updateBtcWalletBalance() - } else if(coin === 'dgb'){ - this.updateDgbWalletBalance() - } else if(coin === 'rvn'){ - this.updateRvnWalletBalance() - }else if(coin === 'arrr'){ - this.updateArrrWalletBalance() - } - } catch (error) { - - } - } - copyCoinList[coin] = Date.now() + 120000; - this.coinList = copyCoinList - - this.requestUpdate() + await parentEpml.request('apiCall', { + url: `/addresses/balance/${qortAddress}?apiKey=${this.myNode.apiKey}`, + }).then((res) => { + this.qortWalletBalance = res + store.dispatch( + setCoinBalances({ + type: 'qort', + fullValue: Number(res) + }) + ) + }).catch(() => { + console.log('error') + }) } + async updateBtcWalletBalance() { + let _url = `/crosschain/btc/walletbalance?apiKey=${this.myNode.apiKey}` + let _body = store.getState().app.selectedAddress.btcWallet.derivedMasterPublicKey - async fetchCoins(arrayOfCoins){ - const getCoinBalances = (arrayOfCoins || []).map( - async (coin) => { - if(coin === 'ltc'){ - await this.updateLtcWalletBalance() - } else if(coin === 'qort'){ - await this.updateQortWalletBalance() - } else if(coin === 'doge'){ - await this.updateDogeWalletBalance() - } else if(coin === 'btc'){ - await this.updateBtcWalletBalance() - } else if(coin === 'dgb'){ - await this.updateDgbWalletBalance() - } else if(coin === 'rvn'){ - await this.updateRvnWalletBalance() - }else if(coin === 'arrr'){ - await this.updateArrrWalletBalance() - } - }) + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.btcWalletBalance = (Number(res) / 1e8).toFixed(8) + store.dispatch( + setCoinBalances({ + type: 'btc', + fullValue: Number(res) + }) + ) + } + }).catch(() => { + console.log('error') + }) + } - await Promise.all(getCoinBalances); + async updateLtcWalletBalance() { + let _url = `/crosschain/ltc/walletbalance?apiKey=${this.myNode.apiKey}` + let _body = store.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey - } + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.ltcWalletBalance = (Number(res) / 1e8).toFixed(8) + store.dispatch( + setCoinBalances({ + type: 'ltc', + fullValue: Number(res) + }) + ) - async fetchBalance(){ - try { - let arrayOfCoins = [] - const copyObject = {...this.coinList} - const currentDate = Date.now() - const array = Object.keys(this.coinList) - for (const key of array) { - const item = this.coinList[key] + } + }).catch(() => { + console.log('error') + }) + } - if(item < currentDate){ - delete copyObject[key] - } else { - arrayOfCoins.push(key) - } - } - if(!this.stop){ - this.stop = true - await this.fetchCoins(arrayOfCoins) - this.stop = false - } - this.coinList = copyObject - } catch (error) { - this.stop = false - } - } + async updateDogeWalletBalance() { + let _url = `/crosschain/doge/walletbalance?apiKey=${this.myNode.apiKey}` + let _body = store.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey - connectedCallback() { - super.connectedCallback(); - this.intervalID = setInterval(this.fetchBalance, 45000); - window.addEventListener( - 'ping-coin-controller-with-coin', - this._updateCoinList - ); + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.dogeWalletBalance = (Number(res) / 1e8).toFixed(8) + store.dispatch( + setCoinBalances({ + type: 'doge', + fullValue: Number(res) + }) + ) + } + }).catch(() => { + console.log('error') + }) + } + + async updateDgbWalletBalance() { + let _url = `/crosschain/dgb/walletbalance?apiKey=${this.myNode.apiKey}` + let _body = store.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.dgbWalletBalance = (Number(res) / 1e8).toFixed(8) + store.dispatch( + setCoinBalances({ + type: 'dgb', + fullValue: Number(res) + }) + ) + } + }).catch(() => { + console.log('error') + }) + } + + async updateRvnWalletBalance() { + let _url = `/crosschain/rvn/walletbalance?apiKey=${this.myNode.apiKey}` + let _body = store.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.rvnWalletBalance = (Number(res) / 1e8).toFixed(8) + store.dispatch( + setCoinBalances({ + type: 'rvn', + fullValue: Number(res) + }) + ) + } + }).catch(() => { + console.log('error') + }) + } + + async updateArrrWalletBalance() { + let _url = `/crosschain/arrr/walletbalance?apiKey=${this.myNode.apiKey}` + let _body = store.getState().app.selectedAddress.arrrWallet.seed58 + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body, + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.arrrWalletBalance = (Number(res) / 1e8).toFixed(8) + store.dispatch( + setCoinBalances({ + type: 'arrr', + fullValue: Number(res) + }) + ) + } + }).catch(() => { + console.log('error') + }) + } + + _updateCoinList(event) { + const copyCoinList = { ...this.coinList } + const coin = event.detail + + if (!copyCoinList[coin]) { + try { + if (coin === 'qort') { + this.updateQortWalletBalance() + } else if (coin === 'btc') { + this.updateBtcWalletBalance() + } else if (coin === 'ltc') { + this.updateLtcWalletBalance() + } else if (coin === 'doge') { + this.updateDogeWalletBalance() + } else if (coin === 'dgb') { + this.updateDgbWalletBalance() + } else if (coin === 'rvn') { + this.updateRvnWalletBalance() + } else if (coin === 'arrr') { + this.updateArrrWalletBalance() + } + } catch (error) { } + } + + copyCoinList[coin] = Date.now() + 120000 + + this.coinList = copyCoinList + this.requestUpdate() + } + + async fetchCoins(arrayOfCoins) { + const getCoinBalances = (arrayOfCoins || []).map(async (coin) => { + if (coin === 'qort') { + await this.updateQortWalletBalance() + } else if (coin === 'btc') { + await this.updateBtcWalletBalance() + } else if (coin === 'ltc') { + await this.updateLtcWalletBalance() + } else if (coin === 'doge') { + await this.updateDogeWalletBalance() + } else if (coin === 'dgb') { + await this.updateDgbWalletBalance() + } else if (coin === 'rvn') { + await this.updateRvnWalletBalance() + } else if (coin === 'arrr') { + await this.updateArrrWalletBalance() + } + }) + + await Promise.all(getCoinBalances) + } + + async fetchBalance() { + try { + let arrayOfCoins = [] + + const copyObject = { ...this.coinList } + const currentDate = Date.now() + const array = Object.keys(this.coinList) + + for (const key of array) { + const item = this.coinList[key] + + if (item < currentDate) { + delete copyObject[key] + } else { + arrayOfCoins.push(key) + } + } + + if (!this.stop) { + this.stop = true + + await this.fetchCoins(arrayOfCoins) + + this.stop = false + } + + this.coinList = copyObject + } catch (error) { + this.stop = false + } + } + + connectedCallback() { + super.connectedCallback() + this.intervalID = setInterval(this.fetchBalance, 45000) + window.addEventListener('ping-coin-controller-with-coin', this._updateCoinList) } disconnectedCallback() { - - super.disconnectedCallback(); - window.removeEventListener( - 'ping-coin-controller-with-coin', - this._updateCoinList - ); - if(this.intervalID){ - clearInterval(this.intervalID); - - } - - } - - - - render() { - return html``; + if (this.intervalID) { clearInterval(this.intervalID) } + window.removeEventListener('ping-coin-controller-with-coin', this._updateCoinList) + super.disconnectedCallback() } } -customElements.define('coin-balances-controller', CoinBalancesController); +window.customElements.define('coin-balances-controller', CoinBalancesController) \ No newline at end of file diff --git a/core/src/components/friends-view/ChatSideNavHeads.js b/core/src/components/friends-view/ChatSideNavHeads.js index d2f6ebdd..c69b09f8 100644 --- a/core/src/components/friends-view/ChatSideNavHeads.js +++ b/core/src/components/friends-view/ChatSideNavHeads.js @@ -1,221 +1,204 @@ -import {css, html, LitElement} from 'lit' -import {get} from '../../../translate' -import '@material/mwc-icon' -import '@vaadin/tooltip'; - +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { get } from '../../../translate' +import { chatSideNavHeadsStyles } from '../../styles/core-css' import './friend-item-actions' +import '@material/mwc-icon' +import '@vaadin/tooltip' -class ChatSideNavHeads extends LitElement { - static get properties() { - return { - selectedAddress: { type: Object }, - config: { type: Object }, - chatInfo: { type: Object }, - iconName: { type: String }, - activeChatHeadUrl: { type: String }, - isImageLoaded: { type: Boolean }, - setActiveChatHeadUrl: {attribute: false}, - openEditFriend: {attribute: false}, - closeSidePanel: {attribute: false, type: Object} - } - } +class ChatSideNavHeads extends connect(store)(LitElement) { + static get properties() { + return { + selectedAddress: { type: Object }, + config: { type: Object }, + chatInfo: { type: Object }, + iconName: { type: String }, + activeChatHeadUrl: { type: String }, + isImageLoaded: { type: Boolean }, + setActiveChatHeadUrl: { attribute: false }, + openEditFriend: { attribute: false }, + closeSidePanel: { attribute: false, type: Object } + } + } - static get styles() { - return css` - :host { - width: 100%; - } - ul { - list-style-type: none; - } - li { - padding: 10px 2px 10px 5px; - cursor: pointer; - width: 100%; - display: flex; - box-sizing: border-box; - font-size: 14px; - transition: 0.2s background-color; - } + static get styles() { + return [chatSideNavHeadsStyles] + } - li:hover { - background-color: var(--lightChatHeadHover); - } - - .active { - background: var(--menuactive); - border-left: 4px solid #3498db; - } - - .img-icon { - font-size:40px; - color: var(--chat-group); - } - - .status { - color: #92959e; - } - - .clearfix { - display: flex; - align-items: center; - } - - .clearfix:after { - visibility: hidden; - display: block; - font-size: 0; - content: " "; - clear: both; - height: 0; - } - ` - } - - constructor() { - super() - this.selectedAddress = {} - this.config = { - user: { - node: { - - } - } - } - this.chatInfo = {} - this.iconName = '' - this.activeChatHeadUrl = '' - this.isImageLoaded = false - this.imageFetches = 0 - } - - createImage(imageUrl) { - const imageHTMLRes = new Image(); - imageHTMLRes.src = imageUrl; - imageHTMLRes.style= "width:30px; height:30px; float: left; border-radius:50%; font-size:14px"; - imageHTMLRes.onclick= () => { - this.openDialogImage = true; - } - imageHTMLRes.onload = () => { - this.isImageLoaded = true; - } - imageHTMLRes.onerror = () => { - if (this.imageFetches < 4) { - setTimeout(() => { - this.imageFetches = this.imageFetches + 1; - imageHTMLRes.src = imageUrl; - }, 500); - } else { - this.isImageLoaded = false - } - }; - return imageHTMLRes; - } - - render() { - let avatarImg = "" - if (this.chatInfo.name) { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port; - const avatarUrl = `${nodeUrl}/arbitrary/THUMBNAIL/${this.chatInfo.name}/qortal_avatar?async=true&apiKey=${myNode.apiKey}`; - avatarImg = this.createImage(avatarUrl) - } - - return html` -
  • { - const target = e.target - const popover = - this.shadowRoot.querySelector('friend-item-actions'); - if (popover) { - popover.openPopover(target); + constructor() { + super() + this.selectedAddress = {} + this.config = { + user: { + node: { } - }} class="clearfix" id=${`friend-item-parent-${this.chatInfo.name}`}> -
    - ${this.isImageLoaded ? html`${avatarImg}` : html``} - ${!this.isImageLoaded && !this.chatInfo.name && !this.chatInfo.groupName - ? html`account_circle` - : html``} - ${!this.isImageLoaded && this.chatInfo.name - ? html`
    - ${this.chatInfo.name.charAt(0)} -
    ` - : ""} - ${!this.isImageLoaded && this.chatInfo.groupName - ? html`
    - ${this.chatInfo.groupName.charAt(0)} -
    ` - : ""} -
    -
    - - ${this.chatInfo.groupName - ? this.chatInfo.groupName - : this.chatInfo.name !== undefined - ? (this.chatInfo.alias || this.chatInfo.name) - : this.chatInfo.address.substr(0, 15)} - -
    -
    + } + } + this.chatInfo = {} + this.iconName = '' + this.activeChatHeadUrl = '' + this.isImageLoaded = false + this.imageFetches = 0 + } -
    -
    - ${this.chatInfo.willFollow ? html` - connect_without_contact - - - ` : ''} -
    -
  • - { - this.openEditFriend(this.chatInfo) - }} - name=${this.chatInfo.name} - .closeSidePanel=${this.closeSidePanel} - > - ` - } + if (this.chatInfo.name) { + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const avatarUrl = `${nodeUrl}/arbitrary/THUMBNAIL/${this.chatInfo.name}/qortal_avatar?async=true` + avatarImg = this.createImage(avatarUrl) + } + return html` +
  • { + const target = e.target + const popover = this.shadowRoot.querySelector('friend-item-actions'); + if (popover) { + popover.openPopover(target); + } + }} + class="clearfix" id=${`friend-item-parent-${this.chatInfo.name}`} + > +
    + ${this.isImageLoaded ? html`${avatarImg}` : html``} + ${!this.isImageLoaded && !this.chatInfo.name && !this.chatInfo.groupName ? + html` + account_circle + ` + : html`` + } + ${!this.isImageLoaded && this.chatInfo.name ? + html` +
    + ${this.chatInfo.name.charAt(0)} +
    + ` : '' + } + ${!this.isImageLoaded && this.chatInfo.groupName ? + html` +
    + ${this.chatInfo.groupName.charAt(0)} +
    + ` : '' + } +
    +
    + + ${this.chatInfo.groupName + ? this.chatInfo.groupName + : this.chatInfo.name !== undefined + ? (this.chatInfo.alias || this.chatInfo.name) + : this.chatInfo.address.substr(0, 15) + } + +
    +
    +
    +
    + ${this.chatInfo.willFollow ? + html` + connect_without_contact + + ` : '' + } +
    +
  • + { + this.openEditFriend(this.chatInfo) + }} + name=${this.chatInfo.name} + .closeSidePanel=${this.closeSidePanel} + > + ` + } + firstUpdated() { + // ... + } - shouldUpdate(changedProperties) { - if(changedProperties.has('activeChatHeadUrl')){ - return true - } - if(changedProperties.has('chatInfo')){ - return true - } - return !!changedProperties.has('isImageLoaded'); + createImage(imageUrl) { + const imageHTMLRes = new Image() + imageHTMLRes.src = imageUrl + imageHTMLRes.style = "width:30px; height:30px; float: left; border-radius:50%; font-size:14px" + imageHTMLRes.onclick = () => { + this.openDialogImage = true + } - } + imageHTMLRes.onload = () => { + this.isImageLoaded = true + } - getUrl(chatUrl) { - this.setActiveChatHeadUrl(chatUrl) - } + imageHTMLRes.onerror = () => { + if (this.imageFetches < 4) { + setTimeout(() => { + this.imageFetches = this.imageFetches + 1 + imageHTMLRes.src = imageUrl + }, 500) + } else { + this.isImageLoaded = false + } + } + return imageHTMLRes + } + shouldUpdate(changedProperties) { + if (changedProperties.has('activeChatHeadUrl')) { + return true + } + + if (changedProperties.has('chatInfo')) { + return true + } + + return !!changedProperties.has('isImageLoaded') + } + + getUrl(chatUrl) { + this.setActiveChatHeadUrl(chatUrl) + } + + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } -window.customElements.define('chat-side-nav-heads', ChatSideNavHeads) +window.customElements.define('chat-side-nav-heads', ChatSideNavHeads) \ No newline at end of file diff --git a/core/src/components/friends-view/add-friends-modal.js b/core/src/components/friends-view/add-friends-modal.js index 1e6f4ddd..b2026b8d 100644 --- a/core/src/components/friends-view/add-friends-modal.js +++ b/core/src/components/friends-view/add-friends-modal.js @@ -1,10 +1,11 @@ -import {css, html, LitElement} from 'lit'; -import {translate,} from '../../../translate' -import '@material/mwc-button'; -import '@material/mwc-dialog'; -import '@material/mwc-checkbox'; -import {connect} from 'pwa-helpers'; -import {store} from '../../store'; +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { translate, } from '../../../translate' +import { addFriendsModalStyles } from '../../styles/core-css' +import '@material/mwc-button' +import '@material/mwc-checkbox' +import '@material/mwc-dialog' import '@polymer/paper-spinner/paper-spinner-lite.js' class AddFriendsModal extends connect(store)(LitElement) { @@ -21,199 +22,195 @@ class AddFriendsModal extends connect(store)(LitElement) { editContent: { type: Object }, onClose: { attribute: false }, mySelectedFeeds: { type: Array }, - availableFeeedSchemas: {type: Array}, - isLoadingSchemas: {type: Boolean} - }; - } - - constructor() { - super(); - this.isOpen = false; - this.isLoading = false; - this.alias = ''; - this.willFollow = true; - this.notes = ''; - this.nodeUrl = this.getNodeUrl(); - this.myNode = this.getMyNode(); - this.mySelectedFeeds = []; - this.availableFeeedSchemas = []; - this.isLoadingSchemas= false; + availableFeeedSchemas: { type: Array }, + isLoadingSchemas: { type: Boolean } + } } static get styles() { - return css` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --mdc-theme-surface: var(--white); - --mdc-dialog-content-ink-color: var(--black); - --mdc-dialog-min-width: 400px; - --mdc-dialog-max-width: 1024px; - box-sizing:border-box; - } - .input { - width: 90%; - outline: 0; - border-width: 0 0 2px; - border-color: var(--mdc-theme-primary); - background-color: transparent; - padding: 10px; - font-family: Roboto, sans-serif; - font-size: 15px; - color: var(--chat-bubble-msg-color); - box-sizing: border-box; - } - - .input::selection { - background-color: var(--mdc-theme-primary); - color: white; - } - - .input::placeholder { - opacity: 0.6; - color: var(--black); - } - - .modal-button { - font-family: Roboto, sans-serif; - font-size: 16px; - color: var(--mdc-theme-primary); - background-color: transparent; - padding: 8px 10px; - border-radius: 5px; - border: none; - transition: all 0.3s ease-in-out; - } - - .modal-button-red { - font-family: Roboto, sans-serif; - font-size: 16px; - color: #f44336; - background-color: transparent; - padding: 8px 10px; - border-radius: 5px; - border: none; - transition: all 0.3s ease-in-out; - } - - .modal-button-red:hover { - cursor: pointer; - background-color: #f4433663; - } - - .modal-button:hover { - cursor: pointer; - background-color: #03a8f475; - } - .checkbox-row { - position: relative; - display: flex; - align-items: center; - align-content: center; - font-family: Montserrat, sans-serif; - font-weight: 600; - color: var(--black); - } - .modal-overlay { - display: block; - position: fixed; - top: 0; - left: 0; - width: 100vw; - height: 100vh; - background-color: rgba( - 0, - 0, - 0, - 0.5 - ); /* Semi-transparent backdrop */ - z-index: 1000; - } - - .modal-content { - position: fixed; - top: 50vh; - left: 50vw; - transform: translate(-50%, -50%); - background-color: var(--mdc-theme-surface); - width: 80vw; - max-width: 600px; - padding: 20px; - box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 6px; - z-index: 1001; - border-radius: 5px; - display: flex; - flex-direction:column; - } - - - .modal-overlay.hidden { - display: none; - } - .avatar { - width: 36px; - height: 36px; - display: flex; - align-items: center; - } - - .app-name { - display: flex; - gap: 20px; - align-items: center; - width: 100%; - cursor: pointer; - padding: 5px; - border-radius: 5px; - margin-bottom: 10px; - } - .inner-content { - display: flex; - flex-direction: column; - max-height: 75vh; - flex-grow: 1; - overflow: auto; - } - - .inner-content::-webkit-scrollbar-track { - background-color: whitesmoke; - border-radius: 7px; - } - - .inner-content::-webkit-scrollbar { - width: 12px; - border-radius: 7px; - background-color: whitesmoke; - } - - .inner-content::-webkit-scrollbar-thumb { - background-color: rgb(180, 176, 176); - border-radius: 7px; - transition: all 0.3s ease-in-out; - } - `; + return [addFriendsModalStyles] } - firstUpdated() {} + constructor() { + super() + this.isOpen = false + this.isLoading = false + this.alias = '' + this.willFollow = true + this.notes = '' + this.nodeUrl = this.getNodeUrl() + this.myNode = this.getMyNode() + this.mySelectedFeeds = [] + this.availableFeeedSchemas = [] + this.isLoadingSchemas = false + } + + render() { + return html` + + ` + } + + firstUpdated() { + // ... + } getNodeUrl() { - const myNode = - store.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ]; - - return myNode.protocol + '://' + myNode.domain + ':' + myNode.port; + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return myNode.protocol + '://' + myNode.domain + ':' + myNode.port } + getMyNode() { - return store.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ]; + return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] } clearFields() { - this.alias = ''; - this.willFollow = true; - this.notes = ''; + this.alias = '' + this.willFollow = true + this.notes = '' } addFriend() { @@ -223,10 +220,10 @@ class AddFriendsModal extends connect(store)(LitElement) { notes: this.notes, willFollow: this.willFollow, mySelectedFeeds: this.mySelectedFeeds + }) - }); - this.clearFields(); - this.onClose(); + this.clearFields() + this.onClose() } removeFriend() { @@ -239,244 +236,60 @@ class AddFriendsModal extends connect(store)(LitElement) { mySelectedFeeds: this.mySelectedFeeds }, true - ); - this.clearFields(); - this.onClose(); + ) + + this.clearFields() + this.onClose() } async updated(changedProperties) { - if ( - changedProperties && - changedProperties.has('editContent') && - this.editContent - ) { - this.userSelected = { - name: this.editContent.name ?? '', - }; - this.notes = this.editContent.notes ?? ''; - this.willFollow = this.editContent.willFollow ?? true; - this.alias = this.editContent.alias ?? ''; + if (changedProperties && changedProperties.has('editContent') && this.editContent) { + this.userSelected = { name: this.editContent.name ?? '' } + this.notes = this.editContent.notes ?? '' + this.willFollow = this.editContent.willFollow ?? true + this.alias = this.editContent.alias ?? '' this.requestUpdate() } - if ( - changedProperties && - changedProperties.has('isOpen') && this.isOpen - ) { + + if (changedProperties && changedProperties.has('isOpen') && this.isOpen) { await this.getAvailableFeedSchemas() } - } async getAvailableFeedSchemas() { try { - this.isLoadingSchemas= true - const url = `${this.nodeUrl}/arbitrary/resources/search?service=DOCUMENT&identifier=ui_schema_feed&prefix=true`; - const res = await fetch(url); - const data = await res.json(); + this.isLoadingSchemas = true + const url = `${this.nodeUrl}/arbitrary/resources/search?service=DOCUMENT&identifier=ui_schema_feed&prefix=true` + const res = await fetch(url) + const data = await res.json() + if (data.error === 401) { - this.availableFeeedSchemas = []; + this.availableFeeedSchemas = [] } else { - this.availableFeeedSchemas = data.filter( - (item) => item.identifier === 'ui_schema_feed' - ); + this.availableFeeedSchemas = data.filter((item) => item.identifier === 'ui_schema_feed') } - this.userFoundModalOpen = true; - } catch (error) {} finally { - this.isLoadingSchemas= false + + this.userFoundModalOpen = true + } catch (error) { + } finally { + this.isLoadingSchemas = false } } - render() { - return html` - - `; + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } } -customElements.define('add-friends-modal', AddFriendsModal); +window.customElements.define('add-friends-modal', AddFriendsModal) \ No newline at end of file diff --git a/core/src/components/friends-view/avatar.js b/core/src/components/friends-view/avatar.js index e0714032..f00a9904 100644 --- a/core/src/components/friends-view/avatar.js +++ b/core/src/components/friends-view/avatar.js @@ -1,16 +1,17 @@ -import {css, html, LitElement} from 'lit'; -import axios from 'axios'; -import '@material/mwc-menu'; -import '@material/mwc-list/mwc-list-item.js'; -import {RequestQueueWithPromise} from '../../../../plugins/plugins/utils/queue'; -import '../../../../plugins/plugins/core/components/TimeAgo'; -import {connect} from 'pwa-helpers'; -import {store} from '../../store'; -import ShortUniqueId from 'short-unique-id'; +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { RequestQueueWithPromise } from '../../../../plugins/plugins/utils/classes' +import { avatarComponentStyles } from '../../styles/core-css' +import axios from 'axios' +import ShortUniqueId from 'short-unique-id' +import '../../../../plugins/plugins/core/components/TimeAgo' +import '@material/mwc-menu' +import '@material/mwc-list/mwc-list-item.js' -const requestQueue = new RequestQueueWithPromise(3); -const requestQueueRawData = new RequestQueueWithPromise(3); -const requestQueueStatus = new RequestQueueWithPromise(3); +const requestQueue = new RequestQueueWithPromise(3) +const requestQueueRawData = new RequestQueueWithPromise(3) +const requestQueueStatus = new RequestQueueWithPromise(3) export class AvatarComponent extends connect(store)(LitElement) { static get properties() { @@ -18,284 +19,210 @@ export class AvatarComponent extends connect(store)(LitElement) { resource: { type: Object }, isReady: { type: Boolean }, status: { type: Object }, - name: { type: String }, - }; + name: { type: String } + } } static get styles() { - return css` - * { - --mdc-theme-text-primary-on-background: var(--black); - box-sizing: border-box; - } - :host { - width: 100%; - box-sizing: border-box; - } - img { - width: 100%; - max-height: 30vh; - border-radius: 5px; - cursor: pointer; - position: relative; - } - .smallLoading, - .smallLoading:after { - border-radius: 50%; - width: 2px; - height: 2px; - } - - .defaultSize { - width: 100%; - height: 160px; - } - .parent-feed-item { - position: relative; - display: flex; - background-color: var(--chat-bubble-bg); - flex-grow: 0; - flex-direction: column; - align-items: flex-start; - justify-content: center; - border-radius: 5px; - padding: 12px 15px 4px 15px; - min-width: 150px; - width: 100%; - box-sizing: border-box; - cursor: pointer; - font-size: 16px; - } - .avatar { - width: 36px; - height: 36px; - border-radius: 50%; - overflow: hidden; - display: flex; - align-items: center; - } - .avatarApp { - width: 30px; - height: 30px; - border-radius: 50%; - overflow: hidden; - display: flex; - align-items: center; - } - .feed-item-name { - user-select: none; - color: #03a9f4; - margin-bottom: 5px; - } - - .app-name { - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; - } - - mwc-menu { - position: absolute; - } - `; + return [avatarComponentStyles] } constructor() { - super(); + super() this.resource = { identifier: '', name: '', - service: '', - }; + service: '' + } this.status = { - status: '', - }; - this.isReady = false; - this.nodeUrl = this.getNodeUrl(); - this.myNode = this.getMyNode(); - this.isFetching = false; - this.uid = new ShortUniqueId(); - } - getNodeUrl() { - const myNode = - window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ]; - - return myNode.protocol + '://' + myNode.domain + ':' + myNode.port; - } - getMyNode() { - return window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ]; - } - - getApiKey() { - const myNode = - window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ]; - return myNode.apiKey; - } - - async fetchResource() { - try { - if (this.isFetching) return; - this.isFetching = true; - await axios.get( - `${this.nodeUrl}/arbitrary/resource/properties/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}` - ); - this.isFetching = false; - } catch (error) { - this.isFetching = false; + status: '' } - } - - async fetchVideoUrl() { - await this.fetchResource(); - } - - async getRawData() { - const url = `${this.nodeUrl}/arbitrary/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`; - return await requestQueueRawData.enqueue(() => { - return axios.get(url); - }); - // const response2 = await fetch(url, { - // method: 'GET', - // headers: { - // 'Content-Type': 'application/json' - // } - // }) - - // const responseData2 = await response2.json() - // return responseData2 - } - - updateDisplayWithPlaceholders(display, resource, rawdata) { - const pattern = /\$\$\{([a-zA-Z0-9_\.]+)\}\$\$/g; - - for (const key in display) { - const value = display[key]; - - display[key] = value.replace(pattern, (match, p1) => { - if (p1.startsWith('rawdata.')) { - const dataKey = p1.split('.')[1]; - if (rawdata[dataKey] === undefined) { - console.error('rawdata key not found:', dataKey); - } - return rawdata[dataKey] || match; - } else if (p1.startsWith('resource.')) { - const resourceKey = p1.split('.')[1]; - if (resource[resourceKey] === undefined) { - console.error('resource key not found:', resourceKey); - } - return resource[resourceKey] || match; - } - return match; - }); - } - } - - async fetchStatus() { - let isCalling = false; - let percentLoaded = 0; - let timer = 24; - const response = await requestQueueStatus.enqueue(() => { - return axios.get( - `${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}` - ); - }); - if (response && response.data && response.data.status === 'READY') { - this.status = response.data; - - return; - } - const intervalId = setInterval(async () => { - if (isCalling) return; - isCalling = true; - - const data = await requestQueue.enqueue(() => { - return axios.get( - `${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}` - ); - }); - const res = data.data; - - isCalling = false; - if (res.localChunkCount) { - if (res.percentLoaded) { - if ( - res.percentLoaded === percentLoaded && - res.percentLoaded !== 100 - ) { - timer = timer - 5; - } else { - timer = 24; - } - if (timer < 0) { - clearInterval(intervalId); - } - percentLoaded = res.percentLoaded; - } - - this.status = res; - if (this.status.status === 'DOWNLOADED') { - await this.fetchResource(); - } - } - - // check if progress is 100% and clear interval if true - if (res.status === 'READY') { - clearInterval(intervalId); - this.status = res; - this.isReady = true; - } - }, 5000); // 1 second interval - } - - async _fetchImage() { - try { - await this.fetchVideoUrl(); - await this.fetchStatus(); - } catch (error) { - /* empty */ - } - } - - firstUpdated() { - this._fetchImage(); + this.isReady = false + this.nodeUrl = this.getNodeUrl() + this.myNode = this.getMyNode() + this.isFetching = false + this.uid = new ShortUniqueId() } render() { return html`
    - ${this.status.status !== 'READY' - ? html` - account_circle - ` - : ''} - ${this.status.status === 'READY' - ? html` -
    - -
    - ` - : ''} + ${this.status.status !== 'READY' ? + html` + account_circle + ` : '' + } + ${this.status.status === 'READY' ? + html` +
    + +
    + ` : '' + }
    - `; + ` + } + + firstUpdated() { + this._fetchImage() + } + + getNodeUrl() { + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return myNode.protocol + '://' + myNode.domain + ':' + myNode.port + } + + getMyNode() { + return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + } + + async fetchResource() { + try { + if (this.isFetching) return + + this.isFetching = true + + await axios.get( + `${this.nodeUrl}/arbitrary/resource/properties/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}` + ) + + this.isFetching = false + } catch (error) { + this.isFetching = false + } + } + + async fetchVideoUrl() { + await this.fetchResource() + } + + async getRawData() { + const url = `${this.nodeUrl}/arbitrary/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}` + + return await requestQueueRawData.enqueue(() => { + return axios.get(url) + }) + } + + updateDisplayWithPlaceholders(display, resource, rawdata) { + const pattern = /\$\$\{([a-zA-Z0-9_\.]+)\}\$\$/g + + for (const key in display) { + const value = display[key] + + display[key] = value.replace(pattern, (match, p1) => { + if (p1.startsWith('rawdata.')) { + const dataKey = p1.split('.')[1] + + if (rawdata[dataKey] === undefined) { + console.error('rawdata key not found:', dataKey) + } + + return rawdata[dataKey] || match + } else if (p1.startsWith('resource.')) { + const resourceKey = p1.split('.')[1] + + if (resource[resourceKey] === undefined) { + console.error('resource key not found:', resourceKey) + } + + return resource[resourceKey] || match + } + + return match + }) + } + } + + async fetchStatus() { + let isCalling = false + let percentLoaded = 0 + let timer = 24 + + const response = await requestQueueStatus.enqueue(() => { + return axios.get( + `${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}` + ) + }) + + if (response && response.data && response.data.status === 'READY') { + this.status = response.data + return + } + + const intervalId = setInterval(async () => { + if (isCalling) return + + isCalling = true + + const data = await requestQueue.enqueue(() => { + return axios.get( + `${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}` + ) + }) + + const res = data.data + + isCalling = false + + if (res.localChunkCount) { + if (res.percentLoaded) { + if (res.percentLoaded === percentLoaded && res.percentLoaded !== 100) { + timer = timer - 5 + } else { + timer = 24 + } + + if (timer < 0) { + clearInterval(intervalId) + } + + percentLoaded = res.percentLoaded + } + + this.status = res + + if (this.status.status === 'DOWNLOADED') { + await this.fetchResource() + } + } + + // check if progress is 100% and clear interval if true + if (res.status === 'READY') { + clearInterval(intervalId) + this.status = res + this.isReady = true + } + }, 5000) // 5 second interval + } + + async _fetchImage() { + try { + await this.fetchVideoUrl() + await this.fetchStatus() + } catch (error) { + /* empty */ + } + } + + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } } -customElements.define('avatar-component', AvatarComponent); +window.customElements.define('avatar-component', AvatarComponent) \ No newline at end of file diff --git a/core/src/components/friends-view/beginner-checklist.js b/core/src/components/friends-view/beginner-checklist.js index 4a688aed..8ef4bd6c 100644 --- a/core/src/components/friends-view/beginner-checklist.js +++ b/core/src/components/friends-view/beginner-checklist.js @@ -1,344 +1,214 @@ -import {css, html, LitElement} from 'lit'; -import {connect} from 'pwa-helpers'; - -import '@vaadin/item'; -import '@vaadin/list-box'; -import '@polymer/paper-icon-button/paper-icon-button.js'; -import '@polymer/iron-icons/iron-icons.js'; -import {store} from '../../store.js'; -import {setNewTab} from '../../redux/app/app-actions.js'; -import '@material/mwc-icon'; -import {get} from '../../../translate'; -import '../../../../plugins/plugins/core/components/TimeAgo.js'; -import '../notification-view/popover.js'; -import ShortUniqueId from 'short-unique-id'; +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { setNewTab } from '../../redux/app/app-actions' +import { get } from '../../../translate' +import { beginnerChecklistStyles } from '../../styles/core-css' +import ShortUniqueId from 'short-unique-id' +import '../notification-view/popover' +import '../../../../plugins/plugins/core/components/TimeAgo' +import '@material/mwc-icon' +import '@polymer/paper-icon-button/paper-icon-button.js' +import '@polymer/iron-icons/iron-icons.js' +import '@vaadin/item' +import '@vaadin/list-box' class BeginnerChecklist extends connect(store)(LitElement) { - static properties = { - notifications: { type: Array }, - showChecklist: { type: Boolean }, - theme: { type: String, reflect: true }, - isSynced: { type: Boolean }, - hasName: { type: Boolean }, - hasTourFinished: { type: Boolean }, - }; - - constructor() { - super(); - this.showChecklist = false; - this.initialFetch = false; - this.theme = localStorage.getItem('qortalTheme') - ? localStorage.getItem('qortalTheme') - : 'light'; - this.isSynced = false; - this.hasName = null; - this.nodeUrl = this.getNodeUrl(); - this.myNode = this.getMyNode(); - this.hasTourFinished = null; - this._controlTourFinished = this._controlTourFinished.bind(this); - this.uid = new ShortUniqueId(); + static get properties() { + return { + notifications: { type: Array }, + showChecklist: { type: Boolean }, + isSynced: { type: Boolean }, + hasName: { type: Boolean }, + hasTourFinished: { type: Boolean }, + theme: { type: String, reflect: true } + } } - _controlTourFinished() { - this.hasTourFinished = true; + static get styles() { + return [beginnerChecklistStyles] + } + + constructor() { + super() + this.showChecklist = false + this.initialFetch = false + this.isSynced = false + this.hasName = null + this.nodeUrl = this.getNodeUrl() + this.myNode = this.getMyNode() + this.hasTourFinished = null + this._controlTourFinished = this._controlTourFinished.bind(this) + this.uid = new ShortUniqueId() + this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' + } + + render() { + return this.hasName === false || this.hasTourFinished === false ? + html` +
    + +
    this._toggleChecklist()}> + + checklist + + +
    +
    +
    +
    +

    Are you synced?

    + ${this.syncPercentage === 100 ? + html` + + task_alt + + ` + : html` + + radio_button_unchecked + + ` + } +
    +
    { + store.dispatch( + setNewTab({ + url: `group-management`, + id: this.uid.rnd(), + myPlugObj: { + url: 'name-registration', + domain: 'core', + page: 'name-registration/index.html', + title: 'Name Registration', + icon: 'vaadin:user-check', + mwcicon: 'manage_accounts', + pluginNumber: 'plugin-qCmtXAQmtu', + menus: [], + parent: false + }, + openExisting: true + }) + ); + this.handleBlur(); + }} + > +

    Do you have a name registered?

    + ${this.hasName ? + html` + + task_alt + + ` : html` + + radio_button_unchecked + + ` + } +
    +
    +
    +
    + ` + : '' } firstUpdated() { - this.address = store.getState().app.selectedAddress.address; - this.hasTourFinished = JSON.parse( - localStorage.getItem(`hasViewedTour-${this.address}`) || 'null' - ); + this.address = store.getState().app.selectedAddress.address + this.hasTourFinished = JSON.parse(localStorage.getItem(`hasViewedTour-${this.address}`) || 'null') + } + + _controlTourFinished() { + this.hasTourFinished = true } connectedCallback() { - super.connectedCallback(); - window.addEventListener( - 'send-tour-finished', - this._controlTourFinished - ); + super.connectedCallback() + window.addEventListener('send-tour-finished', this._controlTourFinished) } disconnectedCallback() { - window.removeEventListener( - 'send-tour-finished', - this._controlTourFinished - ); - - super.disconnectedCallback(); + window.removeEventListener('send-tour-finished', this._controlTourFinished) + super.disconnectedCallback() } getNodeUrl() { - const myNode = - window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ]; - - return myNode.protocol + '://' + myNode.domain + ':' + myNode.port; + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return myNode.protocol + '://' + myNode.domain + ':' + myNode.port } + getMyNode() { - return window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ]; + return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] } async getName(recipient) { try { - if (!recipient) return ''; - const endpoint = `${this.nodeUrl}/names/address/${recipient}`; - const res = await fetch(endpoint); - const getNames = await res.json(); + if (!recipient) return '' - this.hasName = Array.isArray(getNames) && getNames.length > 0; + const endpoint = `${this.nodeUrl}/names/address/${recipient}` + const res = await fetch(endpoint) + const getNames = await res.json() + + this.hasName = Array.isArray(getNames) && getNames.length > 0 } catch (error) { - return ''; + return '' } } stateChanged(state) { - if ( - state.app.nodeStatus && - state.app.nodeStatus.syncPercent !== this.syncPercentage - ) { - this.syncPercentage = state.app.nodeStatus.syncPercent; + if (state.app.nodeStatus && state.app.nodeStatus.syncPercent !== this.syncPercentage) { + this.syncPercentage = state.app.nodeStatus.syncPercent - if ( - !this.hasAttempted && - state.app.selectedAddress && - state.app.nodeStatus.syncPercent === 100 - ) { - this.hasAttempted = true; - this.getName(state.app.selectedAddress.address); + if (!this.hasAttempted && state.app.selectedAddress && state.app.nodeStatus.syncPercent === 100) { + this.hasAttempted = true + this.getName(state.app.selectedAddress.address) } } - if ( - state.app.accountInfo && - state.app.accountInfo.names.length && - state.app.nodeStatus && - state.app.nodeStatus.syncPercent === 100 && - this.hasName === false && - this.hasAttempted && - state.app.accountInfo && - state.app.accountInfo.names && + + if (state.app.accountInfo && + state.app.accountInfo.names.length && state.app.nodeStatus && state.app.nodeStatus.syncPercent === 100 && + this.hasName === false && this.hasAttempted && state.app.accountInfo && state.app.accountInfo.names && state.app.accountInfo.names.length > 0 ) { - this.hasName = true; + this.hasName = true } } handleBlur() { setTimeout(() => { if (!this.shadowRoot.contains(document.activeElement)) { - this.showChecklist = false; + this.showChecklist = false } - }, 0); - } - - render() { - return this.hasName === false || this.hasTourFinished === false - ? html` -
    - -
    this._toggleChecklist()} - > - checklist - - -
    - -
    -
    -
    -

    Are you synced?

    - ${this.syncPercentage === 100 - ? html` - task_alt - ` - : html` - radio_button_unchecked - `} -
    - -
    { - store.dispatch( - setNewTab({ - url: `group-management`, - id: this.uid.rnd(), - myPlugObj: { - url: 'name-registration', - domain: 'core', - page: 'name-registration/index.html', - title: 'Name Registration', - icon: 'vaadin:user-check', - mwcicon: 'manage_accounts', - pluginNumber: - 'plugin-qCmtXAQmtu', - menus: [], - parent: false, - }, - openExisting: true, - }) - ); - this.handleBlur(); - }} - > -

    Do you have a name registered?

    - ${this.hasName - ? html` - task_alt - ` - : html` - radio_button_unchecked - `} -
    -
    -
    -
    - ` - : ''; + }, 0) } _toggleChecklist() { - this.showChecklist = !this.showChecklist; + this.showChecklist = !this.showChecklist + if (this.showChecklist) { requestAnimationFrame(() => { - this.shadowRoot.getElementById('checklist-panel').focus(); - }); + this.shadowRoot.getElementById('checklist-panel').focus() + }) } } - static styles = css` - .layout { - display: flex; - flex-direction: column; - align-items: center; - position: relative; - } + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } - .count { - position: absolute; - top: -5px; - right: -5px; - font-size: 12px; - background-color: red; - color: white; - border-radius: 50%; - width: 16px; - height: 16px; - display: flex; - align-items: center; - justify-content: center; - } + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } - .nocount { - display: none; - } - - .popover-panel { - position: absolute; - width: 200px; - padding: 10px; - background-color: var(--white); - border: 1px solid var(--black); - border-radius: 4px; - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); - top: 40px; - max-height: 350px; - overflow: auto; - scrollbar-width: thin; - scrollbar-color: #6a6c75 #a1a1a1; - } - - .popover-panel::-webkit-scrollbar { - width: 11px; - } - - .popover-panel::-webkit-scrollbar-track { - background: #a1a1a1; - } - - .popover-panel::-webkit-scrollbar-thumb { - background-color: #6a6c75; - border-radius: 6px; - border: 3px solid #a1a1a1; - } - - .list { - display: flex; - flex-direction: column; - gap: 15px; - } - - .task-list-item { - display: flex; - gap: 15px; - justify-content: space-between; - align-items: center; - } - - .checklist-item { - padding: 5px; - border-bottom: 1px solid; - display: flex; - justify-content: space-between; - cursor: pointer; - transition: 0.2s all; - } - - .checklist-item:hover { - background: var(--nav-color-hover); - } - - p { - font-size: 16px; - color: var(--black); - margin: 0px; - padding: 0px; - } - `; + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } -customElements.define('beginner-checklist', BeginnerChecklist); +window.customElements.define('beginner-checklist', BeginnerChecklist) \ No newline at end of file diff --git a/core/src/components/friends-view/computePowWorkerFile.src.js b/core/src/components/friends-view/computePowWorkerFile.src.js index b8bd962d..eb4cb775 100644 --- a/core/src/components/friends-view/computePowWorkerFile.src.js +++ b/core/src/components/friends-view/computePowWorkerFile.src.js @@ -1,91 +1,67 @@ -import {Sha256} from 'asmcrypto.js' +import { Sha256 } from 'asmcrypto.js' - -function sbrk(size, heap){ - let brk = 512 * 1024 // stack top - let old = brk - brk += size - - if (brk > heap.length) - throw new Error('heap exhausted') - - return old +function sbrk(size, heap) { + let brk = 512 * 1024 // stack top + let old = brk + brk += size + if (brk > heap.length) throw new Error('heap exhausted') + return old } - - - self.addEventListener('message', async e => { - const response = await computePow(e.data.convertedBytes, e.data.path) - postMessage(response) - + const response = await computePow(e.data.convertedBytes, e.data.path) + postMessage(response) }) - const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 }) const heap = new Uint8Array(memory.buffer) - - const computePow = async (convertedBytes, path) => { + let response = null + await new Promise((resolve, reject) => { + const _convertedBytesArray = Object.keys(convertedBytes).map( + function (key) { + return convertedBytes[key] + } + ) + const convertedBytesArray = new Uint8Array(_convertedBytesArray) + const convertedBytesHash = new Sha256() + .process(convertedBytesArray) + .finish().result + const hashPtr = sbrk(32, heap) + const hashAry = new Uint8Array( + memory.buffer, + hashPtr, + 32 + ) + hashAry.set(convertedBytesHash) + const difficulty = 14 + const workBufferLength = 8 * 1024 * 1024 + const workBufferPtr = sbrk( + workBufferLength, + heap + ) + const importObject = { + env: { + memory: memory + } + } + function loadWebAssembly(filename, imports) { + return fetch(filename) + .then(response => response.arrayBuffer()) + .then(buffer => WebAssembly.compile(buffer)) + .then(module => { + return new WebAssembly.Instance(module, importObject) + }) + } + loadWebAssembly(path) + .then(wasmModule => { + response = { + nonce: wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty), - - let response = null - - await new Promise((resolve, reject)=> { - - const _convertedBytesArray = Object.keys(convertedBytes).map( - function (key) { - return convertedBytes[key] - } -) -const convertedBytesArray = new Uint8Array(_convertedBytesArray) -const convertedBytesHash = new Sha256() - .process(convertedBytesArray) - .finish().result -const hashPtr = sbrk(32, heap) -const hashAry = new Uint8Array( - memory.buffer, - hashPtr, - 32 -) - -hashAry.set(convertedBytesHash) -const difficulty = 14 -const workBufferLength = 8 * 1024 * 1024 -const workBufferPtr = sbrk( - workBufferLength, - heap -) - - const importObject = { - env: { - memory: memory - }, - }; - - function loadWebAssembly(filename, imports) { - return fetch(filename) - .then(response => response.arrayBuffer()) - .then(buffer => WebAssembly.compile(buffer)) - .then(module => { - return new WebAssembly.Instance(module, importObject); - }); -} - - -loadWebAssembly(path) - .then(wasmModule => { - response = { - nonce : wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty), - - } - resolve() - - }); - - - }) - - return response -} + } + resolve() + }) + }) + return response +} \ No newline at end of file diff --git a/core/src/components/friends-view/core-sync-status.js b/core/src/components/friends-view/core-sync-status.js index a4345671..8c695b4d 100644 --- a/core/src/components/friends-view/core-sync-status.js +++ b/core/src/components/friends-view/core-sync-status.js @@ -1,7 +1,8 @@ -import {css, html, LitElement} from 'lit' -import {store} from '../../store' -import {connect} from 'pwa-helpers' -import {translate} from '../../../translate' +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { translate } from '../../../translate' +import { coreSyncStatusStyles } from '../../styles/core-css' class CoreSyncStatus extends connect(store)(LitElement) { static get properties() { @@ -12,6 +13,10 @@ class CoreSyncStatus extends connect(store)(LitElement) { } } + static get styles() { + return [coreSyncStatusStyles] + } + constructor() { super() this.nodeInfos = [] @@ -19,69 +24,6 @@ class CoreSyncStatus extends connect(store)(LitElement) { this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' } - static get styles() { - return css` - .lineHeight { - line-height: 33%; - } - - .tooltip { - display: inline-block; - position: relative; - text-align: left; - } - - .tooltip .bottom { - min-width: 200px; - max-width: 250px; - top: 35px; - left: 50%; - transform: translate(-50%, 0); - padding: 10px 10px; - color: var(--black); - background-color: var(--white); - font-weight: normal; - font-size: 13px; - border-radius: 8px; - position: absolute; - z-index: 99999999; - box-sizing: border-box; - box-shadow: 0 1px 8px rgba(0,0,0,0.5); - border: 1px solid var(--black); - visibility: hidden; - opacity: 0; - transition: opacity 0.8s; - } - - .tooltip:hover .bottom { - visibility: visible; - opacity: 1; - } - - .tooltip .bottom i { - position: absolute; - bottom: 100%; - left: 50%; - margin-left: -12px; - width: 24px; - height: 12px; - overflow: hidden; - } - - .tooltip .bottom i::after { - content: ''; - position: absolute; - width: 12px; - height: 12px; - left: 50%; - transform: translate(-50%,50%) rotate(45deg); - background-color: var(--white); - border: 1px solid var(--black); - box-shadow: 0 1px 8px rgba(0,0,0,0.5); - } - ` - } - render() { return html`
    @@ -136,7 +78,7 @@ class CoreSyncStatus extends connect(store)(LitElement) {

    ${translate("walletprofile.wp3")}

    -

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}

    +

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0, 12) : ''}

    ${translate("appinfo.synchronizing")}... ${this.nodeInfos.syncPercent !== undefined ? this.nodeInfos.syncPercent + '%' : ''}

    ${translate("appinfo.blockheight")}: ${this.nodeInfos.height ? this.nodeInfos.height : ''}

    ${translate("appinfo.peers")}: ${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}

    @@ -150,7 +92,7 @@ class CoreSyncStatus extends connect(store)(LitElement) {

    ${translate("walletprofile.wp3")}

    -

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}

    +

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0, 12) : ''}

    ${translate("walletprofile.wp4")} ${translate("walletprofile.wp2")}

    ${translate("appinfo.blockheight")}: ${this.nodeInfos.height ? this.nodeInfos.height : ''}

    ${translate("appinfo.peers")}: ${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}

    @@ -164,7 +106,7 @@ class CoreSyncStatus extends connect(store)(LitElement) {

    ${translate("walletprofile.wp3")}

    -

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}

    +

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0, 12) : ''}

    ${translate("walletprofile.wp4")} ${translate("walletprofile.wp2")}

    ${translate("appinfo.blockheight")}: ${this.nodeInfos.height ? this.nodeInfos.height : ''}

    ${translate("appinfo.peers")}: ${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}

    @@ -178,7 +120,7 @@ class CoreSyncStatus extends connect(store)(LitElement) {

    ${translate("walletprofile.wp3")}

    -

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}

    +

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0, 12) : ''}

    ${translate("walletprofile.wp4")} ( ${translate("walletprofile.wp1")} )

    ${translate("appinfo.blockheight")}: ${this.nodeInfos.height ? this.nodeInfos.height : ''}

    ${translate("appinfo.peers")}: ${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}

    @@ -192,7 +134,7 @@ class CoreSyncStatus extends connect(store)(LitElement) {

    ${translate("walletprofile.wp3")}

    -

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}

    +

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0, 12) : ''}

    ${translate("walletprofile.wp4")} ( ${translate("walletprofile.wp1")} )

    ${translate("appinfo.blockheight")}: ${this.nodeInfos.height ? this.nodeInfos.height : ''}

    ${translate("appinfo.peers")}: ${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}

    @@ -206,7 +148,7 @@ class CoreSyncStatus extends connect(store)(LitElement) {

    ${translate("walletprofile.wp3")}

    -

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}

    +

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0, 12) : ''}

    ${translate("appinfo.synchronizing")}... ${this.nodeInfos.syncPercent !== undefined ? this.nodeInfos.syncPercent + '%' : ''}

    ${translate("appinfo.blockheight")}: ${this.nodeInfos.height ? this.nodeInfos.height : ''}

    ${translate("appinfo.peers")}: ${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}

    @@ -221,6 +163,20 @@ class CoreSyncStatus extends connect(store)(LitElement) { // ... } + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } -customElements.define('core-sync-status', CoreSyncStatus) \ No newline at end of file +window.customElements.define('core-sync-status', CoreSyncStatus) \ No newline at end of file diff --git a/core/src/components/friends-view/feed-item.js b/core/src/components/friends-view/feed-item.js index 2410c5ff..07e11d64 100644 --- a/core/src/components/friends-view/feed-item.js +++ b/core/src/components/friends-view/feed-item.js @@ -1,366 +1,282 @@ -import {css, html, LitElement} from 'lit'; -import {translate,} from '../../../translate' +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { setNewTab } from '../../redux/app/app-actions' +import { RequestQueueWithPromise } from '../../../../plugins/plugins/utils/classes' +import { translate, } from '../../../translate' +import { feedItemStyles } from '../../styles/core-css' import axios from 'axios' -import '@material/mwc-menu'; -import '@material/mwc-list/mwc-list-item.js' -import {RequestQueueWithPromise} from '../../../../plugins/plugins/utils/queue'; +import ShortUniqueId from 'short-unique-id' import '../../../../plugins/plugins/core/components/TimeAgo' -import {connect} from 'pwa-helpers'; -import {store} from '../../store'; -import {setNewTab} from '../../redux/app/app-actions'; -import ShortUniqueId from 'short-unique-id'; - -const requestQueue = new RequestQueueWithPromise(3); -const requestQueueRawData = new RequestQueueWithPromise(3); -const requestQueueStatus = new RequestQueueWithPromise(3); +import '@material/mwc-menu' +import '@material/mwc-list/mwc-list-item.js' +const requestQueue = new RequestQueueWithPromise(3) +const requestQueueRawData = new RequestQueueWithPromise(3) +const requestQueueStatus = new RequestQueueWithPromise(3) export class FeedItem extends connect(store)(LitElement) { - static get properties() { - return { - resource: { type: Object }, - isReady: { type: Boolean}, - status: {type: Object}, - feedItem: {type: Object}, - appName: {type: String}, - link: {type: String} - }; - } - - static get styles() { - return css` - * { - --mdc-theme-text-primary-on-background: var(--black); - box-sizing: border-box; - } - :host { - width: 100%; - box-sizing: border-box; - } - img { - width:100%; - max-height:30vh; - border-radius: 5px; - cursor: pointer; - position: relative; - } - .smallLoading, - .smallLoading:after { - border-radius: 50%; - width: 2px; - height: 2px; - } - - .smallLoading { - border-width: 0.8em; - border-style: solid; - border-color: rgba(3, 169, 244, 0.2) rgba(3, 169, 244, 0.2) - rgba(3, 169, 244, 0.2) rgb(3, 169, 244); - font-size: 30px; - position: relative; - text-indent: -9999em; - transform: translateZ(0px); - animation: 1.1s linear 0s infinite normal none running loadingAnimation; - } - - .defaultSize { - width: 100%; - height: 160px; - } - .parent-feed-item { - position: relative; - display: flex; - background-color: var(--chat-bubble-bg); - flex-grow: 0; - flex-direction: column; - align-items: flex-start; - justify-content: center; - border-radius: 5px; - padding: 12px 15px 4px 15px; - min-width: 150px; - width: 100%; - box-sizing: border-box; - cursor: pointer; - font-size: 16px; - } - .avatar { - width: 36px; - height: 36px; - border-radius:50%; - overflow: hidden; - display:flex; - align-items:center; - } - .avatarApp { - width: 30px; - height: 30px; - border-radius:50%; - overflow: hidden; - display:flex; - align-items:center; - } - .feed-item-name { - user-select: none; - color: #03a9f4; - margin-bottom: 5px; + static get properties() { + return { + resource: { type: Object }, + isReady: { type: Boolean }, + status: { type: Object }, + feedItem: { type: Object }, + appName: { type: String }, + link: { type: String } + } } - .app-name { - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; - } + static get styles() { + return [feedItemStyles] + } - mwc-menu { - position: absolute; - } + constructor() { + super() + this.resource = { + identifier: "", + name: "", + service: "" + } + this.status = { + status: '' + } + this.isReady = false + this.nodeUrl = this.getNodeUrl() + this.myNode = this.getMyNode() + this.hasCalledWhenDownloaded = false + this.isFetching = false + this.uid = new ShortUniqueId() + this.observer = new IntersectionObserver(entries => { + for (const entry of entries) { + if (entry.isIntersecting && this.status.status !== 'READY') { + this._fetchImage() + // Stop observing after the image has started loading + this.observer.unobserve(this) + } + } + }) + this.feedItem = null + } + render() { + let avatarImg + const avatarUrl = `${this.nodeUrl}/arbitrary/THUMBNAIL/${this.resource.name}/qortal_avatar?async=true` + avatarImg = html`` + let avatarImgApp + const avatarUrl2 = `${this.nodeUrl}/arbitrary/THUMBNAIL/${this.appName}/qortal_avatar?async=true` + avatarImgApp = html`` + return html` +
    + ${this.status.status !== 'READY' ? + html` +
    +
    +

    + ${`${Math.round(this.status.percentLoaded || 0).toFixed(0)}% `}${translate('chatpage.cchange94')} +

    +
    + ` + : '' + } + ${this.status.status === 'READY' && this.feedItem ? + html` +
    +
    +
    ${avatarImg}
    + ${this.resource.name} +
    +
    +

    ${this.feedItem.title}

    +
    +
    +
    ${avatarImgApp}
    + +
    +
    + ` + : '' + } +
    + ` + } - @-webkit-keyframes loadingAnimation { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } - } + firstUpdated() { + this.observer.observe(this) + } - @keyframes loadingAnimation { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } - } - `; - } + getNodeUrl() { + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return myNode.protocol + '://' + myNode.domain + ':' + myNode.port + } - constructor() { - super(); - this.resource = { - identifier: "", - name: "", - service: "" - } - this.status = { - status: '' - } - this.isReady = false - this.nodeUrl = this.getNodeUrl() - this.myNode = this.getMyNode() - this.hasCalledWhenDownloaded = false - this.isFetching = false - this.uid = new ShortUniqueId() + getMyNode() { + return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + } - this.observer = new IntersectionObserver(entries => { - for (const entry of entries) { - if (entry.isIntersecting && this.status.status !== 'READY') { - this._fetchImage(); - // Stop observing after the image has started loading - this.observer.unobserve(this); - } - } - }); - this.feedItem = null - } - getNodeUrl(){ - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + async fetchResource() { + try { + if (this.isFetching) return + this.isFetching = true + await axios.get(`${this.nodeUrl}/arbitrary/resource/properties/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`) + this.isFetching = false - return myNode.protocol + '://' + myNode.domain + ':' + myNode.port -} -getMyNode(){ - return window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] -} + } catch (error) { + this.isFetching = false + } + } - getApiKey() { - const myNode = - window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ]; - return myNode.apiKey; - } + async fetchVideoUrl() { + await this.fetchResource() + } - async fetchResource() { - try { - if(this.isFetching) return - this.isFetching = true - await axios.get(`${this.nodeUrl}/arbitrary/resource/properties/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`) - this.isFetching = false + async getRawData() { + const url = `${this.nodeUrl}/arbitrary/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}` - } catch (error) { - this.isFetching = false - } - } + return await requestQueueRawData.enqueue(() => { + return axios.get(url) + }) + } - async fetchVideoUrl() { + updateDisplayWithPlaceholders(display, resource, rawdata) { + const pattern = /\$\$\{([a-zA-Z0-9_\.]+)\}\$\$/g - await this.fetchResource() + for (const key in display) { + const value = display[key] - } + display[key] = value.replace(pattern, (match, p1) => { + if (p1.startsWith('rawdata.')) { + const dataKey = p1.split('.')[1] + if (rawdata[dataKey] === undefined) { + console.error("rawdata key not found:", dataKey) + } + return rawdata[dataKey] || match + } else if (p1.startsWith('resource.')) { + const resourceKey = p1.split('.')[1] + if (resource[resourceKey] === undefined) { + console.error("resource key not found:", resourceKey) + } + return resource[resourceKey] || match + } + return match + }) + } + } - async getRawData(){ - const url = `${this.nodeUrl}/arbitrary/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}` - return await requestQueueRawData.enqueue(()=> { - return axios.get(url) - }) - // const response2 = await fetch(url, { - // method: 'GET', - // headers: { - // 'Content-Type': 'application/json' - // } - // }) + async fetchStatus() { + let isCalling = false + let percentLoaded = 0 + let timer = 24 - // const responseData2 = await response2.json() - // return responseData2 - } + const response = await requestQueueStatus.enqueue(() => { + return axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`) + }) - updateDisplayWithPlaceholders(display, resource, rawdata) { - const pattern = /\$\$\{([a-zA-Z0-9_\.]+)\}\$\$/g; + if (response && response.data && response.data.status === 'READY') { + const rawData = await this.getRawData() - for (const key in display) { - const value = display[key]; + const object = { + ...this.resource.schema.display + } - display[key] = value.replace(pattern, (match, p1) => { - if (p1.startsWith('rawdata.')) { - const dataKey = p1.split('.')[1]; - if (rawdata[dataKey] === undefined) { - console.error("rawdata key not found:", dataKey); - } - return rawdata[dataKey] || match; - } else if (p1.startsWith('resource.')) { - const resourceKey = p1.split('.')[1]; - if (resource[resourceKey] === undefined) { - console.error("resource key not found:", resourceKey); - } - return resource[resourceKey] || match; - } - return match; - }); - } -} + this.updateDisplayWithPlaceholders(object, {}, rawData.data) + this.feedItem = object + this.status = response.data + return + } + const intervalId = setInterval(async () => { + if (isCalling) return + isCalling = true + const data = await requestQueue.enqueue(() => { + return axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`) + }) - async fetchStatus(){ - let isCalling = false - let percentLoaded = 0 - let timer = 24 - const response = await requestQueueStatus.enqueue(()=> { - return axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`) - }) - if(response && response.data && response.data.status === 'READY'){ - const rawData = await this.getRawData() - const object = { - ...this.resource.schema.display - } - this.updateDisplayWithPlaceholders(object, {},rawData.data) - this.feedItem = object - this.status = response.data + const res = data.data - return - } - const intervalId = setInterval(async () => { - if (isCalling) return - isCalling = true + isCalling = false + if (res.localChunkCount) { + if (res.percentLoaded) { + if (res.percentLoaded === percentLoaded && res.percentLoaded !== 100) { + timer = timer - 5 + } else { + timer = 24 + } + if (timer < 0) { + timer = 24 + isCalling = true + this.status = { + ...res, + status: 'REFETCHING' + } - const data = await requestQueue.enqueue(() => { - return axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`) - }); - const res = data.data + setTimeout(() => { + isCalling = false + this.fetchResource() + }, 25000) - isCalling = false - if (res.localChunkCount) { - if (res.percentLoaded) { - if ( - res.percentLoaded === percentLoaded && - res.percentLoaded !== 100 - ) { - timer = timer - 5 - } else { - timer = 24 - } - if (timer < 0) { - timer = 24 - isCalling = true - this.status = { - ...res, - status: 'REFETCHING' - } + return + } + percentLoaded = res.percentLoaded + } - setTimeout(() => { - isCalling = false - this.fetchResource() - }, 25000) - return - } - percentLoaded = res.percentLoaded - } + this.status = res - this.status = res - if(this.status.status === 'DOWNLOADED'){ - await this.fetchResource() - } - } + if (this.status.status === 'DOWNLOADED') { + await this.fetchResource() + } + } - // check if progress is 100% and clear interval if true - if (res.status === 'READY') { - const rawData = await this.getRawData() - const object = { - ...this.resource.schema.display - } - this.updateDisplayWithPlaceholders(object, {},rawData.data) - this.feedItem = object - clearInterval(intervalId) - this.status = res - this.isReady = true - } - }, 5000) // 1 second interval - } + // check if progress is 100% and clear interval if true + if (res.status === 'READY') { + const rawData = await this.getRawData() + const object = { + ...this.resource.schema.display + } + this.updateDisplayWithPlaceholders(object, {}, rawData.data) + this.feedItem = object + clearInterval(intervalId) + this.status = res + this.isReady = true + } + }, 5000) // 5 second interval + } - async _fetchImage() { - try { - await this.fetchVideoUrl() - await this.fetchStatus() - } catch (error) { /* empty */ } - } + async _fetchImage() { + try { + await this.fetchVideoUrl() + await this.fetchStatus() + } catch (error) { /* empty */ } + } - firstUpdated(){ - this.observer.observe(this); + async goToFeedLink() { + try { + let newQuery = this.link + if (newQuery.endsWith('/')) { + newQuery = newQuery.slice(0, -1) + } + const res = await this.extractComponents(newQuery) + if (!res) return + const { service, name, identifier, path } = res + let query = `?service=${service}` + if (name) { + query = query + `&name=${name}` + } + if (identifier) { + query = query + `&identifier=${identifier}` + } + if (path) { + query = query + `&path=${path}` + } - } - - - - async goToFeedLink(){ - try { - let newQuery = this.link - if (newQuery.endsWith('/')) { - newQuery = newQuery.slice(0, -1) - } - const res = await this.extractComponents(newQuery) - if (!res) return - const { service, name, identifier, path } = res - let query = `?service=${service}` - if (name) { - query = query + `&name=${name}` - } - if (identifier) { - query = query + `&identifier=${identifier}` - } - if (path) { - query = query + `&path=${path}` - } - - store.dispatch(setNewTab({ + store.dispatch(setNewTab({ url: `qdn/browser/index.html${query}`, id: this.uid.rnd(), myPlugObj: { @@ -373,137 +289,72 @@ getMyNode(){ "menus": [], "parent": false }, - openExisting: true + openExisting: true })) - } catch (error) { - console.log({error}) - } - } + } catch (error) { + console.log({ error }) + } + } + async extractComponents(url) { + if (!url.startsWith("qortal://")) { + return null + } + url = url.replace(/^(qortal\:\/\/)/, "") - async extractComponents(url) { - if (!url.startsWith("qortal://")) { - return null - } + if (url.includes("/")) { + let parts = url.split("/") + const service = parts[0].toUpperCase() + parts.shift() + const name = parts[0] + parts.shift() + let identifier - url = url.replace(/^(qortal\:\/\/)/, "") - if (url.includes("/")) { - let parts = url.split("/") - const service = parts[0].toUpperCase() - parts.shift() - const name = parts[0] - parts.shift() - let identifier + if (parts.length > 0) { + identifier = parts[0] // Do not shift yet + // Check if a resource exists with this service, name and identifier combination + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/arbitrary/resource/status/${service}/${name}/${identifier}?apiKey=${myNode.apiKey}}` - if (parts.length > 0) { - identifier = parts[0] // Do not shift yet - // Check if a resource exists with this service, name and identifier combination - const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/arbitrary/resource/status/${service}/${name}/${identifier}?apiKey=${myNode.apiKey}}` + const res = await fetch(url); + const data = await res.json(); + if (data.totalChunkCount > 0) { + // Identifier exists, so don't include it in the path + parts.shift() + } + else { + identifier = null + } + } - const res = await fetch(url); - const data = await res.json(); - if (data.totalChunkCount > 0) { - // Identifier exists, so don't include it in the path - parts.shift() - } - else { - identifier = null - } - } + const path = parts.join("/") - const path = parts.join("/") + const components = {} + components["service"] = service + components["name"] = name + components["identifier"] = identifier + components["path"] = path + return components + } + return null + } - const components = {} - components["service"] = service - components["name"] = name - components["identifier"] = identifier - components["path"] = path - return components - } - return null + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } - - - - - - - - render() { - let avatarImg - const avatarUrl = `${this.nodeUrl}/arbitrary/THUMBNAIL/${this.resource.name}/qortal_avatar?async=true&apiKey=${this.myNode.apiKey}`; - avatarImg = html``; - let avatarImgApp - const avatarUrl2 = `${this.nodeUrl}/arbitrary/THUMBNAIL/${this.appName}/qortal_avatar?async=true&apiKey=${this.myNode.apiKey}`; - avatarImgApp = html``; - return html` -
    - ${ - this.status.status !== 'READY' - ? html` -
    -
    -

    ${`${Math.round(this.status.percentLoaded || 0 - ).toFixed(0)}% `}${translate('chatpage.cchange94')}

    -
    - ` - : '' - } - ${this.status.status === 'READY' && this.feedItem ? html` -
    -
    -
    - ${avatarImg}
    ${this.resource.name} -
    -
    -

    ${this.feedItem.title}

    -
    -
    -
    - ${avatarImgApp} -
    - -
    -
    - ` : ''} - -
    - - ` - - - } -} - -customElements.define('feed-item', FeedItem); +window.customElements.define('feed-item', FeedItem) \ No newline at end of file diff --git a/core/src/components/friends-view/friend-item-actions.js b/core/src/components/friends-view/friend-item-actions.js index 06b1217a..1f57893c 100644 --- a/core/src/components/friends-view/friend-item-actions.js +++ b/core/src/components/friends-view/friend-item-actions.js @@ -1,146 +1,42 @@ -// popover-component.js -import {css, html, LitElement} from 'lit'; -import {createPopper} from '@popperjs/core'; -import '@material/mwc-icon'; -import {translate} from '../../../translate' -import {store} from '../../store'; -import {connect} from 'pwa-helpers'; -import {setNewTab, setSideEffectAction} from '../../redux/app/app-actions'; -import ShortUniqueId from 'short-unique-id'; +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { createPopper } from '@popperjs/core' +import { setNewTab, setSideEffectAction } from '../../redux/app/app-actions' +import { translate } from '../../../translate' +import { friendItemActionsStyles } from '../../styles/core-css' +import ShortUniqueId from 'short-unique-id' +import '@material/mwc-icon' export class FriendItemActions extends connect(store)(LitElement) { - static styles = css` - :host { - display: none; - position: absolute; - background-color: var(--white); - border: 1px solid #ddd; - padding: 8px; - z-index: 10; - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); - color: var(--black); - max-width: 250px; - } - - .close-icon { - cursor: pointer; - float: right; - margin-left: 10px; - color: var(--black); - } - - .send-message-button { - font-family: Roboto, sans-serif; - letter-spacing: 0.3px; - font-weight: 300; - padding: 8px 5px; - border-radius: 3px; - text-align: center; - color: var(--mdc-theme-primary); - transition: all 0.3s ease-in-out; - display: flex; - align-items: center; - gap: 10px; - } - - .send-message-button:hover { - cursor: pointer; - background-color: #03a8f485; - } - .action-parent { - display: flex; - flex-direction: column; - width: 100%; - } - - div[tabindex='0']:focus { - outline: none; - } - `; - static get properties() { return { for: { type: String, reflect: true }, message: { type: String }, openEditFriend: { attribute: false }, name: { type: String }, - closeSidePanel: { attribute: false, type: Object }, - }; + closeSidePanel: { attribute: false, type: Object } + } + } + + static get styles() { + return [friendItemActionsStyles] } constructor() { - super(); - this.message = ''; - this.nodeUrl = this.getNodeUrl(); - this.uid = new ShortUniqueId(); - this.getUserAddress = this.getUserAddress.bind(this); - } - getNodeUrl() { - const myNode = - store.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] - - return myNode.protocol + '://' + myNode.domain + ':' + myNode.port - } - - firstUpdated() { - // We'll defer the popper attachment to the openPopover() method to ensure target availability - } - - attachToTarget(target) { - if (!this.popperInstance && target) { - this.popperInstance = createPopper(target, this, { - placement: 'bottom', - }); - } - } - - openPopover(target) { - this.attachToTarget(target); - this.style.display = 'block'; - setTimeout(() => { - this.shadowRoot.getElementById('parent-div').focus(); - }, 50); - } - - closePopover() { - this.style.display = 'none'; - if (this.popperInstance) { - this.popperInstance.destroy(); - this.popperInstance = null; - } - this.requestUpdate(); - } - handleBlur() { - setTimeout(() => { - this.closePopover(); - }, 0); - } - - async getUserAddress() { - try { - const url = `${this.nodeUrl}/names/${this.name}`; - const res = await fetch(url); - const result = await res.json(); - if (result.error === 401) { - return ''; - } else { - return result.owner; - } - } catch (error) { - return ''; - } + super() + this.message = '' + this.nodeUrl = this.getNodeUrl() + this.uid = new ShortUniqueId() + this.getUserAddress = this.getUserAddress.bind(this) } render() { return html`
    - close + + close +
    - person + person ${translate('profile.profile18')}
    - `; + ` + } + + firstUpdated() { + // ... + } + + getNodeUrl() { + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return myNode.protocol + '://' + myNode.domain + ':' + myNode.port + } + + attachToTarget(target) { + if (!this.popperInstance && target) { + this.popperInstance = createPopper(target, this, { + placement: 'bottom' + }) + } + } + + openPopover(target) { + this.attachToTarget(target) + this.style.display = 'block' + setTimeout(() => { + this.shadowRoot.getElementById('parent-div').focus() + }, 50) + } + + closePopover() { + this.style.display = 'none' + if (this.popperInstance) { + this.popperInstance.destroy() + this.popperInstance = null + } + this.requestUpdate() + } + + handleBlur() { + setTimeout(() => { + this.closePopover() + }, 0) + } + + async getUserAddress() { + try { + const url = `${this.nodeUrl}/names/${this.name}` + const res = await fetch(url) + const result = await res.json() + if (result.error === 401) { + return '' + } else { + return result.owner + } + } catch (error) { + return '' + } + } + + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } } -customElements.define('friend-item-actions', FriendItemActions); +window.customElements.define('friend-item-actions', FriendItemActions) diff --git a/core/src/components/friends-view/friends-feed.js b/core/src/components/friends-view/friends-feed.js index 597fa8e1..b20a18e2 100644 --- a/core/src/components/friends-view/friends-feed.js +++ b/core/src/components/friends-view/friends-feed.js @@ -1,476 +1,461 @@ -import {html, LitElement} from 'lit'; -import '@material/mwc-icon'; -import './friends-view' -import {friendsViewStyles} from './friends-view-css'; -import {connect} from 'pwa-helpers'; -import {store} from '../../store'; +import { html, LitElement } from 'lit' +import { store } from '../../store' +import { connect } from 'pwa-helpers' +import { translate } from '../../../translate' +import { friendsViewStyles } from '../../styles/core-css' import './feed-item' -import {translate} from '../../../translate' - +import './friends-view' +import '@material/mwc-icon' import '@polymer/paper-spinner/paper-spinner-lite.js' +const perEndpointCount = 20 +const totalDesiredCount = 100 +const maxResultsInMemory = 300 -const perEndpointCount = 20; -const totalDesiredCount = 100; -const maxResultsInMemory = 300; class FriendsFeed extends connect(store)(LitElement) { - static get properties() { + static get properties() { return { - feed: {type: Array}, - setHasNewFeed: {attribute:false}, - isLoading: {type: Boolean}, - hasFetched: {type: Boolean}, - mySelectedFeeds: {type: Array} - }; - } - constructor(){ - super() - this.feed = [] - this.feedToRender = [] - this.nodeUrl = this.getNodeUrl(); - this.myNode = this.getMyNode(); - this.endpoints = [] - this.endpointOffsets = [] // Initialize offsets for each endpoint to 0 - - this.loadAndMergeData = this.loadAndMergeData.bind(this) - this.hasInitialFetch = false - this.observerHandler = this.observerHandler.bind(this); - this.elementObserver = this.elementObserver.bind(this) - this.mySelectedFeeds = [] - this.getSchemas = this.getSchemas.bind(this) - this.hasFetched = false - this._updateFeeds = this._updateFeeds.bind(this) - + feed: { type: Array }, + setHasNewFeed: { attribute: false }, + isLoading: { type: Boolean }, + hasFetched: { type: Boolean }, + mySelectedFeeds: { type: Array } + } } static get styles() { - return [friendsViewStyles]; + return [friendsViewStyles] + } + + constructor() { + super() + this.feed = [] + this.feedToRender = [] + this.nodeUrl = this.getNodeUrl() + this.myNode = this.getMyNode() + this.endpoints = [] + this.endpointOffsets = [] // Initialize offsets for each endpoint to 0 + this.loadAndMergeData = this.loadAndMergeData.bind(this) + this.hasInitialFetch = false + this.observerHandler = this.observerHandler.bind(this) + this.elementObserver = this.elementObserver.bind(this) + this.mySelectedFeeds = [] + this.getSchemas = this.getSchemas.bind(this) + this.hasFetched = false + this._updateFeeds = this._updateFeeds.bind(this) + } + + render() { + return html` +
    +
    + ${this.isLoading ? html` +
    + +
    + ` : ''} + ${this.hasFetched && !this.isLoading && this.feed.length === 0 ? html` +
    +

    ${translate('friends.friend17')}

    +
    + ` : ''} + ${this.feedToRender.map((item) => { + return html` + + + ` + })} +
    +
    +
    + ` } + async firstUpdated() { + this.viewElement = this.shadowRoot.getElementById('viewElement') + this.downObserverElement = this.shadowRoot.getElementById('downObserver') + this.elementObserver() + + try { + await new Promise((res) => { + setTimeout(() => { + res() + }, 5000) + }) + + if (this.mySelectedFeeds.length === 0) { + await this.getEndpoints() + await this.loadAndMergeData() + } + + this.getFeedOnInterval() + } catch (error) { + console.log(error) + } + } getNodeUrl() { - const myNode = - store.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] - + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] return myNode.protocol + '://' + myNode.domain + ':' + myNode.port } + getMyNode() { - return store.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] + return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] } - _updateFeeds(event) { + _updateFeeds(event) { this.mySelectedFeeds = event.detail - this.reFetchFeedData() - this.requestUpdate() + this.reFetchFeedData() + this.requestUpdate() } connectedCallback() { super.connectedCallback() - window.addEventListener('friends-my-selected-feeds-event', this._updateFeeds) } + window.addEventListener('friends-my-selected-feeds-event', this._updateFeeds) + } disconnectedCallback() { window.removeEventListener('friends-my-selected-feeds-event', this._updateFeeds) super.disconnectedCallback() } - async getSchemas(){ - this.mySelectedFeeds = JSON.parse(localStorage.getItem('friends-my-selected-feeds') || "[]") - const schemas = this.mySelectedFeeds - const getAllSchemas = (schemas || []).map( - async (schema) => { - try { - const url = `${this.nodeUrl}/arbitrary/${schema.service}/${schema.name}/${schema.identifier}`; - const res = await fetch(url) - const data = await res.json() - if(data.error) return false - return data - } catch (error) { - console.log(error); - return false - } - } - ); - const res = await Promise.all(getAllSchemas); - return res.filter((item)=> !!item) - } + async getSchemas() { + this.mySelectedFeeds = JSON.parse(localStorage.getItem('friends-my-selected-feeds') || "[]") + const schemas = this.mySelectedFeeds - getFeedOnInterval(){ - let interval = null; - let stop = false; - const getAnswer = async () => { - - if (!stop) { - stop = true; + const getAllSchemas = (schemas || []).map( + async (schema) => { try { - await this.reFetchFeedData() - } catch (error) {} - stop = false; + const url = `${this.nodeUrl}/arbitrary/${schema.service}/${schema.name}/${schema.identifier}` + const res = await fetch(url) + const data = await res.json() + if (data.error) return false + return data + } catch (error) { + console.log(error) + return false + } } - }; - interval = setInterval(getAnswer, 900000); + ) - } - - async getEndpoints(){ - const dynamicVars = { - - } - const schemas = await this.getSchemas() - const friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]") - const names = friendList.map(friend => `name=${friend.name}`).join('&'); - if(names.length === 0){ - this.endpoints= [] - this.endpointOffsets = Array(this.endpoints.length).fill(0); - return - } - const baseurl = `${this.nodeUrl}/arbitrary/resources/search?reverse=true&mode=ALL&exactmatchnames=true&${names}` - let formEndpoints = [] - schemas.forEach((schema)=> { - const feedData = schema.feed[0] - if(feedData){ - const copyFeedData = {...feedData} - const fullUrl = constructUrl(baseurl, copyFeedData.search, dynamicVars); - if(fullUrl){ - formEndpoints.push({ - url: fullUrl, schemaName: schema.name, schema: copyFeedData - }) - } - } - - - }) - this.endpoints= formEndpoints - this.endpointOffsets = Array(this.endpoints.length).fill(0); - } - - async firstUpdated(){ - this.viewElement = this.shadowRoot.getElementById('viewElement'); - this.downObserverElement = - this.shadowRoot.getElementById('downObserver'); - this.elementObserver(); - - - try { - await new Promise((res)=> { - setTimeout(() => { - res() - }, 5000); - }) - if(this.mySelectedFeeds.length === 0){ - await this.getEndpoints() - -await this.loadAndMergeData(); - } - -this.getFeedOnInterval() - - } catch (error) { - console.log(error) - } + const res = await Promise.all(getAllSchemas) + return res.filter((item) => !!item) } - getMoreFeed(){ - if(!this.hasInitialFetch) return - if(this.feedToRender.length === this.feed.length ) return - this.feedToRender = this.feed.slice(0, this.feedToRender.length + 20) - this.requestUpdate() - } + getFeedOnInterval() { + let interval = null + let stop = false - async refresh(){ - try { - await this.getEndpoints() - await this.reFetchFeedData() - } catch (error) { + const getAnswer = async () => { + if (!stop) { + stop = true + try { + await this.reFetchFeedData() + } catch (error) { } + stop = false + } + } - } - } + interval = setInterval(getAnswer, 900000) + } + async getEndpoints() { + const dynamicVars = { } + const schemas = await this.getSchemas() + const friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]") + const names = friendList.map(friend => `name=${friend.name}`).join('&') + + if (names.length === 0) { + this.endpoints = [] + this.endpointOffsets = Array(this.endpoints.length).fill(0) + return + } + + const baseurl = `${this.nodeUrl}/arbitrary/resources/search?reverse=true&mode=ALL&exactmatchnames=true&${names}` + let formEndpoints = [] + + schemas.forEach((schema) => { + const feedData = schema.feed[0] + if (feedData) { + const copyFeedData = { ...feedData } + const fullUrl = constructUrl(baseurl, copyFeedData.search, dynamicVars) + if (fullUrl) { + formEndpoints.push({ + url: fullUrl, schemaName: schema.name, schema: copyFeedData + }) + } + } + }) + + this.endpoints = formEndpoints + this.endpointOffsets = Array(this.endpoints.length).fill(0) + } + + getMoreFeed() { + if (!this.hasInitialFetch) return + if (this.feedToRender.length === this.feed.length) return + this.feedToRender = this.feed.slice(0, this.feedToRender.length + 20) + this.requestUpdate() + } + + async refresh() { + try { + await this.getEndpoints() + await this.reFetchFeedData() + } catch (error) { + + } + } elementObserver() { const options = { rootMargin: '0px', - threshold: 1, - }; + threshold: 1 + } + // identify an element to observe - const elementToObserve = this.downObserverElement; + const elementToObserve = this.downObserverElement + // passing it a callback function const observer = new IntersectionObserver( this.observerHandler, options - ); + ) + // call `observe()` on that MutationObserver instance, // passing it the element to observe, and the options object - observer.observe(elementToObserve); + observer.observe(elementToObserve) } observerHandler(entries) { if (!entries[0].isIntersecting) { - } else { if (this.feedToRender.length < 20) { - return; + return } - this.getMoreFeed(); + this.getMoreFeed() } } - async fetchDataFromEndpoint(endpointIndex, count) { - const offset = this.endpointOffsets[endpointIndex]; - const url = `${this.endpoints[endpointIndex].url}&limit=${count}&offset=${offset}`; - const res = await fetch(url) - const data = await res.json() - return data.map((i)=> { - return { - ...this.endpoints[endpointIndex], - ...i - } - }) + async fetchDataFromEndpoint(endpointIndex, count) { + const offset = this.endpointOffsets[endpointIndex] + const url = `${this.endpoints[endpointIndex].url}&limit=${count}&offset=${offset}` + const res = await fetch(url) + const data = await res.json() - } + return data.map((i) => { + return { + ...this.endpoints[endpointIndex], + ...i + } + }) + } + async initialLoad() { + let results = [] + let totalFetched = 0 + let i = 0 + let madeProgress = true + let exhaustedEndpoints = new Set() - async initialLoad() { - let results = []; - let totalFetched = 0; - let i = 0; - let madeProgress = true; - let exhaustedEndpoints = new Set(); + while (totalFetched < totalDesiredCount && madeProgress) { + madeProgress = false + this.isLoading = true + for (i = 0; i < this.endpoints.length; i++) { + if (exhaustedEndpoints.has(i)) { + continue + } - while (totalFetched < totalDesiredCount && madeProgress) { - madeProgress = false; - this.isLoading = true - for (i = 0; i < this.endpoints.length; i++) { - if (exhaustedEndpoints.has(i)) { - continue; - } + const remainingCount = totalDesiredCount - totalFetched - const remainingCount = totalDesiredCount - totalFetched; + // If we've already reached the desired count, break + if (remainingCount <= 0) { + break; + } - // If we've already reached the desired count, break - if (remainingCount <= 0) { - break; - } + let fetchCount = Math.min(perEndpointCount, remainingCount) + let data = await this.fetchDataFromEndpoint(i, fetchCount) - let fetchCount = Math.min(perEndpointCount, remainingCount); - let data = await this.fetchDataFromEndpoint(i, fetchCount); + // Increment the offset for this endpoint by the number of items fetched + this.endpointOffsets[i] += data.length - // Increment the offset for this endpoint by the number of items fetched - this.endpointOffsets[i] += data.length; + if (data.length > 0) { + madeProgress = true + } - if (data.length > 0) { - madeProgress = true; - } + if (data.length < fetchCount) { + exhaustedEndpoints.add(i) + } - if (data.length < fetchCount) { - exhaustedEndpoints.add(i); - } + results = results.concat(data) + totalFetched += data.length + } - results = results.concat(data); - totalFetched += data.length; - } + if (exhaustedEndpoints.size === this.endpoints.length) { + break + } + } - if (exhaustedEndpoints.size === this.endpoints.length) { - break; - } - } - this.isLoading = false - this.hasFetched = true; - // Trim the results if somehow they are over the totalDesiredCount - return results.slice(0, totalDesiredCount); - } + this.isLoading = false + this.hasFetched = true + // Trim the results if somehow they are over the totalDesiredCount + return results.slice(0, totalDesiredCount) + } + trimDataToLimit(data, limit) { + return data.slice(0, limit) + } + mergeData(newData, existingData) { + const existingIds = new Set(existingData.map(item => item.identifier)) // Assume each item has a unique 'id' + const uniqueNewData = newData.filter(item => !existingIds.has(item.identifier)) + return uniqueNewData.concat(existingData) + } + async addExtraData(data) { + let newData = [] + for (let item of data) { + let newItem = { + ...item, + schema: { + ...item.schema, + customParams: { ...item.schema.customParams } - trimDataToLimit(data, limit) { - return data.slice(0, limit); - } + } + } - mergeData(newData, existingData) { - const existingIds = new Set(existingData.map(item => item.identifier)); // Assume each item has a unique 'id' - const uniqueNewData = newData.filter(item => !existingIds.has(item.identifier)); - return uniqueNewData.concat(existingData); - } + let newResource = { + identifier: newItem.identifier, + service: newItem.service, + name: newItem.name + } + if (newItem.schema) { + const resource = newItem - async addExtraData(data){ - let newData = [] - for (let item of data) { - let newItem = { - ...item, - schema: { - ...item.schema, - customParams: {...item.schema.customParams} - - } - } - let newResource = { - identifier: newItem.identifier, - service: newItem.service, - name: newItem.name - } - if(newItem.schema){ - const resource = newItem - - let clickValue1 = newItem.schema.click; + let clickValue1 = newItem.schema.click; newItem.link = replacePlaceholders(clickValue1, resource, newItem.schema.customParams) - newData.push(newItem) - } - } - return newData + newData.push(newItem) + } + } + return newData + } - } - async reFetchFeedData() { - // Resetting offsets to start fresh. - this.endpointOffsets = Array(this.endpoints.length).fill(0); - await this.getEndpoints() - const oldIdentifiers = new Set(this.feed.map(item => item.identifier)); - const newData = await this.initialLoad(); + async reFetchFeedData() { + // Resetting offsets to start fresh. + this.endpointOffsets = Array(this.endpoints.length).fill(0) + await this.getEndpoints() + const oldIdentifiers = new Set(this.feed.map(item => item.identifier)) + const newData = await this.initialLoad() - // Filter out items that are already in the feed - const trulyNewData = newData.filter(item => !oldIdentifiers.has(item.identifier)); + // Filter out items that are already in the feed + const trulyNewData = newData.filter(item => !oldIdentifiers.has(item.identifier)) - if (trulyNewData.length > 0) { - // Adding extra data and merging with old data - const enhancedNewData = await this.addExtraData(trulyNewData); + if (trulyNewData.length > 0) { + // Adding extra data and merging with old data + const enhancedNewData = await this.addExtraData(trulyNewData) - // Merge new data with old data immutably - this.feed = [...enhancedNewData, ...this.feed]; - this.feed = this.removeDuplicates(this.feed) - this.feed.sort((a, b) => new Date(b.created) - new Date(a.created)); // Sort by timestamp, most recent first - this.feed = this.trimDataToLimit(this.feed, maxResultsInMemory); // Trim to the maximum allowed in memory - this.feedToRender = this.feed.slice(0, 20); - this.hasInitialFetch = true; + // Merge new data with old data immutably + this.feed = [...enhancedNewData, ...this.feed] + this.feed = this.removeDuplicates(this.feed) + this.feed.sort((a, b) => new Date(b.created) - new Date(a.created)) // Sort by timestamp, most recent first + this.feed = this.trimDataToLimit(this.feed, maxResultsInMemory) // Trim to the maximum allowed in memory + this.feedToRender = this.feed.slice(0, 20) + this.hasInitialFetch = true - const created = trulyNewData[0].created; - let value = localStorage.getItem('lastSeenFeed'); - if (((+value || 0) < created)) { - this.setHasNewFeed(true); - } - } - } - - - removeDuplicates(array) { - const seenIds = new Set(); - return array.filter(item => { - if (!seenIds.has(item.identifier)) { - seenIds.add(item.identifier); - return true; - } - return false; - }); - } - - - async loadAndMergeData() { - let allData = this.feed - const newData = await this.initialLoad(); - allData = await this.addExtraData(newData) - allData = this.mergeData(newData, allData); - allData.sort((a, b) => new Date(b.created) - new Date(a.created)); // Sort by timestamp, most recent first - allData = this.trimDataToLimit(allData, maxResultsInMemory); // Trim to the maximum allowed in memory - allData = this.removeDuplicates(allData) - this.feed = [...allData] - this.feedToRender = this.feed.slice(0,20) - this.hasInitialFetch = true - if(allData.length > 0){ - const created = allData[0].created - let value = localStorage.getItem('lastSeenFeed') + const created = trulyNewData[0].created + let value = localStorage.getItem('lastSeenFeed') if (((+value || 0) < created)) { this.setHasNewFeed(true) } - } - } - - - - - - render() { - return html` -
    -
    - ${this.isLoading ? html` -
    - -
    - ` : ''} - ${this.hasFetched && !this.isLoading && this.feed.length === 0 ? html` -
    -

    ${translate('friends.friend17')}

    -
    - ` : ''} - ${this.feedToRender.map((item) => { - return html``; - })} -
    -
    -
    - `; + } } + removeDuplicates(array) { + const seenIds = new Set() + return array.filter(item => { + if (!seenIds.has(item.identifier)) { + seenIds.add(item.identifier) + return true + } + return false + }) + } + + async loadAndMergeData() { + let allData = this.feed + const newData = await this.initialLoad(); + allData = await this.addExtraData(newData) + allData = this.mergeData(newData, allData); + allData.sort((a, b) => new Date(b.created) - new Date(a.created)); // Sort by timestamp, most recent first + allData = this.trimDataToLimit(allData, maxResultsInMemory); // Trim to the maximum allowed in memory + allData = this.removeDuplicates(allData) + this.feed = [...allData] + this.feedToRender = this.feed.slice(0, 20) + this.hasInitialFetch = true + if (allData.length > 0) { + const created = allData[0].created + let value = localStorage.getItem('lastSeenFeed') + if (((+value || 0) < created)) { + this.setHasNewFeed(true) + } + } + } + + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } -customElements.define('friends-feed', FriendsFeed); +window.customElements.define('friends-feed', FriendsFeed) export function substituteDynamicVar(value, dynamicVars) { - if (typeof value !== 'string') return value; - - const pattern = /\$\$\{([a-zA-Z0-9_]+)\}\$\$/g; // Adjusted pattern to capture $${name}$$ with curly braces - - return value.replace(pattern, (match, p1) => { - return dynamicVars[p1] !== undefined ? dynamicVars[p1] : match; - }); + if (typeof value !== 'string') return value + const pattern = /\$\$\{([a-zA-Z0-9_]+)\}\$\$/g // Adjusted pattern to capture $${name}$$ with curly braces + return value.replace(pattern, (match, p1) => { + return dynamicVars[p1] !== undefined ? dynamicVars[p1] : match + }) } export function constructUrl(base, search, dynamicVars) { - let queryStrings = []; - - for (const [key, value] of Object.entries(search)) { - const substitutedValue = substituteDynamicVar(value, dynamicVars); - queryStrings.push(`${key}=${encodeURIComponent(substitutedValue)}`); - } - - return queryStrings.length > 0 ? `${base}&${queryStrings.join('&')}` : base; + let queryStrings = [] + for (const [key, value] of Object.entries(search)) { + const substitutedValue = substituteDynamicVar(value, dynamicVars) + queryStrings.push(`${key}=${encodeURIComponent(substitutedValue)}`) + } + return queryStrings.length > 0 ? `${base}&${queryStrings.join('&')}` : base } - - - - - - - export function replacePlaceholders(template, resource, customParams) { - const dataSource = { resource, customParams }; - - return template.replace(/\$\$\{(.*?)\}\$\$/g, (match, p1) => { - const keys = p1.split('.'); - let value = dataSource; - - for (let key of keys) { - if (value[key] !== undefined) { - value = value[key]; - } else { - return match; // Return placeholder unchanged - } - } - return value; - }); -} - - - - + const dataSource = { resource, customParams } + return template.replace(/\$\$\{(.*?)\}\$\$/g, (match, p1) => { + const keys = p1.split('.') + let value = dataSource + for (let key of keys) { + if (value[key] !== undefined) { + value = value[key] + } else { + return match // Return placeholder unchanged + } + } + return value + }) +} \ No newline at end of file diff --git a/core/src/components/friends-view/friends-side-panel-parent.js b/core/src/components/friends-view/friends-side-panel-parent.js index 42984e65..1af1c69e 100644 --- a/core/src/components/friends-view/friends-side-panel-parent.js +++ b/core/src/components/friends-view/friends-side-panel-parent.js @@ -1,68 +1,43 @@ -import {css, html, LitElement} from 'lit' +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { translate } from '../../../translate' +import { friendsSidePanelParentStyles } from '../../styles/core-css' +import './friends-side-panel' import '@material/mwc-icon' -import './friends-side-panel.js' import '@vaadin/tooltip' -import {translate} from '../../../translate' -class FriendsSidePanelParent extends LitElement { +class FriendsSidePanelParent extends connect(store)(LitElement) { static get properties() { return { - isOpen: {type: Boolean}, - hasNewFeed: {type: Boolean} + isOpen: { type: Boolean }, + hasNewFeed: { type: Boolean } } } + static get styles() { + return [friendsSidePanelParentStyles] + } + constructor() { super() this.isOpen = false this.hasNewFeed = false } - static styles = css` - .header { - display: flex; - align-items: center; - justify-content: space-between; - padding: 16px; - border-bottom: 1px solid #e0e0e0; - } - - .content { - padding: 16px; - } - .close { - visibility: hidden; - position: fixed; - z-index: -100; - right: -1000px; - } - - .parent-side-panel { - transform: translateX(100%); /* start from outside the right edge */ - transition: transform 0.3s ease-in-out; - } - .parent-side-panel.open { - transform: translateX(0); /* slide in to its original position */ - - } - ` - - setHasNewFeed(val){ - this.hasNewFeed = val - } - render() { return html` { + @click=${() => { this.isOpen = !this.isOpen - if(this.isOpen && this.hasNewFeed) { + if (this.isOpen && this.hasNewFeed) { localStorage.setItem('lastSeenFeed', Date.now()) this.hasNewFeed = false this.shadowRoot.querySelector("friends-side-panel").selected = 'feed' } - }} style="color: ${this.hasNewFeed ? 'green' : 'var(--black)'}; cursor:pointer;user-select:none" + }} + style="color: ${this.hasNewFeed ? 'green' : 'var(--black)'}; cursor:pointer;user-select:none" > group @@ -72,12 +47,33 @@ class FriendsSidePanelParent extends LitElement { hover-delay=${400} hide-delay=${1} text=${translate('friends.friend12')} - > - - this.setHasNewFeed(val)} ?isOpen=${this.isOpen} .setIsOpen=${(val)=> this.isOpen = val}> - + > + this.setHasNewFeed(val)} ?isOpen=${this.isOpen} .setIsOpen=${(val) => this.isOpen = val}> ` } + + firstUpdated() { + // ... + } + + setHasNewFeed(val) { + this.hasNewFeed = val + } + + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } -customElements.define('friends-side-panel-parent', FriendsSidePanelParent) +window.customElements.define('friends-side-panel-parent', FriendsSidePanelParent) \ No newline at end of file diff --git a/core/src/components/friends-view/friends-side-panel.js b/core/src/components/friends-view/friends-side-panel.js index 3e4a0370..11485887 100644 --- a/core/src/components/friends-view/friends-side-panel.js +++ b/core/src/components/friends-view/friends-side-panel.js @@ -1,158 +1,94 @@ -import {css, html, LitElement} from 'lit'; -import '@material/mwc-icon'; +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { translate } from '../../../translate' +import { friendsSidePanelStyles } from '../../styles/core-css' import './friends-view' import './friends-feed' -import {translate} from '../../../translate' +import '@material/mwc-icon' -class FriendsSidePanel extends LitElement { - static get properties() { +class FriendsSidePanel extends connect(store)(LitElement) { + static get properties() { return { - setIsOpen: { attribute: false}, - isOpen: {type: Boolean}, - selected: {type: String}, - setHasNewFeed: {attribute: false}, - closeSidePanel: {attribute: false, type: Object}, - openSidePanel: {attribute: false, type: Object} - }; + setIsOpen: { attribute: false }, + isOpen: { type: Boolean }, + selected: { type: String }, + setHasNewFeed: { attribute: false }, + closeSidePanel: { attribute: false, type: Object }, + openSidePanel: { attribute: false, type: Object } + } } - constructor(){ + static get styles() { + return [friendsSidePanelStyles] + } + + constructor() { super() this.selected = 'friends' this.closeSidePanel = this.closeSidePanel.bind(this) this.openSidePanel = this.openSidePanel.bind(this) - - } - - static styles = css` - :host { - display: block; - position: fixed; - top: 55px; - right: 0px; - width: 420px; - max-width: 95%; - height: calc(100vh - 55px); - background-color: var(--white); - border-left: 1px solid rgb(224, 224, 224); - z-index: 1; - transform: translateX(100%); /* start from outside the right edge */ - transition: transform 0.3s ease-in-out; - } - :host([isOpen]) { - transform: unset; /* slide in to its original position */ - } - - .header { - display: flex; - align-items: center; - justify-content: space-between; - padding: 16px; - border-bottom: 1px solid #e0e0e0; - } - - .content { - padding: 16px; - display: flex; - flex-direction: column; - flex-grow: 1; - overflow: auto; - } - .content::-webkit-scrollbar-track { - background-color: whitesmoke; - border-radius: 7px; - } - - .content::-webkit-scrollbar { - width: 12px; - border-radius: 7px; - background-color: whitesmoke; - } - - .content::-webkit-scrollbar-thumb { - background-color: rgb(180, 176, 176); - border-radius: 7px; - transition: all 0.3s ease-in-out; - } - .parent { - display: flex; - flex-direction: column; - height: 100%; - } - - .active { - font-size: 16px; - background: var(--black); - color: var(--white); - padding: 5px; - border-radius: 2px; - cursor: pointer; - } - - .default { - font-size: 16px; - color: var(--black); - padding: 5px; - border-radius: 2px; - cursor: pointer; - } - - .default-content { - visibility: hidden; - position: absolute; - z-index: -50; - } - - `; - - refreshFeed(){ - - this.shadowRoot.querySelector('friends-feed').refresh() - - - } - - closeSidePanel(){ - this.setIsOpen(false) - } - openSidePanel(){ - this.setIsOpen(true) } render() { return html`
    -
    -
    - this.selected = 'friends'} class="${this.selected === 'friends' ? 'active' : 'default'}">${translate('friends.friend12')} - this.selected = 'feed'} class="${this.selected === 'feed' ? 'active' : 'default'}">${translate('friends.friend13')} -
    -
    - { - this.refreshFeed() - }} style="color: var(--black); cursor:pointer;">refresh - { - this.setIsOpen(false) - }}>close -
    - -
    -
    -
    - this.refreshFeed()}> +
    +
    + this.selected = 'friends'} class="${this.selected === 'friends' ? 'active' : 'default'}">${translate('friends.friend12')} + this.selected = 'feed'} class="${this.selected === 'feed' ? 'active' : 'default'}">${translate('friends.friend13')} +
    +
    + { this.refreshFeed(); }} style="color: var(--black); cursor:pointer;"> + refresh + + { this.setIsOpen(false); }}> + close + +
    -
    - this.setHasNewFeed(val)}> +
    +
    + this.refreshFeed()}> +
    +
    + this.setHasNewFeed(val)}> +
    - - - -
    -
    - `; + ` } + firstUpdated() { + // ... + } + + refreshFeed() { + this.shadowRoot.querySelector('friends-feed').refresh() + } + + closeSidePanel() { + this.setIsOpen(false) + } + + openSidePanel() { + this.setIsOpen(true) + } + + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } -customElements.define('friends-side-panel', FriendsSidePanel); +window.customElements.define('friends-side-panel', FriendsSidePanel) \ No newline at end of file diff --git a/core/src/components/friends-view/friends-view-css.js b/core/src/components/friends-view/friends-view-css.js deleted file mode 100644 index aa3aa5be..00000000 --- a/core/src/components/friends-view/friends-view-css.js +++ /dev/null @@ -1,182 +0,0 @@ -import {css} from 'lit' - -export const friendsViewStyles = css` -* { - box-sizing: border-box; -} - .top-bar-icon { - cursor: pointer; - height: 18px; - width: 18px; - transition: 0.2s all; - } - - .top-bar-icon:hover { - color: var(--black); - } - - .modal-button { - font-family: Roboto, sans-serif; - font-size: 16px; - color: var(--mdc-theme-primary); - background-color: transparent; - padding: 8px 10px; - border-radius: 5px; - border: none; - transition: all 0.3s ease-in-out; - } - - .close-row { - width: 100%; - display: flex; - justify-content: flex-end; - height: 50px; - flex:0 - - } - - .container-body { - width: 100%; - display: flex; - flex-direction: column; - flex-grow: 1; - margin-top: 5px; - padding: 0px 6px; - box-sizing: border-box; - align-items: center; - gap: 10px; - } - - .container-body::-webkit-scrollbar-track { - background-color: whitesmoke; - border-radius: 7px; - } - - .container-body::-webkit-scrollbar { - width: 6px; - border-radius: 7px; - background-color: whitesmoke; - } - - .container-body::-webkit-scrollbar-thumb { - background-color: rgb(180, 176, 176); - border-radius: 7px; - transition: all 0.3s ease-in-out; - } - - .container-body::-webkit-scrollbar-thumb:hover { - background-color: rgb(148, 146, 146); - cursor: pointer; - } - - p { - color: var(--black); - margin: 0px; - padding: 0px; - word-break: break-all; - } - - .container { - display: flex; - width: 100%; - flex-direction: column; - height: 100%; - } - - .chat-right-panel-label { - font-family: Montserrat, sans-serif; - color: var(--group-header); - padding: 5px; - font-size: 13px; - user-select: none; - } - - .group-info { - display: flex; - flex-direction: column; - justify-content: flex-start; - gap: 10px; - } - - .group-name { - font-family: Raleway, sans-serif; - font-size: 20px; - color: var(--chat-bubble-msg-color); - text-align: center; - user-select: none; - } - - .group-description { - font-family: Roboto, sans-serif; - color: var(--chat-bubble-msg-color); - letter-spacing: 0.3px; - font-weight: 300; - font-size: 14px; - margin-top: 15px; - word-break: break-word; - user-select: none; - } - - .group-subheader { - font-family: Montserrat, sans-serif; - font-size: 14px; - color: var(--chat-bubble-msg-color); - } - - .group-data { - font-family: Roboto, sans-serif; - letter-spacing: 0.3px; - font-weight: 300; - font-size: 14px; - color: var(--chat-bubble-msg-color); - } - .search-results-div { - position: absolute; - top: 25px; - right: 25px; - } - - .name-input { - width: 100%; - outline: 0; - border-width: 0 0 2px; - border-color: var(--mdc-theme-primary); - background-color: transparent; - padding: 10px; - font-family: Roboto, sans-serif; - font-size: 15px; - color: var(--chat-bubble-msg-color); - box-sizing: border-box; - } - - .name-input::selection { - background-color: var(--mdc-theme-primary); - color: white; - } - - .name-input::placeholder { - opacity: 0.9; - color: var(--black); - } - - .search-field { - width: 100%; - position: relative; - } - - .search-icon { - position: absolute; - right: 3px; - color: var(--chat-bubble-msg-color); - transition: hover 0.3s ease-in-out; - background: none; - border-radius: 50%; - padding: 6px 3px; - font-size: 21px; - } - - .search-icon:hover { - cursor: pointer; - background: #d7d7d75c; - } -` diff --git a/core/src/components/friends-view/friends-view.js b/core/src/components/friends-view/friends-view.js index 94e4b128..6d320f39 100644 --- a/core/src/components/friends-view/friends-view.js +++ b/core/src/components/friends-view/friends-view.js @@ -1,22 +1,20 @@ -import {html, LitElement} from 'lit'; -import {connect} from 'pwa-helpers'; - -import '@material/mwc-button'; -import '@material/mwc-dialog'; -import '@polymer/paper-spinner/paper-spinner-lite.js'; -import '@polymer/paper-progress/paper-progress.js'; -import '@material/mwc-icon'; +import { html, LitElement } from 'lit' +import { store } from '../../store' +import { connect } from 'pwa-helpers' +import { parentEpml } from '../show-plugin' +import { translate } from '../../../translate' +import { friendsViewStyles } from '../../styles/core-css' +import './add-friends-modal' +import './ChatSideNavHeads' +import '../../../../plugins/plugins/core/components/ChatSearchResults' +import '@material/mwc-button' +import '@material/mwc-dialog' +import '@material/mwc-icon' +import '@polymer/paper-spinner/paper-spinner-lite.js' +import '@polymer/paper-progress/paper-progress.js' import '@vaadin/icon' import '@vaadin/icons' -import '@vaadin/button'; -import './ChatSideNavHeads'; -import '../../../../plugins/plugins/core/components/ChatSearchResults' -import './add-friends-modal' - -import {translate,} from '../../../translate' -import {store} from '../../store'; -import {friendsViewStyles} from './friends-view-css'; -import {parentEpml} from '../show-plugin'; +import '@vaadin/button' class FriendsView extends connect(store)(LitElement) { static get properties() { @@ -29,94 +27,159 @@ class FriendsView extends connect(store)(LitElement) { setUserName: { attribute: false }, friendList: { type: Array }, userSelected: { type: Object }, - isLoading: {type: Boolean}, - userFoundModalOpen: {type: Boolean}, - userFound: { type: Array}, - isOpenAddFriendsModal: {type: Boolean}, - editContent: {type: Object}, - mySelectedFeeds: {type: Array}, - refreshFeed: {attribute: false}, - closeSidePanel: {attribute: false, type: Object}, - openSidePanel: {attribute:false, type: Object} - }; + isLoading: { type: Boolean }, + userFoundModalOpen: { type: Boolean }, + userFound: { type: Array }, + isOpenAddFriendsModal: { type: Boolean }, + editContent: { type: Object }, + mySelectedFeeds: { type: Array }, + refreshFeed: { attribute: false }, + closeSidePanel: { attribute: false, type: Object }, + openSidePanel: { attribute: false, type: Object } + } } + static get styles() { - return [friendsViewStyles]; + return [friendsViewStyles] } constructor() { - super(); - this.error = false; - this.observerHandler = this.observerHandler.bind(this); - this.viewElement = ''; - this.downObserverElement = ''; - this.myAddress = - window.parent.reduxStore.getState().app.selectedAddress.address; - this.errorMessage = ''; - this.successMessage = ''; - this.friendList = []; - this.userSelected = {}; - this.isLoading = false; + super() + this.error = false + this.observerHandler = this.observerHandler.bind(this) + this.viewElement = '' + this.downObserverElement = '' + this.myAddress = store.getState().app.selectedAddress.address + this.errorMessage = '' + this.successMessage = '' + this.friendList = [] + this.userSelected = {} + this.isLoading = false this.userFoundModalOpen = false - this.userFound = []; - this.nodeUrl = this.getNodeUrl(); - this.myNode = this.getMyNode(); + this.userFound = [] + this.nodeUrl = this.getNodeUrl() + this.myNode = this.getMyNode() this.isOpenAddFriendsModal = false this.editContent = null this.addToFriendList = this.addToFriendList.bind(this) this._updateFriends = this._updateFriends.bind(this) this._updateFeed = this._updateFeed.bind(this) this._addFriend = this._addFriend.bind(this) + } + render() { + return html` +
    +
    +

    My Friends

    +
    + { + if (e.key === 'Enter') { + this.userSearch() + } + }} + > + + +
    +
    + { + this.userSelected = result; + this.isOpenAddFriendsModal = true + this.userFound = []; + this.userFoundModalOpen = false; + }} + .closeFunc=${() => { + this.userFoundModalOpen = false; + this.userFound = []; + }} + .searchResults=${this.userFound} + ?isOpen=${this.userFoundModalOpen} + ?loading=${this.isLoading} + > + +
    + ${this.friendList.map((item) => { + return html` + { }} + .chatInfo=${item} + .openEditFriend=${(val) => this.openEditFriend(val)} + .closeSidePanel=${this.closeSidePanel} + > + + ` + })} +
    +
    +
    + { + this.isOpenAddFriendsModal = val + }} + .userSelected=${this.userSelected} + .onSubmit=${(val, isRemove) => this.addToFriendList(val, isRemove)} + .editContent=${this.editContent} + .onClose=${() => this.onClose()} + .mySelectedFeeds=${this.mySelectedFeeds} + > + + ` + } + + firstUpdated() { + this.viewElement = this.shadowRoot.getElementById('viewElement') + this.downObserverElement = this.shadowRoot.getElementById('downObserver') + this.elementObserver() + this.mySelectedFeeds = JSON.parse(localStorage.getItem('friends-my-selected-feeds') || "[]") + this.friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]") } getNodeUrl() { - const myNode = - store.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] - + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] return myNode.protocol + '://' + myNode.domain + ':' + myNode.port } + getMyNode() { - return store.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] + return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] } - getMoreFriends() {} - - firstUpdated() { - this.viewElement = this.shadowRoot.getElementById('viewElement'); - this.downObserverElement = - this.shadowRoot.getElementById('downObserver'); - this.elementObserver(); - this.mySelectedFeeds = JSON.parse(localStorage.getItem('friends-my-selected-feeds') || "[]") - this.friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]") - - - - - } + getMoreFriends() { } _updateFriends(event) { this.friendList = event.detail } + _updateFeed(event) { this.mySelectedFeeds = event.detail this.requestUpdate() } - _addFriend(event){ - const name = event.detail; - const findFriend = this.friendList.find((friend)=> friend.name === name) - if(findFriend){ - this.editContent = {...findFriend, mySelectedFeeds: this.mySelectedFeeds} - this.userSelected = findFriend; + _addFriend(event) { + const name = event.detail; + const findFriend = this.friendList.find((friend) => friend.name === name) + if (findFriend) { + this.editContent = { ...findFriend, mySelectedFeeds: this.mySelectedFeeds } + this.userSelected = findFriend } else { this.userSelected = { name - }; + } } this.isOpenAddFriendsModal = true @@ -134,7 +197,6 @@ class FriendsView extends connect(store)(LitElement) { window.removeEventListener('friends-my-friend-list-event', this._updateFriends) window.removeEventListener('friends-my-selected-feeds-event', this._updateFeed) window.removeEventListener('add-friend', this._addFriend) - super.disconnectedCallback() } @@ -142,18 +204,21 @@ class FriendsView extends connect(store)(LitElement) { const options = { root: this.viewElement, rootMargin: '0px', - threshold: 1, - }; + threshold: 1 + } + // identify an element to observe - const elementToObserve = this.downObserverElement; + const elementToObserve = this.downObserverElement + // passing it a callback function const observer = new IntersectionObserver( this.observerHandler, options - ); + ) + // call `observe()` on that MutationObserver instance, // passing it the element to observe, and the options object - observer.observe(elementToObserve); + observer.observe(elementToObserve) } observerHandler(entries) { @@ -163,112 +228,121 @@ class FriendsView extends connect(store)(LitElement) { if (this.friendList.length < 20) { return; } - this.getMoreFriends(); + + this.getMoreFriends() } } async userSearch() { const nameValue = this.shadowRoot.getElementById('sendTo').value - if(!nameValue) { + + if (!nameValue) { + this.userFound = [] + this.userFoundModalOpen = true + return; + } + + try { + const url = `${this.nodeUrl}/names/${nameValue}` + const res = await fetch(url) + const result = await res.json() + + if (result.error === 401) { this.userFound = [] - this.userFoundModalOpen = true - return; - } - try { - const url = `${this.nodeUrl}/names/${nameValue}` - const res = await fetch(url) - const result = await res.json() - if (result.error === 401) { - this.userFound = [] - } else { - this.userFound = [ - result - ]; - } - this.userFoundModalOpen = true; - } catch (error) { - // let err4string = get("chatpage.cchange35"); - // parentEpml.request('showSnackBar', `${err4string}`) + } else { + this.userFound = [ + result + ] } + + this.userFoundModalOpen = true; + } catch (error) { + // let err4string = get("chatpage.cchange35") + // parentEpml.request('showSnackBar', `${err4string}`) } + } - getApiKey() { - const apiNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - return apiNode.apiKey - } + async myFollowName(name) { + let items = [ + name + ] - async myFollowName(name) { - let items = [ - name - ] - let namesJsonString = JSON.stringify({ "items": items }) + let namesJsonString = JSON.stringify({ "items": items }) - return await parentEpml.request('apiCall', { - url: `/lists/followedNames?apiKey=${this.getApiKey()}`, - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: `${namesJsonString}` - }) - } + return await parentEpml.request('apiCall', { + url: `/lists/followedNames?apiKey=${this.getApiKey()}`, + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + } - async unFollowName(name) { - let items = [ - name - ] - let namesJsonString = JSON.stringify({ "items": items }) + async unFollowName(name) { + let items = [ + name + ] - return await parentEpml.request('apiCall', { - url: `/lists/followedNames?apiKey=${this.getApiKey()}`, - method: 'DELETE', - headers: { - 'Content-Type': 'application/json' - }, - body: `${namesJsonString}` - }) - } - async addToFriendList(val, isRemove){ - const copyVal = {...val} + let namesJsonString = JSON.stringify({ "items": items }) + + return await parentEpml.request('apiCall', { + url: `/lists/followedNames?apiKey=${this.getApiKey()}`, + method: 'DELETE', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + } + + async addToFriendList(val, isRemove) { + const copyVal = { ...val } delete copyVal.mySelectedFeeds - if(isRemove){ - this.friendList = this.friendList.filter((item)=> item.name !== copyVal.name) - }else if(this.editContent){ - const findFriend = this.friendList.findIndex(item=> item.name === copyVal.name) - if(findFriend !== -1){ + + if (isRemove) { + this.friendList = this.friendList.filter((item) => item.name !== copyVal.name) + } else if (this.editContent) { + const findFriend = this.friendList.findIndex(item => item.name === copyVal.name) + if (findFriend !== -1) { const copyList = [...this.friendList] copyList[findFriend] = copyVal this.friendList = copyList } - } else { this.friendList = [...this.friendList, copyVal] } - if(!copyVal.willFollow || isRemove) { + + if (!copyVal.willFollow || isRemove) { await this.unFollowName(copyVal.name) - } else if(copyVal.willFollow){ + } else if (copyVal.willFollow) { await this.myFollowName(copyVal.name) } + this.setMySelectedFeeds(val.mySelectedFeeds) - await new Promise((res)=> { - setTimeout(()=> { + + await new Promise((res) => { + setTimeout(() => { res() - },50) + }, 50) }) - this.userSelected = {}; + + this.userSelected = {} this.shadowRoot.getElementById('sendTo').value = '' - this.isLoading = false; + this.isLoading = false this.isOpenAddFriendsModal = false this.editContent = null this.setMyFriends(this.friendList) - if(!isRemove && this.friendList.length === 1){ + + if (!isRemove && this.friendList.length === 1) { this.refreshFeed() } } - setMyFriends(friendList){ + + setMyFriends(friendList) { localStorage.setItem('friends-my-friend-list', JSON.stringify(friendList)); - const tempSettingsData= JSON.parse(localStorage.getItem('temp-settings-data') || "{}") + const tempSettingsData = JSON.parse(localStorage.getItem('temp-settings-data') || "{}") const newTemp = { ...tempSettingsData, userLists: { @@ -277,18 +351,20 @@ class FriendsView extends connect(store)(LitElement) { } } - localStorage.setItem('temp-settings-data', JSON.stringify(newTemp)); + localStorage.setItem('temp-settings-data', JSON.stringify(newTemp)) + this.dispatchEvent( new CustomEvent('temp-settings-data-event', { - bubbles: true, - composed: true - }), - ); - + bubbles: true, + composed: true + }) + ) } - setMySelectedFeeds(mySelectedFeeds){ + + setMySelectedFeeds(mySelectedFeeds) { this.mySelectedFeeds = mySelectedFeeds - const tempSettingsData= JSON.parse(localStorage.getItem('temp-settings-data') || "{}") + const tempSettingsData = JSON.parse(localStorage.getItem('temp-settings-data') || "{}") + const newTemp = { ...tempSettingsData, friendsFeed: { @@ -297,98 +373,37 @@ class FriendsView extends connect(store)(LitElement) { } } - localStorage.setItem('temp-settings-data', JSON.stringify(newTemp)); - localStorage.setItem('friends-my-selected-feeds', JSON.stringify(mySelectedFeeds)); - } - openEditFriend(val){ - this.isOpenAddFriendsModal = true - this.userSelected = val - this.editContent = {...val, mySelectedFeeds: this.mySelectedFeeds} + localStorage.setItem('temp-settings-data', JSON.stringify(newTemp)) + localStorage.setItem('friends-my-selected-feeds', JSON.stringify(mySelectedFeeds)) } - onClose(){ + openEditFriend(val) { + this.isOpenAddFriendsModal = true + this.userSelected = val + this.editContent = { ...val, mySelectedFeeds: this.mySelectedFeeds } + } + + onClose() { this.isLoading = false; this.isOpenAddFriendsModal = false this.editContent = null this.userSelected = {} } - render() { - return html` -
    -
    -

    My Friends

    -
    - { - if(e.key === 'Enter'){ - this.userSearch() - } - }} - /> + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } - - + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } -
    -
    - { - this.userSelected = result; - this.isOpenAddFriendsModal = true - - this.userFound = []; - this.userFoundModalOpen = false; - }} - .closeFunc=${() => { - this.userFoundModalOpen = false; - this.userFound = []; - }} - .searchResults=${this.userFound} - ?isOpen=${this.userFoundModalOpen} - ?loading=${this.isLoading}> - -
    - - - ${this.friendList.map((item) => { - return html` { - - }} - .chatInfo=${item} - .openEditFriend=${(val)=> this.openEditFriend(val)} - .closeSidePanel=${this.closeSidePanel} - >`; - })} -
    -
    -
    - { - this.isOpenAddFriendsModal = val - }} - .userSelected=${this.userSelected} - .onSubmit=${(val, isRemove)=> this.addToFriendList(val, isRemove)} - .editContent=${this.editContent} - .onClose=${()=> this.onClose()} - .mySelectedFeeds=${this.mySelectedFeeds} - > - - `; + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } } -customElements.define('friends-view', FriendsView); +window.customElements.define('friends-view', FriendsView) \ No newline at end of file diff --git a/core/src/components/friends-view/profile-modal-update.js b/core/src/components/friends-view/profile-modal-update.js index 8e1418bf..9f84c738 100644 --- a/core/src/components/friends-view/profile-modal-update.js +++ b/core/src/components/friends-view/profile-modal-update.js @@ -1,14 +1,15 @@ -import {css, html, LitElement} from 'lit'; -import {get, translate} from '../../../translate' -import '@material/mwc-button'; -import '@material/mwc-icon'; -import '@vaadin/tooltip'; -import '@material/mwc-dialog'; -import '@material/mwc-checkbox'; -import {connect} from 'pwa-helpers'; -import {store} from '../../store'; -import '@polymer/paper-spinner/paper-spinner-lite.js'; -import {parentEpml} from '../show-plugin'; +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { parentEpml } from '../show-plugin' +import { get, translate } from '../../../translate' +import { profileModalUpdateStyles } from '../../styles/core-css' +import '@material/mwc-button' +import '@material/mwc-checkbox' +import '@material/mwc-dialog' +import '@material/mwc-icon' +import '@polymer/paper-spinner/paper-spinner-lite.js' +import '@vaadin/tooltip' class ProfileModalUpdate extends connect(store)(LitElement) { static get properties() { @@ -25,420 +26,57 @@ class ProfileModalUpdate extends connect(store)(LitElement) { hasFetchedArrr: { type: Boolean }, isOpenCustomDataModal: { type: Boolean }, customData: { type: Object }, - newCustomDataField: {type: Object}, - newFieldName: {type: String}, - qortalRequestCustomData: {type: Object}, - newCustomDataKey: {type: String}, - newCustomDataValue: {type: String}, - isSaving: {type: Boolean} - }; + newCustomDataField: { type: Object }, + newFieldName: { type: String }, + qortalRequestCustomData: { type: Object }, + newCustomDataKey: { type: String }, + newCustomDataValue: { type: String }, + isSaving: { type: Boolean } + } + } + + static get styles() { + return [profileModalUpdateStyles] } constructor() { super(); - this.isOpen = false; - this.isLoading = false; - this.nodeUrl = this.getNodeUrl(); - this.myNode = this.getMyNode(); - this.tagline = ''; - this.bio = ''; - this.walletList = ['btc', 'ltc', 'doge', 'dgb', 'rvn', 'arrr']; - let wallets = {}; + this.isOpen = false + this.isLoading = false + this.nodeUrl = this.getNodeUrl() + this.myNode = this.getMyNode() + this.tagline = '' + this.bio = '' + this.walletList = ['btc', 'ltc', 'doge', 'dgb', 'rvn', 'arrr'] + let wallets = {} this.walletList.forEach((item) => { - wallets[item] = ''; - }); - this.wallets = wallets; - this.walletsUi = new Map(); + wallets[item] = '' + }) + this.wallets = wallets + this.walletsUi = new Map() let coinProp = { - wallet: null, - }; - + wallet: null + } this.walletList.forEach((c, i) => { - this.walletsUi.set(c, { ...coinProp }); - }); - this.walletsUi.get('btc').wallet = - window.parent.reduxStore.getState().app.selectedAddress.btcWallet; - this.walletsUi.get('ltc').wallet = - window.parent.reduxStore.getState().app.selectedAddress.ltcWallet; - this.walletsUi.get('doge').wallet = - window.parent.reduxStore.getState().app.selectedAddress.dogeWallet; - this.walletsUi.get('dgb').wallet = - window.parent.reduxStore.getState().app.selectedAddress.dgbWallet; - this.walletsUi.get('rvn').wallet = - window.parent.reduxStore.getState().app.selectedAddress.rvnWallet; - this.hasFetchedArrr = false; - this.isOpenCustomDataModal = false; - this.customData = {}; - this.newCustomDataKey = ""; - this.newCustomDataValue = ""; - this.newCustomDataField = {}; - this.newFieldName = ''; - this.isSaving = false; - this.addPrivate = this.addPrivate.bind(this); - this.checkForPrivate = this.checkForPrivate.bind(this); - } - - static get styles() { - return css` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --mdc-theme-surface: var(--white); - --mdc-dialog-content-ink-color: var(--black); - --mdc-dialog-min-width: 400px; - --mdc-dialog-max-width: 1024px; - box-sizing: border-box; - } - .input { - width: 90%; - outline: 0; - border-width: 0 0 2px; - border-color: var(--mdc-theme-primary); - background-color: transparent; - padding: 10px; - font-family: Roboto, sans-serif; - font-size: 15px; - color: var(--chat-bubble-msg-color); - box-sizing: border-box; - } - .input::selection { - background-color: var(--mdc-theme-primary); - color: white; - } - - .input::placeholder { - opacity: 0.6; - color: var(--black); - } - - .modal-button { - font-family: Roboto, sans-serif; - font-size: 16px; - color: var(--mdc-theme-primary); - background-color: transparent; - padding: 8px 10px; - border-radius: 5px; - border: none; - transition: all 0.3s ease-in-out; - } - - .modal-button-red { - font-family: Roboto, sans-serif; - font-size: 16px; - color: #f44336; - background-color: transparent; - padding: 8px 10px; - border-radius: 5px; - border: none; - transition: all 0.3s ease-in-out; - } - - .modal-button-red:hover { - cursor: pointer; - background-color: #f4433663; - } - - .modal-button:hover { - cursor: pointer; - background-color: #03a8f475; - } - .checkbox-row { - position: relative; - display: flex; - align-items: center; - align-content: center; - font-family: Montserrat, sans-serif; - font-weight: 600; - color: var(--black); - } - .modal-overlay { - display: block; - position: fixed; - top: 0; - left: 0; - width: 100vw; - height: 100vh; - background-color: rgba( - 0, - 0, - 0, - 0.5 - ); /* Semi-transparent backdrop */ - z-index: 1000; - } - - .modal-content { - position: fixed; - top: 50vh; - left: 50vw; - transform: translate(-50%, -50%); - background-color: var(--mdc-theme-surface); - width: 80vw; - padding: 20px; - box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 6px; - z-index: 1001; - border-radius: 5px; - display: flex; - flex-direction: column; - } - - .modal-overlay.hidden { - display: none; - } - - .avatar { - width: 36px; - height: 36px; - display: flex; - align-items: center; - } - - .app-name { - display: flex; - gap: 20px; - align-items: center; - width: 100%; - cursor: pointer; - padding: 5px; - border-radius: 5px; - margin-bottom: 10px; - } - .inner-content { - display: flex; - flex-direction: column; - max-height: 75vh; - flex-grow: 1; - overflow: auto; - } - - .inner-content::-webkit-scrollbar-track { - background-color: whitesmoke; - border-radius: 7px; - } - - .inner-content::-webkit-scrollbar { - width: 12px; - border-radius: 7px; - background-color: whitesmoke; - } - - .inner-content::-webkit-scrollbar-thumb { - background-color: rgb(180, 176, 176); - border-radius: 7px; - transition: all 0.3s ease-in-out; - } - - .checkbox-row { - position: relative; - display: flex; - align-items: center; - align-content: center; - font-family: Montserrat, sans-serif; - font-weight: 600; - color: var(--black); - } - `; - } - - async updated(changedProperties) { - if ( - changedProperties && - changedProperties.has('editContent') && - this.editContent - ) { - const {bio, tagline, wallets, customData} = this.editContent - this.bio = bio ?? ''; - this.tagline = tagline ?? ''; - let formWallets = {...this.wallets} - if(wallets && Object.keys(wallets).length){ - Object.keys(formWallets).forEach((key)=> { - if(wallets[key]){ - formWallets[key] = wallets[key] - } - }) - } - this.wallets = formWallets - - this.customData = {...customData} - this.requestUpdate(); - } - if ( - changedProperties && - changedProperties.has('qortalRequestCustomData') && - this.qortalRequestCustomData - ) { - this.isOpenCustomDataModal = true - this.newCustomDataField = {...this.qortalRequestCustomData.payload.customData} - this.newCustomDataKey = this.qortalRequestCustomData.property - this.requestUpdate(); - } - - - } - - async firstUpdated() { - try { - await this.fetchWalletAddress('arrr'); - } catch (error) { - console.log({ error }); - } finally { - } - } - - async fetchWalletAddress(coin) { - switch (coin) { - case 'arrr': - const arrrWalletName = `${coin}Wallet`; - - let res = await parentEpml.request('apiCall', { - url: `/crosschain/${coin}/walletaddress?apiKey=${this.myNode.apiKey}`, - method: 'POST', - body: `${ - window.parent.reduxStore.getState().app.selectedAddress[ - arrrWalletName - ].seed58 - }`, - }); - if (res != null && res.error != 1201 && res.length === 78) { - this.arrrWalletAddress = res; - this.hasFetchedArrr = true; - } - break; - - default: - // Not used for other coins yet - break; - } - } - - async getSelectedWalletAddress(wallet) { - switch (wallet) { - case 'arrr': - if(!this.arrrWalletAddress){ - try { - await this.fetchWalletAddress('arrr'); - } catch (error) { - console.log({error}) - } - } - // Use address returned by core API - return this.arrrWalletAddress; - - default: - // Use locally derived address - return this.walletsUi.get(wallet).wallet.address; - } - } - - getNodeUrl() { - const myNode = - store.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] - - return myNode.protocol + '://' + myNode.domain + ':' + myNode.port - } - getMyNode() { - return store.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] - } - - clearFields() { - this.bio = ''; - this.tagline = ''; - } - - async fillAddress(coin) { - const address = await this.getSelectedWalletAddress(coin); - if (address) { - this.wallets = { - ...this.wallets, - [coin]: address, - }; - } - } - - async saveProfile() { - try { - const data = { - version: 1, - tagline: this.tagline, - bio: this.bio, - wallets: this.wallets, - customData: this.customData - }; - this.isSaving = true - await this.onSubmit(data); - this.setIsOpen(false); - this.clearFields(); - this.onClose('success'); - } catch (error) {} finally { - this.isSaving = false - } - } - - removeField(key){ - const copyObj = {...this.newCustomDataField} - delete copyObj[key] - this.newCustomDataField = copyObj - } - - addField(){ - if (!this.newFieldName || !this.newCustomDataValue) { - let snack5string = get("profile.profile24"); - parentEpml.request('showSnackBar', `${snack5string}`); - return; - } - const copyObj = {...this.newCustomDataField} - copyObj[this.newFieldName] = this.newCustomDataValue - this.newCustomDataField = copyObj - this.newFieldName = "" - this.newCustomDataValue = "" - } - - addCustomData(){ - const copyObj = {...this.customData} - copyObj[this.newCustomDataKey] = this.newCustomDataField - this.customData = copyObj + this.walletsUi.set(c, { ...coinProp }) + }) + this.walletsUi.get('btc').wallet = store.getState().app.selectedAddress.btcWallet + this.walletsUi.get('ltc').wallet = store.getState().app.selectedAddress.ltcWallet + this.walletsUi.get('doge').wallet = store.getState().app.selectedAddress.dogeWallet + this.walletsUi.get('dgb').wallet = store.getState().app.selectedAddress.dgbWallet + this.walletsUi.get('rvn').wallet = store.getState().app.selectedAddress.rvnWallet + this.hasFetchedArrr = false + this.isOpenCustomDataModal = false + this.customData = {} this.newCustomDataKey = "" - this.newCustomDataField = {}; + this.newCustomDataValue = "" + this.newCustomDataField = {} this.newFieldName = '' - this.newCustomDataValue = '' - this.isOpenCustomDataModal = false; + this.isSaving = false + this.addPrivate = this.addPrivate.bind(this) + this.checkForPrivate = this.checkForPrivate.bind(this) } - updateCustomData(key, data){ - this.isOpenCustomDataModal = true - this.newCustomDataField = data - this.newCustomDataKey = key - - } - - removeCustomData(key){ - const copyObj = {...this.customData} - delete copyObj[key] - this.customData = copyObj - } - - checkForPrivate(){ - let isPrivate = false - if(this.newCustomDataKey.includes('-private')) isPrivate = true - return isPrivate - } - - addPrivate(e){ - if (e.target.checked) { - if(this.newCustomDataKey.includes('-private')){ - - } else { - this.newCustomDataKey = this.newCustomDataKey + '-private' - } - } else { - this.newCustomDataKey = this.newCustomDataKey.replace('-private', ''); - } - } - render() { return html` @@ -277,13 +165,14 @@ class Chat extends LitElement { { - this.resetChatEditor() - this.openPrivateMessage = false - this.shadowRoot.getElementById('sendTo').value = "" + this.resetChatEditor(); + this.openPrivateMessage = false; + this.shadowRoot.getElementById('sendTo').value = ''; this.userFoundModalOpen = false; - this.userFound = [] + this.userFound = []; }} - style=${this.openPrivateMessage ? "visibility:visible;z-index:50" : "visibility: hidden;z-index:-100;position: relative"}> + style=${this.openPrivateMessage ? "visibility:visible;z-index:50" : "visibility: hidden;z-index:-100;position: relative"} + >
    @@ -298,32 +187,24 @@ class Chat extends LitElement { ?disabled=${this.isLoading} id="sendTo" placeholder="${translate("chatpage.cchange7")}" - value=${this.userSelected.name ? this.userSelected.name: ''} + value=${this.userSelected.name ? this.userSelected.name : ''} @keypress=${() => { - this.userSelected = {} + this.userSelected = {}; this.requestUpdate() }} /> - ${this.userSelected.name ? ( - html` + ${this.userSelected.name ? + (html`
    -

    ${translate("chatpage.cchange38")}

    +

    ${translate("chatpage.cchange38")}

    - ` - ) : ( - html` - - - ` - )} + `) + : (html` + + `) + }
    - this.updatePlaceholder(editor, value)} + .updatePlaceholder=${(editor, value) => this.updatePlaceholder(editor, value)} > - @@ -365,13 +245,13 @@ class Chat extends LitElement {
    { - this.userSelected = result + this.userSelected = result; this.userFound = []; - this.userFoundModalOpen = false + this.userFoundModalOpen = false; }} .closeFunc=${() => { - this.userFoundModalOpen = false - this.userFound = [] + this.userFoundModalOpen = false; + this.userFound = []; }} .searchResults=${this.userFound} ?isOpen=${this.userFoundModalOpen} @@ -381,7 +261,6 @@ class Chat extends LitElement {
    -
    @@ -392,26 +271,20 @@ class Chat extends LitElement { { if (data.item.name === "No registered name") { - render(html`${translate("chatpage.cchange15")}`, root) + render(html`${translate("chatpage.cchange15")}`, root); } else { - render(html`${data.item.name}`, root) + render(html`${data.item.name}`, root); } }}> { - render(html`${this.renderUnblockButton(data.item)}`, root) + render(html`${this.renderUnblockButton(data.item)}`, root); }}> - ${this.isEmptyArray(this.blockedUserList) ? html` - ${translate("chatpage.cchange14")} - `: ''} - + ${this.isEmptyArray(this.blockedUserList) ? html`${translate("chatpage.cchange14")}`: ''} + ${translate("general.close")} @@ -425,9 +298,12 @@ class Chat extends LitElement { this.getLocalBlockedList() const getBlockedUsers = async () => { - this.blockedUsers = await parentEpml.request('apiCall', { + let blockedUsers = await parentEpml.request('apiCall', { url: `/lists/blockedAddresses?apiKey=${this.getApiKey()}` }) + + this.blockedUsers = blockedUsers + setTimeout(getBlockedUsers, 60000) } @@ -442,14 +318,12 @@ class Chat extends LitElement { this.shadowRoot.getElementById('messageBox').addEventListener('keydown', stopKeyEventPropagation) - const runFunctionsAfterPageLoad = () => { + const runFunctionsAfterPageLoad = async () => { // Functions to exec after render while waiting for page info... - // getDataFromURL() - try { let key = `${window.parent.reduxStore.getState().app.selectedAddress.address.substr(0, 10)}_chat-heads` let localChatHeads = localStorage.getItem(key) - this.setChatHeads(JSON.parse(localChatHeads)) + await this.setChatHeads(JSON.parse(localChatHeads)) } catch (e) { // TODO: Could add error handling in case there's a weird one... (-_-) return @@ -458,6 +332,7 @@ class Chat extends LitElement { // Clear Interval... if (this.selectedAddress.address !== undefined) { clearInterval(runFunctionsAfterPageLoadInterval) + return } } @@ -471,13 +346,17 @@ class Chat extends LitElement { } else { this.theme = 'light' } + document.querySelector('html').setAttribute('theme', this.theme) }) - if (!isElectron()) { /* empty */ } else { + if (!isElectron()) { + // ... + } else { window.addEventListener('contextmenu', (event) => { // Check if the clicked element has the class let target = event.target + while (target !== null) { if (target.classList && target.classList.contains('customContextMenuDiv')) { // Your custom context menu logic @@ -496,7 +375,6 @@ class Chat extends LitElement { let configLoaded = false parentEpml.ready().then(() => { - parentEpml.subscribe('config', c => { if (!configLoaded) { setTimeout(getBlockedUsers, 1) @@ -504,18 +382,20 @@ class Chat extends LitElement { } this.config = JSON.parse(c) }) + parentEpml.subscribe('chat_heads', chatHeads => { chatHeads = JSON.parse(chatHeads) this.getChatHeadFromState(chatHeads) }) + parentEpml.subscribe('side_effect_action', async sideEffectActionParam => { const sideEffectAction = JSON.parse(sideEffectActionParam) - if(sideEffectAction && sideEffectAction.type === 'openPrivateChat') { + if (sideEffectAction && sideEffectAction.type === 'openPrivateChat') { const name = sideEffectAction.data.name const address = sideEffectAction.data.address - if(this.chatHeadsObj.direct && this.chatHeadsObj.direct.find(item=> item.address === address)){ - await this.setActiveChatHeadUrl(`direct/${address}`) + if (this.chatHeadsObj.direct && this.chatHeadsObj.direct.find(item => item.address === address)) { + this.setActiveChatHeadUrl(`direct/${address}`) window.parent.reduxStore.dispatch( window.parent.reduxAction.setSideEffectAction(null)) } else { @@ -526,9 +406,9 @@ class Chat extends LitElement { window.parent.reduxStore.dispatch( window.parent.reduxAction.setSideEffectAction(null)) } - } }) + parentEpml.request('apiCall', { url: `/addresses/balance/${window.parent.reduxStore.getState().app.selectedAddress.address}` }).then(res => { @@ -536,48 +416,174 @@ class Chat extends LitElement { this.requestUpdate() }) }) + parentEpml.imReady() + this.clearConsole() + setInterval(() => { this.clearConsole() }, 60000) } + async setActiveChatHeadUrl(url) { + this.activeChatHeadUrl = url + this.requestUpdate() + } + + resetChatEditor() { + this.editor.commands.setContent('') + } + + async getUpdateCompleteTextEditor() { + await super.getUpdateComplete() + const marginElements = Array.from(this.shadowRoot.querySelectorAll('chat-text-editor')) + await Promise.all(marginElements.map(el => el.updateComplete)) + const marginElements2 = Array.from(this.shadowRoot.querySelectorAll('wrapper-modal')) + await Promise.all(marginElements2.map(el => el.updateComplete)) + return true + } + + async connectedCallback() { + super.connectedCallback() + + await this.getUpdateCompleteTextEditor() + + const elementChatId = this.shadowRoot.getElementById('messageBox').shadowRoot.getElementById('privateMessage') + this.editor = new Editor({ + onUpdate: () => { + this.shadowRoot.getElementById('messageBox').getMessageSize(this.editor.getJSON()) + }, + element: elementChatId, + extensions: [ + StarterKit, + Underline, + Highlight, + Placeholder.configure({ + placeholder: 'Write something …' + }), + Extension.create({ + addKeyboardShortcuts: () => { + return { + 'Enter': () => { + const chatTextEditor = this.shadowRoot.getElementById('messageBox') + chatTextEditor.sendMessageFunc({ }) + return true + } + } + } + }) + ] + }) + + this.unsubscribeStore = window.parent.reduxStore.subscribe(() => { + try { + const currentState = window.parent.reduxStore.getState() + + if (window.parent.location && window.parent.location.search) { + const queryString = window.parent.location.search + const params = new URLSearchParams(queryString) + const chat = params.get("chat") + if (chat && chat !== this.activeChatHeadUrl) { + let url = window.parent.location.href + let newUrl = url.split("?")[0] + window.parent.history.pushState({}, "", newUrl) + this.setActiveChatHeadUrl(chat) + } + } + + if (currentState.app.accountInfo && currentState.app.accountInfo.names && currentState.app.accountInfo.names.length > 0 && this.loggedInUserName !== currentState.app.accountInfo.names[0].name) { + this.loggedInUserName = currentState.app.accountInfo.names[0].name + } + + if (currentState.app.accountInfo && currentState.app.accountInfo.addressInfo && currentState.app.accountInfo.addressInfo.address && this.loggedInUserAddress !== currentState.app.accountInfo.addressInfo.address) { + this.loggedInUserAddress = currentState.app.accountInfo.addressInfo.address + } + } catch (error) { /* empty */ } + }) + } + + disconnectedCallback() { + super.disconnectedCallback() + this.editor.destroy() + this.unsubscribeStore() + } + + updatePlaceholder(editor, text) { + editor.extensionManager.extensions.forEach((extension) => { + if (extension.name === 'placeholder') { + extension.options['placeholder'] = text + editor.commands.focus('end') + } + }) + } + + setOpenDialogGroupsModal(val) { + this.openDialogGroupsModal = val + } + + openTabToGroupManagement() { + window.parent.reduxStore.dispatch( + window.parent.reduxAction.setNewTab({ + url: `group-management`, + id: this.uid.rnd(), + myPlugObj: { + 'url': 'group-management', + 'domain': 'core', + 'page': 'group-management/index.html', + 'title': 'Group Management', + 'icon': 'vaadin:group', + 'mwcicon': 'group', + 'pluginNumber': 'plugin-fJZNpyLGTl', + 'menus': [], + 'parent': false + }, + openExisting: true + }) + ) + } + clearConsole() { - if (!isElectron()) { /* empty */ } else { + if (!isElectron()) { + // ... + } else { console.clear() window.parent.electronAPI.clearCache() } } setOpenPrivateMessage(props) { - this.openPrivateMessage = props.open; - this.shadowRoot.getElementById("sendTo").value = props.name + this.openPrivateMessage = props.open + this.shadowRoot.getElementById('sendTo').value = props.name } async userSearch() { const nameValue = this.shadowRoot.getElementById('sendTo').value - if(!nameValue) { + + if (!nameValue) { this.userFound = [] this.userFoundModalOpen = true return } + try { const result = await parentEpml.request('apiCall', { type: 'api', url: `/names/${nameValue}` }) + if (result.error === 401) { this.userFound = [] } else { this.userFound = [ ...this.userFound, - result, - ]; + result + ] } - this.userFoundModalOpen = true; + + this.userFoundModalOpen = true } catch (error) { - let err4string = get("chatpage.cchange35"); + let err4string = get('chatpage.cchange35') parentEpml.request('showSnackBar', `${err4string}`) } } @@ -587,9 +593,10 @@ class Chat extends LitElement { } async _sendMessage(outSideMsg, msg) { - this.isLoading = true; + this.isLoading = true const trimmedMessage = msg + if (/^\s*$/.test(trimmedMessage)) { this.isLoading = false } else { @@ -600,7 +607,7 @@ class Chat extends LitElement { version: 3 } const stringifyMessageObject = JSON.stringify(messageObject) - await this.sendMessage(stringifyMessageObject) + this.sendMessage(stringifyMessageObject) } } @@ -617,19 +624,22 @@ class Chat extends LitElement { let myNameRes = await parentEpml.request('apiCall', { type: 'api', url: `/names/${receiverName}` - }); + }) + if (myNameRes.error === 401) { - myRes = false; + myRes = false } else { myRes = myNameRes } - return myRes; + + return myRes } catch (error) { - return "" + return '' } } const myNameRes = await validateName(_recipient) + if (!myNameRes) { recipient = _recipient } else { @@ -637,8 +647,8 @@ class Chat extends LitElement { } const getAddressPublicKey = async () => { - let isEncrypted; - let _publicKey; + let isEncrypted + let _publicKey let addressPublicKey = await parentEpml.request('apiCall', { type: 'api', @@ -647,22 +657,26 @@ class Chat extends LitElement { if (addressPublicKey.error === 102) { _publicKey = false - let err4string = get("chatpage.cchange19") + let err4string = get('chatpage.cchange19') parentEpml.request('showSnackBar', `${err4string}`) this.isLoading = false } else if (addressPublicKey !== false) { isEncrypted = 1 _publicKey = addressPublicKey - await sendMessageRequest(isEncrypted, _publicKey) + sendMessageRequest(isEncrypted, _publicKey) } else { - let err4string = get("chatpage.cchange39") + let err4string = get('chatpage.cchange39') parentEpml.request('showSnackBar', `${err4string}`) this.isLoading = false } } + let _reference = new Uint8Array(64) - window.crypto.getRandomValues(_reference); + + window.crypto.getRandomValues(_reference) + let reference = window.parent.Base58.encode(_reference) + const sendMessageRequest = async (isEncrypted, _publicKey) => { let chatResponse = await parentEpml.request('chat', { type: 18, @@ -679,17 +693,20 @@ class Chat extends LitElement { isText: 1 } }) - await _computePow(chatResponse) + + _computePow(chatResponse) } const _computePow = async (chatBytes) => { const difficulty = this.balance < 4 ? 18 : 8 const path = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full' const worker = new WebWorker() + let nonce = null let chatBytesArray = null + await new Promise((res) => { - worker.postMessage({chatBytes, path, difficulty}) + worker.postMessage({ chatBytes, path, difficulty }) worker.onmessage = e => { worker.terminate() chatBytesArray = e.data.chatBytesArray @@ -703,26 +720,27 @@ class Chat extends LitElement { chatBytesArray: chatBytesArray, chatNonce: nonce }) + getSendChatResponse(_response) } const getSendChatResponse = (response) => { if (response === true) { this.setActiveChatHeadUrl(`direct/${recipient}`) - this.shadowRoot.getElementById('sendTo').value = "" + this.shadowRoot.getElementById('sendTo').value = '' this.openPrivateMessage = false - this.resetChatEditor(); + this.resetChatEditor() } else if (response.error) { parentEpml.request('showSnackBar', response.message) } else { - let err2string = get("chatpage.cchange21") + let err2string = get('chatpage.cchange21') parentEpml.request('showSnackBar', `${err2string}`) } this.isLoading = false } - // Exec.. - await getAddressPublicKey() + + getAddressPublicKey() } insertImage(file) { @@ -730,7 +748,8 @@ class Chat extends LitElement { this.imageFile = file return } - parentEpml.request('showSnackBar', get("chatpage.cchange28")) + + parentEpml.request('showSnackBar', get('chatpage.cchange28')) } renderLoadingText() { @@ -738,12 +757,12 @@ class Chat extends LitElement { } renderSendText() { - return html`${translate("chatpage.cchange9")}` + return html`${translate('chatpage.cchange9')}` } relMessages() { setTimeout(() => { - window.location.href = window.location.href.split( '#' )[0] + window.location.href = window.location.href.split('#')[0] }, 500) } @@ -752,7 +771,7 @@ class Chat extends LitElement { const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port const blockedAddressesUrl = `${nodeUrl}/lists/blockedAddresses?apiKey=${this.getApiKey()}` - localStorage.removeItem("MessageBlockedAddresses") + localStorage.removeItem('MessageBlockedAddresses') var hidelist = [] @@ -762,7 +781,8 @@ class Chat extends LitElement { data.map(item => { hidelist.push(item) }) - localStorage.setItem("MessageBlockedAddresses", JSON.stringify(hidelist)) + + localStorage.setItem('MessageBlockedAddresses', JSON.stringify(hidelist)) this.blockedUserList = hidelist }) @@ -774,7 +794,7 @@ class Chat extends LitElement { const blockedAddressesUrl = `${nodeUrl}/lists/blockedAddresses?apiKey=${this.getApiKey()}` const err1string = 'No registered name' - localStorage.removeItem("ChatBlockedAddresses") + localStorage.removeItem('ChatBlockedAddresses') var obj = [] @@ -786,18 +806,21 @@ class Chat extends LitElement { name: err1string, owner: item } + fetch(`${nodeUrl}/names/address/${item}?limit=0&reverse=true`).then(res => { return res.json() }).then(jsonRes => { - if(jsonRes.length) { - jsonRes.map (item => { + if (jsonRes.length) { + jsonRes.map(item => { obj.push(item) }) } else { obj.push(noName) } - localStorage.setItem("ChatBlockedAddresses", JSON.stringify(obj)) - this.blockedUserList = JSON.parse(localStorage.getItem("ChatBlockedAddresses") || "[]") + + localStorage.setItem('ChatBlockedAddresses', JSON.stringify(obj)) + + this.blockedUserList = JSON.parse(localStorage.getItem('ChatBlockedAddresses') || '[]') }) }) }) @@ -805,12 +828,14 @@ class Chat extends LitElement { async getPendingGroupInvites() { const myAddress = window.parent.reduxStore.getState().app.selectedAddress.address + try { - this.groupInvites = await parentEpml.request('apiCall', { + let pendingGroupInvites = await parentEpml.request('apiCall', { url: `/groups/invites/${myAddress}` - }); + }) + this.groupInvites = pendingGroupInvites } catch (error) { - let err4string = get("chatpage.cchange61"); + let err4string = get('chatpage.cchange61') parentEpml.request('showSnackBar', `${err4string}`) } } @@ -822,7 +847,7 @@ class Chat extends LitElement { owner ] - let ownersJsonString = JSON.stringify({ "items": items }) + let ownersJsonString = JSON.stringify({ 'items': items }) let ret = await parentEpml.request('apiCall', { url: `/lists/blockedAddresses?apiKey=${this.getApiKey()}`, @@ -836,26 +861,26 @@ class Chat extends LitElement { if (ret === true) { this.blockedUsers = this.blockedUsers.filter(item => item != owner) this.getChatBlockedList() - this.blockedUserList = JSON.parse(localStorage.getItem("ChatBlockedAddresses") || "[]") - let err2string = get("chatpage.cchange16") + this.blockedUserList = JSON.parse(localStorage.getItem('ChatBlockedAddresses') || '[]') + let err2string = get('chatpage.cchange16') snackbar.add({ labelText: `${err2string}`, dismiss: true }) this.relMessages() - } - else { - let err3string = get("chatpage.cchange17") + } else { + let err3string = get('chatpage.cchange17') snackbar.add({ labelText: `${err3string}`, dismiss: true }) } + return ret } renderUnblockButton(websiteObj) { - return html`` + return html`` } changeTheme() { @@ -874,20 +899,21 @@ class Chat extends LitElement { myAddress=${JSON.stringify(this.selectedAddress)} .setOpenPrivateMessage=${(val) => this.setOpenPrivateMessage(val)} > - ` + + ` } renderChatHead(chatHeadArr) { return chatHeadArr.map(eachChatHead => { - return html` this.setActiveChatHeadUrl(val)} chatInfo=${JSON.stringify(eachChatHead)}>` + return html` this.setActiveChatHeadUrl(val)} chatInfo=${JSON.stringify(eachChatHead)}>` }) } renderChatPage() { // Check for the chat ID from and render chat messages // Else render Welcome to Q-CHat - // TODO: DONE: Do the above in the ChatPage + return html` this.setOpenPrivateMessage(val)} - .setActiveChatHeadUrl=${(val)=> this.setActiveChatHeadUrl(val)} + .setActiveChatHeadUrl=${(val) => this.setActiveChatHeadUrl(val)} balance=${this.balance} loggedInUserName=${this.loggedInUserName} loggedInUserAddress=${this.loggedInUserAddress} @@ -905,16 +931,48 @@ class Chat extends LitElement { ` } - setChatHeads(chatObj) { - const chatObjGroups = Array.isArray(chatObj.groups) ? chatObj.groups : [] + async getOwnerName(newGroupId) { + try { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + + const response = await fetch(`${nodeUrl}/groups/${newGroupId}`) + const data = await response.json() + + const res = await fetch(`${nodeUrl}/names/address/${data.owner}?limit=0&reverse=true`) + const jsonRes = await res.json() + + let goName = 'undefined' + + if (jsonRes.length) { + jsonRes.forEach(item => { + goName = item.name + }) + } + + return goName + } catch (error) { + console.error('Error fetching name', error) + throw error + } + } + + async setChatHeads(chatObj) { + const chatObjGroups = Array.isArray(chatObj.groups) ? chatObj.groups : [] const chatObjDirect = Array.isArray(chatObj.direct) ? chatObj.direct : [] - let groupList = chatObjGroups.map(group => group.groupId === 0 ? { - groupId: group.groupId, url: `group/${group.groupId}`, - groupName: "Qortal General Chat", + let groupList = await Promise.all(chatObjGroups.map(async group => group.groupId === 0 ? { + groupId: group.groupId, + url: `group/${group.groupId}`, + groupName: 'Qortal General Chat', timestamp: group.timestamp === undefined ? 2 : group.timestamp, - sender: group.sender } : { ...group, timestamp: group.timestamp === undefined ? 1 : group.timestamp, url: `group/${group.groupId}` - }) + sender: group.sender + } : { + ...group, + timestamp: group.timestamp === undefined ? 1 : group.timestamp, + url: `group/${group.groupId}`, + ownerName: group.ownerName === undefined ? await this.getOwnerName(group.groupId) : 'undefined' + })) let directList = chatObjDirect.map(dc => { return { ...dc, url: `direct/${dc.address}` } @@ -925,6 +983,7 @@ class Chat extends LitElement { } groupList.sort(compareNames) + let chatHeadMasterList = [...groupList, ...directList] const compareArgs = (a, b) => { @@ -934,12 +993,12 @@ class Chat extends LitElement { this.chatHeads = chatHeadMasterList.sort(compareArgs) } - getChatHeadFromState(chatObj) { + async getChatHeadFromState(chatObj) { if (chatObj === undefined) { - + return } else { this.chatHeadsObj = chatObj - this.setChatHeads(chatObj) + await this.setChatHeads(chatObj) } } @@ -951,23 +1010,13 @@ class Chat extends LitElement { parentEpml.request('setPageUrl', pageUrl) } - isEmptyArray(arr) { - if (!arr) { return true } - return arr.length === 0 - } - - getApiKey() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - return myNode.apiKey - } - scrollToBottom() { const viewElement = this.shadowRoot.querySelector('chat-page').shadowRoot.querySelector('chat-scroller').shadowRoot.getElementById('viewElement') - const chatScrollerElement = this.shadowRoot.querySelector('chat-page').shadowRoot.querySelector('chat-scroller') + if (chatScrollerElement && chatScrollerElement.disableAddingNewMessages) { const chatPageElement = this.shadowRoot.querySelector('chat-page') - if(chatPageElement && chatPageElement.getLastestMessages) + if (chatPageElement && chatPageElement.getLastestMessages) chatPageElement.getLastestMessages() } else { viewElement.scroll({ top: viewElement.scrollHeight, left: 0, behavior: 'smooth' }) @@ -981,6 +1030,21 @@ class Chat extends LitElement { hideNewMessageBar() { this.shadowRoot.getElementById('newMessageBar').classList.add('hide-new-message-bar') } + + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } -window.customElements.define('q-chat', Chat) +window.customElements.define('q-chat', Chat) \ No newline at end of file diff --git a/plugins/plugins/core/qdn/index.html b/plugins/plugins/core/q-website/index.html similarity index 94% rename from plugins/plugins/core/qdn/index.html rename to plugins/plugins/core/q-website/index.html index da9c4777..e1ef8b98 100644 --- a/plugins/plugins/core/qdn/index.html +++ b/plugins/plugins/core/q-website/index.html @@ -48,8 +48,8 @@ - - + + diff --git a/plugins/plugins/core/q-website/q-websites.src.js b/plugins/plugins/core/q-website/q-websites.src.js new file mode 100644 index 00000000..0bb07ed9 --- /dev/null +++ b/plugins/plugins/core/q-website/q-websites.src.js @@ -0,0 +1,976 @@ +import { html, LitElement } from 'lit' +import { render } from 'lit/html.js' +import { Epml } from '../../../epml' +import { qWebsitesStyles } from '../components/plugins-css' +import isElectron from 'is-electron' +import '@material/mwc-dialog' +import '@material/mwc-icon' +import '@material/mwc-button' +import '@material/mwc-tab-bar' +import '@material/mwc-textfield' +import '@vaadin/button' +import '@vaadin/grid' +import '@vaadin/icon' +import '@vaadin/icons' +import '@vaadin/text-field' + +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../core/translate' +registerTranslateConfig({ + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) +}) + +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + +class QWebsites extends LitElement { + static get properties() { + return { + identifier: { type: String }, + loading: { type: Boolean }, + resources: { type: Array }, + pageRes: { type: Array }, + followedNames: { type: Array }, + blockedNames: { type: Array }, + relayMode: { type: Boolean }, + selectedAddress: { type: Object }, + searchName: { type: String }, + searchResources: { type: Array }, + followedResources: { type: Array }, + blockedResources: { type: Array }, + theme: { type: String, reflect: true } + } + } + + static get styles() { + return [qWebsitesStyles] + } + + constructor() { + super() + this.identifier = '' + this.selectedAddress = {} + this.resources = [] + this.pageRes = [] + this.followedNames = [] + this.blockedNames = [] + this.relayMode = false + this.isLoading = false + this.searchName = '' + this.searchResources = [] + this.followedResources = [] + this.blockedResources = [] + this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' + } + + render() { + return html` +
    + + + + + +
    +
    +
    +

    ${translate("websitespage.schange1")}

    +

    ${this.renderSearchButton()}

    +

    ${this.renderPublishButton()}

    +
    +

    ${translate("websitespage.schange9")}

    + + { + render(html`${this.renderAvatar(data.item)}`, root) + }}> + + { + render(html`${this.renderInfo(data.item)}`, root) + }}> + + { + render(html`${this.renderPublishedBy(data.item)}`, root) + }}> + + { + render(html`${this.renderFollowUnfollowButton(data.item)}`, root); + }}> + + { + render(html`${this.renderBlockUnblockButton(data.item)}`, root); + }}> + + +
    + ${this.pageRes == null ? html` + Loading... + ` : ''} + ${this.isEmptyArray(this.pageRes) ? html` + ${translate("websitespage.schange10")} + ` : ''} + ${this.renderRelayModeText()} +
    +
    +
    +

    ${translate("websitespage.schange11")}

    +

    ${this.renderSearchButton()}

    +

    ${this.renderPublishButton()}

    +
    +

    ${translate("websitespage.schange12")}

    + + { + render(html`${this.renderAvatar(data.item)}`, root) + }}> + + { + render(html`${this.renderInfo(data.item)}`, root) + }}> + + { + render(html`${this.renderPublishedBy(data.item)}`, root) + }}> + + { + render(html`${this.renderFollowUnfollowButtonTab(data.item)}`, root); + }}> + + + ${this.followedResources == null ? html` + Loading... + ` : ''} + ${this.isEmptyArray(this.followedResources) ? html` + ${translate("websitespage.schange13")} + ` : ''} + ${this.renderRelayModeText()} +
    +
    +
    +

    ${translate("websitespage.schange14")}

    +

    ${this.renderSearchButton()}

    +

    ${this.renderPublishButton()}

    +
    +

    ${translate("websitespage.schange15")}

    + + { + render(html`${this.renderAvatar(data.item)}`, root) + }}> + + { + render(html`${this.renderInfo(data.item)}`, root) + }}> + + { + render(html`${this.renderPublishedBy(data.item)}`, root) + }}> + + { + render(html`${this.renderBlockUnblockButtonTab(data.item)}`, root); + }}> + + + ${this.blockedResources == null ? html` + Loading... + ` : ''} + ${this.isEmptyArray(this.blockedResources) ? html` + ${translate("websitespage.schange16")} + ` : ''} + ${this.renderRelayModeText()} +
    +
    +
    + +

    ${translate("websitespage.schange4")}

    + +
    + + { + render(html`${this.renderAvatar(data.item)}`, root) + }}> + + { + render(html`${this.renderPublishedBy(data.item)}`, root) + }}> + + { + render(html`${this.renderFollowUnfollowButton(data.item)}`, root); + }}> + + { + render(html`${this.renderBlockUnblockButton(data.item)}`, root); + }}> + + +
    + ` + } + + firstUpdated() { + this.changeTheme() + this.changeLanguage() + this.showWebsites() + + setTimeout(() => { + this.displayTabContent('browse') + }, 0) + + const getFollowedNames = async () => { + this.followedNames = await parentEpml.request('apiCall', { + url: `/lists/followedNames?apiKey=${this.getApiKey()}` + }) + setTimeout(getFollowedNames, 60000) + } + + const getBlockedNames = async () => { + this.blockedNames = await parentEpml.request('apiCall', { + url: `/lists/blockedNames?apiKey=${this.getApiKey()}` + }) + setTimeout(getBlockedNames, 60000) + } + + const getRelayMode = async () => { + this.relayMode = await parentEpml.request('apiCall', { + url: `/arbitrary/relaymode?apiKey=${this.getApiKey()}` + }) + setTimeout(getRelayMode, 600000) + } + + window.addEventListener('storage', () => { + const checkLanguage = localStorage.getItem('qortalLanguage') + const checkTheme = localStorage.getItem('qortalTheme') + + use(checkLanguage) + + if (checkTheme === 'dark') { + this.theme = 'dark' + } else { + this.theme = 'light' + } + document.querySelector('html').setAttribute('theme', this.theme) + }) + + if (!isElectron()) { + } else { + window.addEventListener('contextmenu', (event) => { + event.preventDefault() + window.parent.electronAPI.showMyMenu() + }) + } + + let configLoaded = false + + parentEpml.ready().then(() => { + parentEpml.subscribe('selected_address', async selectedAddress => { + this.selectedAddress = {} + selectedAddress = JSON.parse(selectedAddress) + if (!selectedAddress || Object.entries(selectedAddress).length === 0) return + this.selectedAddress = selectedAddress + }) + + parentEpml.subscribe('config', c => { + if (!configLoaded) { + setTimeout(getFollowedNames, 1) + setTimeout(getBlockedNames, 1) + setTimeout(getRelayMode, 1) + setTimeout(this.getFollowedNamesResource, 1) + setTimeout(this.getBlockedNamesResource, 1) + setInterval(this.getArbitraryResources, 900000) + configLoaded = true + } + + this.config = JSON.parse(c) + }) + }) + + parentEpml.imReady() + + this.clearConsole() + + setInterval(() => { + this.clearConsole() + }, 60000) + } + + clearConsole() { + if (!isElectron()) { + } else { + console.clear() + window.parent.electronAPI.clearCache() + } + } + + changeTheme() { + const checkTheme = localStorage.getItem('qortalTheme') + + if (checkTheme === 'dark') { + this.theme = 'dark' + } else { + this.theme = 'light' + } + document.querySelector('html').setAttribute('theme', this.theme) + } + + changeLanguage() { + const checkLanguage = localStorage.getItem('qortalLanguage') + + if (checkLanguage === null || checkLanguage.length === 0) { + localStorage.setItem('qortalLanguage', 'us') + use('us') + } else { + use(checkLanguage) + } + } + + renderCatText() { + return html`${translate('websitespage.schange26')}` + } + + async displayTabContent(tab) { + const tabBrowseContent = this.shadowRoot.getElementById('tab-browse-content') + const tabFollowedContent = this.shadowRoot.getElementById('tab-followed-content') + const tabBlockedContent = this.shadowRoot.getElementById('tab-blocked-content') + + if (tab === 'browse') { + tabBrowseContent.style.display = 'block' + tabFollowedContent.style.display = 'none' + tabBlockedContent.style.display = 'none' + await this.refreshWebsites() + } else if (tab === 'followed') { + tabBrowseContent.style.display = 'none' + tabFollowedContent.style.display = 'block' + tabBlockedContent.style.display = 'none' + await this.getFollowedNamesRefresh() + await this.getFollowedNamesResource() + } else if (tab === 'blocked') { + tabBrowseContent.style.display = 'none' + tabFollowedContent.style.display = 'none' + tabBlockedContent.style.display = 'block' + await this.getBlockedNamesRefresh() + await this.getBlockedNamesResource() + } + } + + searchListener(e) { + if (e.key === 'Enter') { + this.doSearch(e) + } + } + + async getResourcesGrid() { + this.resourcesGrid = this.shadowRoot.querySelector('#resourcesGrid') + this.pagesControl = this.shadowRoot.querySelector('#pages') + this.pages = undefined + } + + async getArbitraryResources() { + this.resources = await parentEpml.request('apiCall', { + url: `/arbitrary/resources?service=WEBSITE&default=true&limit=0&reverse=false&includestatus=false&includemetadata=false&excludeblocked=true` + }) + } + + async getFollowedNamesResource() { + this.followedResources = await parentEpml.request('apiCall', { + url: `/arbitrary/resources?service=WEBSITE&default=true&limit=0&reverse=false&includestatus=true&includemetadata=true&namefilter=followedNames` + }) + } + + async getFollowedNamesRefresh() { + this.followedNames = await parentEpml.request('apiCall', { + url: `/lists/followedNames?apiKey=${this.getApiKey()}` + }) + } + + async getBlockedNamesResource() { + this.blockedResources = await parentEpml.request('apiCall', { + url: `/arbitrary/resources?service=WEBSITE&default=true&limit=0&reverse=false&includestatus=true&includemetadata=true&namefilter=blockedNames` + }) + } + + async getBlockedNamesRefresh() { + this.blockedNames = await parentEpml.request('apiCall', { + url: `/lists/blockedNames?apiKey=${this.getApiKey()}` + }) + } + + async getData(offset) { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + + let jsonOffsetUrl = `${nodeUrl}/arbitrary/resources?service=WEBSITE&default=true&limit=20&offset=${offset}&reverse=false&includestatus=true&includemetadata=true&excludeblocked=true` + + const jsonOffsetRes = await fetch(jsonOffsetUrl) + + this.pageRes = await jsonOffsetRes.json() + } + + async updateItemsFromPage(page) { + if (page === undefined) { + return + } + + if (!this.pages) { + this.pages = Array.apply(null, { length: Math.ceil(this.resources.length / 20) }).map((item, index) => { + return index + 1 + }) + + let offset = 0 + + const prevBtn = document.createElement('button') + prevBtn.textContent = '<' + prevBtn.addEventListener('click', () => { + if (parseInt(this.pagesControl.querySelector('[selected]').textContent) > 1) { + offset = (parseInt(this.pagesControl.querySelector('[selected]').textContent) - 2) * 20 + } else { + offset = 0 + } + this.getData(offset) + const selectedPage = parseInt(this.pagesControl.querySelector('[selected]').textContent) + this.updateItemsFromPage(selectedPage - 1) + }) + this.pagesControl.appendChild(prevBtn) + + this.pages.forEach((pageNumber) => { + const pageBtn = document.createElement('button') + pageBtn.textContent = pageNumber + let offset = 0 + pageBtn.addEventListener('click', (e) => { + if (parseInt(e.target.textContent) > 1) { + offset = (parseInt(e.target.textContent) - 1) * 20 + } else { + offset = 0 + } + this.getData(offset) + this.updateItemsFromPage(parseInt(e.target.textContent)) + }) + if (pageNumber === page) { + pageBtn.setAttribute('selected', true) + } + this.pagesControl.appendChild(pageBtn) + }) + + const nextBtn = window.document.createElement('button') + nextBtn.textContent = '>' + nextBtn.addEventListener('click', () => { + if (parseInt(this.pagesControl.querySelector('[selected]').textContent) >= 1) { + offset = ((parseInt(this.pagesControl.querySelector('[selected]').textContent) + 1) * 20) - 20 + } else { + offset = 0 + } + + this.getData(offset) + const selectedPage = parseInt(this.pagesControl.querySelector('[selected]').textContent) + this.updateItemsFromPage(selectedPage + 1) + }) + + this.pagesControl.appendChild(nextBtn) + } + + const buttons = Array.from(this.pagesControl.children) + buttons.forEach((btn, index) => { + if (parseInt(btn.textContent) === page) { + btn.setAttribute('selected', true) + } else { + btn.removeAttribute('selected') + } + + if (index === 0) { + if (page === 1) { + btn.setAttribute('disabled', '') + } else { + btn.removeAttribute('disabled') + } + } + + if (index === buttons.length - 1) { + if (page === this.pages.length) { + btn.setAttribute('disabled', '') + } else { + btn.removeAttribute('disabled') + } + } + }) + } + + async showWebsites() { + await this.getData(0) + await this.getArbitraryResources() + await this.getResourcesGrid() + await this.updateItemsFromPage(1, true) + } + + async refreshWebsites() { + await this.getData(0) + await this.getArbitraryResources() + await this.updateItemsFromPage(1, true) + } + + doSearch(e) { + this.searchResult() + } + + async searchResult() { + let searchName = this.shadowRoot.getElementById('searchName').value + + if (searchName.length === 0) { + let err1string = get('websitespage.schange34') + parentEpml.request('showSnackBar', `${err1string}`) + } else { + let searchResources = await parentEpml.request('apiCall', { + url: `/arbitrary/resources/search?service=WEBSITE&query=${searchName}&default=true&limit=5&reverse=false&includestatus=true&includemetadata=true` + }) + if (this.isEmptyArray(searchResources)) { + let err2string = get('websitespage.schange17') + parentEpml.request('showSnackBar', `${err2string}`) + } else { + this.searchResources = searchResources + } + } + } + + renderAvatar(websiteObj) { + let name = websiteObj.name + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/arbitrary/THUMBNAIL/${name}/qortal_avatar?async=true}` + return html`` + } + + renderRelayModeText() { + if (this.relayMode === true) { + return html`
    ${translate('websitespage.schange18')} "relayModeEnabled": false ${translate('websitespage.schange19')} settings.json
    ` + } else if (this.relayMode === false) { + return html`
    ${translate('websitespage.schange20')} "relayModeEnabled": true ${translate('websitespage.schange19')} settings.json
    ` + } else { + return html`` + } + } + + renderPublishButton() { + // Only show the publish button if we have admin permissions on this node + // We can check the followed names array to achieve this + if (this.followedNames == null || !Array.isArray(this.followedNames)) { + return html`` + } else { + return html` this.publishWebsite()}>add${translate('websitespage.schange21')}` + } + } + + renderSearchButton() { + return html` this.openSearchDialog()}>search${translate('websitespage.schange4')}` + } + + openSearchDialog() { + this.searchResources = [] + this.shadowRoot.getElementById('searchName').value = '' + this.shadowRoot.getElementById('searchWebsiteDialog').show() + } + + publishWebsite() { + window.location.href = `../qdn/publish/index.html?service=WEBSITE&identifier=${this.identifier}&uploadType=zip&category=Website&showName=true&showService=false&showIdentifier=false&showMetadata=true` + } + + async followName(websiteObj) { + let name = websiteObj.name + + let items = [ + name + ] + + let namesJsonString = JSON.stringify({ 'items': items }) + + let ret = await parentEpml.request('apiCall', { + url: `/lists/followedNames?apiKey=${this.getApiKey()}`, + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + + if (ret === true) { + // Successfully followed - add to local list + // Remove it first by filtering the list - doing it this way ensures the UI updates + // immediately, as apposed to only adding if it doesn't already exist + this.followedNames = this.followedNames.filter(item => item != name) + this.followedNames.push(name) + } else { + let err3string = get('websitespage.schange22') + parentEpml.request('showSnackBar', `${err3string}`) + } + + return ret + } + + async followNameTab(websiteObj) { + let name = websiteObj.name + + let items = [ + name + ] + + let namesJsonString = JSON.stringify({ 'items': items }) + + let ret = await parentEpml.request('apiCall', { + url: `/lists/followedNames?apiKey=${this.getApiKey()}`, + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + + if (ret === true) { + // Successfully followed - add to local list + // Remove it first by filtering the list - doing it this way ensures the UI updates + // immediately, as apposed to only adding if it doesn't already exist + this.followedNames = this.followedNames.filter(item => item != name) + this.followedNames.push(name) + await this.getFollowedNamesRefresh() + await this.getFollowedNamesResource() + } else { + let err3string = get('websitespage.schange22') + parentEpml.request('showSnackBar', `${err3string}`) + } + + return ret + } + + async unfollowName(websiteObj) { + let name = websiteObj.name + + let items = [ + name + ] + + let namesJsonString = JSON.stringify({ 'items': items }) + + let ret = await parentEpml.request('apiCall', { + url: `/lists/followedNames?apiKey=${this.getApiKey()}`, + method: 'DELETE', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + + if (ret === true) { + // Successfully unfollowed - remove from local list + this.followedNames = this.followedNames.filter(item => item != name) + } else { + let err4string = get('websitespage.schange23') + parentEpml.request('showSnackBar', `${err4string}`) + } + + return ret + } + + async unfollowNameTab(websiteObj) { + let name = websiteObj.name + + let items = [ + name + ] + + let namesJsonString = JSON.stringify({ 'items': items }) + + let ret = await parentEpml.request('apiCall', { + url: `/lists/followedNames?apiKey=${this.getApiKey()}`, + method: 'DELETE', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + + if (ret === true) { + // Successfully unfollowed - remove from local list + this.followedNames = this.followedNames.filter(item => item != name) + await this.getFollowedNamesRefresh() + await this.getFollowedNamesResource() + } else { + let err4string = get('websitespage.schange23') + parentEpml.request('showSnackBar', `${err4string}`) + } + + return ret + } + + async blockName(websiteObj) { + let name = websiteObj.name + + let items = [ + name + ] + + let namesJsonString = JSON.stringify({ 'items': items }) + + let ret = await parentEpml.request('apiCall', { + url: `/lists/blockedNames?apiKey=${this.getApiKey()}`, + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + + if (ret === true) { + // Successfully blocked - add to local list + // Remove it first by filtering the list - doing it this way ensures the UI updates + // immediately, as apposed to only adding if it doesn't already exist + this.blockedNames = this.blockedNames.filter(item => item != name) + this.blockedNames.push(name) + } else { + let err5string = get('websitespage.schange24') + parentEpml.request('showSnackBar', `${err5string}`) + } + + return ret + } + + async blockNameTab(websiteObj) { + let name = websiteObj.name + + let items = [ + name + ] + + let namesJsonString = JSON.stringify({ 'items': items }) + + let ret = await parentEpml.request('apiCall', { + url: `/lists/blockedNames?apiKey=${this.getApiKey()}`, + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + + if (ret === true) { + // Successfully blocked - add to local list + // Remove it first by filtering the list - doing it this way ensures the UI updates + // immediately, as apposed to only adding if it doesn't already exist + this.blockedNames = this.blockedNames.filter(item => item != name) + this.blockedNames.push(name) + await this.getBlockedNamesRefresh() + await this.getBlockedNamesResource() + } else { + let err5string = get('websitespage.schange24') + parentEpml.request('showSnackBar', `${err5string}`) + } + + return ret + } + + async unblockName(websiteObj) { + let name = websiteObj.name + + let items = [ + name + ] + + let namesJsonString = JSON.stringify({ 'items': items }) + + let ret = await parentEpml.request('apiCall', { + url: `/lists/blockedNames?apiKey=${this.getApiKey()}`, + method: 'DELETE', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + + if (ret === true) { + // Successfully unblocked - remove from local list + this.blockedNames = this.blockedNames.filter(item => item != name) + } else { + let err6string = get('websitespage.schange25') + parentEpml.request('showSnackBar', `${err6string}`) + } + + return ret + } + + async unblockNameTab(websiteObj) { + let name = websiteObj.name + + let items = [ + name + ] + + let namesJsonString = JSON.stringify({ 'items': items }) + + let ret = await parentEpml.request('apiCall', { + url: `/lists/blockedNames?apiKey=${this.getApiKey()}`, + method: 'DELETE', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + + if (ret === true) { + // Successfully unblocked - remove from local list + this.blockedNames = this.blockedNames.filter(item => item != name) + await this.getBlockedNamesRefresh() + await this.getBlockedNamesResource() + } else { + let err6string = get('websitespage.schange25') + parentEpml.request('showSnackBar', `${err6string}`) + } + + return ret + } + + renderInfo(websiteObj) { + let name = websiteObj.name + let title = name + let description = '' + let categoryName = this.renderCatText() + let tags = '' + let sizeReadable = '' + + if (websiteObj.metadata != null) { + title = websiteObj.metadata.title + description = websiteObj.metadata.description + categoryName = websiteObj.metadata.categoryName + if (websiteObj.metadata.tags != null && websiteObj.metadata.tags.length > 0) { + tags = 'Tags: ' + websiteObj.metadata.tags.join(', ') + } + } + + if (websiteObj.size != null) { + sizeReadable = this.bytesToSize(websiteObj.size) + } + + return html` +
    + ${title} +
    +
    ${description}
    +
    + ${categoryName}  + ${tags.length > 0 ? " | " : ""}  + ${tags}  + ${sizeReadable.length > 0 ? " | " : ""}  + ${translate("websitespage.schange27")}: ${sizeReadable} +
    + ` + } + + renderPublishedBy(websiteObj) { + return html` +
    ${websiteObj.name}
    +
    + ${translate('websitespage.schange28')}: ${websiteObj.status.title} +
    + ` + } + + renderSize(websiteObj) { + if (websiteObj.size === null) { + return html`` + } + + let sizeReadable = this.bytesToSize(websiteObj.size) + + return html`${sizeReadable}` + } + + renderFollowUnfollowButton(websiteObj) { + let name = websiteObj.name + + // Only show the follow/unfollow button if we have permission to modify the list on this node + if (this.followedNames == null || !Array.isArray(this.followedNames)) { + return html`` + } + + if (this.followedNames.indexOf(name) === -1) { + // render follow button + return html` this.followName(websiteObj)}>add_to_queue ${translate('websitespage.schange29')}` + } else { + // render unfollow button + return html` this.unfollowName(websiteObj)}>remove_from_queue ${translate('websitespage.schange30')}` + } + } + + renderFollowUnfollowButtonTab(websiteObj) { + let name = websiteObj.name + + // Only show the follow/unfollow button if we have permission to modify the list on this node + if (this.followedNames == null || !Array.isArray(this.followedNames)) { + return html`` + } + + if (this.followedNames.indexOf(name) === -1) { + // render follow button + return html` this.followNameTab(websiteObj)}>add_to_queue ${translate('websitespage.schange29')}` + } else { + // render unfollow button + return html` this.unfollowNameTab(websiteObj)}>remove_from_queue ${translate('websitespage.schange30')}` + } + } + + renderBlockUnblockButton(websiteObj) { + let name = websiteObj.name + + // Only show the block/unblock button if we have permission to modify the list on this node + if (this.blockedNames == null || !Array.isArray(this.blockedNames)) { + return html`` + } + + if (this.blockedNames.indexOf(name) === -1) { + // render block button + return html` this.blockName(websiteObj)}>block ${translate('websitespage.schange31')}` + } else { + // render unblock button + return html` this.unblockName(websiteObj)}>radio_button_unchecked ${translate('websitespage.schange32')}` + } + } + + renderBlockUnblockButtonTab(websiteObj) { + let name = websiteObj.name + + // Only show the block/unblock button if we have permission to modify the list on this node + if (this.blockedNames == null || !Array.isArray(this.blockedNames)) { + return html`` + } + + if (this.blockedNames.indexOf(name) === -1) { + // render block button + return html` this.blockNameTab(websiteObj)}>block ${translate('websitespage.schange31')}` + } else { + // render unblock button + return html` this.unblockNameTab(websiteObj)}>radio_button_unchecked ${translate('websitespage.schange32')}` + } + } + + bytesToSize(bytes) { + var sizes = ['bytes', 'KB', 'MB', 'GB', 'TB'] + if (bytes == 0) return '0 bytes' + var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024))) + return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i] + } + + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } +} + +window.customElements.define('q-websites', QWebsites) \ No newline at end of file diff --git a/plugins/plugins/core/qdn/browser/browser.src.js b/plugins/plugins/core/qdn/browser/browser.src.js index 8d0c5ad5..60fb6e53 100644 --- a/plugins/plugins/core/qdn/browser/browser.src.js +++ b/plugins/plugins/core/qdn/browser/browser.src.js @@ -1,19 +1,8 @@ -import {css, html, LitElement} from 'lit' -import {Epml} from '../../../../epml' -import isElectron from 'is-electron' -import {get, registerTranslateConfig, translate, use} from '../../../../../core/translate' -import ShortUniqueId from 'short-unique-id'; -import FileSaver from 'file-saver' -import * as actions from '../../components/qdn-action-types' -import '@material/mwc-button' -import '@material/mwc-icon' -import '@material/mwc-checkbox' -import WebWorker from 'web-worker:./computePowWorkerFile.src.js' -import WebWorkerChat from 'web-worker:./computePowWorker.src.js' -import {publishData} from '../../../utils/publish-image.js' -import {Loader} from '../../../utils/loader.js'; -import {QORT_DECIMALS} from '../../../../../crypto/api/constants' -import {mimeToExtensionMap} from '../../components/qdn-action-constants'; +import { html, LitElement } from 'lit' +import { Epml } from '../../../../epml' +import { Loader, publishData } from '../../../utils/classes' +import { QORT_DECIMALS } from '../../../../../crypto/api/constants' +import { mimeToExtensionMap } from '../../components/qdn-action-constants' import { base64ToUint8Array, decryptDeprecatedSingle, @@ -22,13 +11,25 @@ import { fileToBase64, uint8ArrayStartsWith, uint8ArrayToBase64 -} from '../../components/qdn-action-encryption'; +} from '../../components/qdn-action-encryption' +import { webBrowserStyles, webBrowserModalStyles } from '../../components/plugins-css' +import * as actions from '../../components/qdn-action-types' +import isElectron from 'is-electron' +import ShortUniqueId from 'short-unique-id' +import FileSaver from 'file-saver' +import WebWorker from 'web-worker:./computePowWorkerFile.js' +import WebWorkerChat from 'web-worker:./computePowWorker.js' +import '@material/mwc-button' +import '@material/mwc-icon' +import '@material/mwc-checkbox' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../../core/translate' registerTranslateConfig({ - loader: (lang) => fetch(`/language/${lang}.json`).then((res) => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) -const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }); +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) class WebBrowser extends LitElement { static get properties() { @@ -60,77 +61,7 @@ class WebBrowser extends LitElement { } static get styles() { - return css` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --paper-input-container-focus-color: var(--mdc-theme-primary); - --mdc-checkbox-unchecked-color: var(--black); - --mdc-theme-on-surface: var(--black); - --mdc-checkbox-disabled-color: var(--black); - --mdc-checkbox-ink-color: var(--black); - } - - #websitesWrapper paper-button { - float: right; - } - - #websitesWrapper .buttons { - width: auto !important; - } - - .address-bar { - position: absolute; - top: 0; - left: 0; - right: 0; - height: 100px; - background-color: var(--white); - height: 36px; - } - - .address-bar-button mwc-icon { - width: 20px; - } - - .iframe-container { - position: absolute; - top: 36px; - left: 0; - right: 0; - bottom: 0; - border-top: 1px solid var(--black); - } - - .iframe-container iframe { - display: block; - width: 100%; - height: 100%; - border: none; - background-color: var(--white); - } - - input[type='text'] { - margin: 0; - padding: 2px 0 0 20px; - border: 0; - height: 34px; - font-size: 16px; - background-color: var(--white); - } - input { - outline: none - } - - - paper-progress { - --paper-progress-active-color: var(--mdc-theme-primary); - } - - .float-right { - float: right; - } - `; + return [webBrowserStyles] } constructor() { @@ -142,15 +73,8 @@ class WebBrowser extends LitElement { const urlParams = new URLSearchParams(window.location.search) this.name = urlParams.get('name') this.service = urlParams.get('service') - this.identifier = - urlParams.get('identifier') != null - ? urlParams.get('identifier') - : null - this.path = - urlParams.get('path') != null - ? (urlParams.get('path').startsWith('/') ? '' : '/') + - urlParams.get('path') - : '' + this.identifier = urlParams.get('identifier') != null ? urlParams.get('identifier') : null + this.path = urlParams.get('path') != null ? (urlParams.get('path').startsWith('/') ? '' : '/') + urlParams.get('path') : '' this.preview = urlParams.get('preview') this.link = urlParams.get('link') this.dev = urlParams.get('dev') @@ -166,9 +90,11 @@ class WebBrowser extends LitElement { displayUrl = 'qortal://app/development' } else { displayUrl = 'qortal://' + this.service + '/' + this.name + if (this.identifier && this.identifier != 'null' && this.identifier != 'default') { displayUrl = displayUrl.concat('/' + this.identifier) } + if (this.path != null && this.path != '/') { displayUrl = displayUrl.concat(this.path) } @@ -178,8 +104,9 @@ class WebBrowser extends LitElement { const getFollowedNames = async () => { this.followedNames = await parentEpml.request('apiCall', { - url: `/lists/followedNames?apiKey=${this.getApiKey()}`, + url: `/lists/followedNames?apiKey=${this.getApiKey()}` }) + setTimeout( getFollowedNames, this.config.user.nodeSettings.pingInterval @@ -188,8 +115,9 @@ class WebBrowser extends LitElement { const getBlockedNames = async () => { this.blockedNames = await parentEpml.request('apiCall', { - url: `/lists/blockedNames?apiKey=${this.getApiKey()}`, + url: `/lists/blockedNames?apiKey=${this.getApiKey()}` }) + setTimeout( getBlockedNames, this.config.user.nodeSettings.pingInterval @@ -197,12 +125,8 @@ class WebBrowser extends LitElement { } const render = () => { - const myNode = - window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] - const nodeUrl = - myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port if (this.preview != null && this.preview.length > 0) { // In preview mode we access the preview URL path directly @@ -211,10 +135,7 @@ class WebBrowser extends LitElement { this.url = `${this.link}` } else { // Normal mode - - this.url = `${nodeUrl}/render/${this.service}/${this.name}${this.path != null ? this.path : '' - }?theme=${this.theme}&identifier=${(this.identifier != null && this.identifier != 'null') ? this.identifier : '' - }` + this.url = `${nodeUrl}/render/${this.service}/${this.name}${this.path != null ? this.path : ''}?theme=${this.theme}&identifier=${(this.identifier != null && this.identifier != 'null') ? this.identifier : ''}` } } @@ -231,7 +152,10 @@ class WebBrowser extends LitElement { parentEpml.ready().then(() => { parentEpml.subscribe('selected_address', async (selectedAddress) => { selectedAddress = JSON.parse(selectedAddress) - if (!selectedAddress || Object.entries(selectedAddress).length === 0) return + + if (!selectedAddress || Object.entries(selectedAddress).length === 0) { + return + } this.selectedAddress = selectedAddress this.btcWallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet @@ -241,6 +165,7 @@ class WebBrowser extends LitElement { this.rvnWallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet this.arrrWallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet }) + parentEpml.subscribe('config', (c) => { this.config = JSON.parse(c) if (!configLoaded) { @@ -253,119 +178,28 @@ class WebBrowser extends LitElement { }) } - async extractComponents(url) { - if (!url.startsWith("qortal://")) { - return null - } - - url = url.replace(/^(qortal\:\/\/)/, "") - if (url.includes("/")) { - let parts = url.split("/") - const service = parts[0].toUpperCase() - parts.shift() - const name = parts[0] - parts.shift() - let identifier - if (parts.length > 0) { - identifier = parts[0] // Do not shift yet - // Check if a resource exists with this service, name and identifier combination - let responseObj = await parentEpml.request('apiCall', { - url: `/arbitrary/resource/status/${service}/${name}/${identifier}?apiKey=${this.getApiKey()}` - }) - - if (responseObj.totalChunkCount > 0) { - // Identifier exists, so don't include it in the path - parts.shift() - } - else { - identifier = null - } - } - const path = parts.join("/") - const components = {} - components["service"] = service - components["name"] = name - components["identifier"] = identifier - components["path"] = path - return components - } - - return null - } - - async _handleKeyDown(e) { - if (e.key === 'Enter') { - let newQuery = e.target.value - if (newQuery.endsWith('/')) { - newQuery = newQuery.slice(0, -1) - } - const res = await this.extractComponents(newQuery) - if (!res) return - const { service, name, identifier, path } = res - let query = `?service=${service}` - if (name) { - query = query + `&name=${name}` - } - if (identifier) { - query = query + `&identifier=${identifier}` - } - if (path) { - query = query + `&path=${path}` - } - window.location = window.location.origin + window.location.pathname + query - } - } - - async linkOpenNewTab(link) { - - let newQuery = link - if (newQuery.endsWith('/')) { - newQuery = newQuery.slice(0, -1) - } - const res = await this.extractComponents(newQuery) - if (!res) return - const { service, name, identifier, path } = res - let query = `?service=${service}` - if (name) { - query = query + `&name=${name}` - } - if (identifier) { - query = query + `&identifier=${identifier}` - } - if (path) { - query = query + `&path=${path}` - } - - window.parent.reduxStore.dispatch(window.parent.reduxAction.setNewTab({ - url: `qdn/browser/index.html${query}`, - id: this.uid.rnd(), - myPlugObj: { - "url": service === 'WEBSITE' ? "websites" : "qapps", - "domain": "core", - "page": `qdn/browser/index.html${query}`, - "title": name, - "icon": service === 'WEBSITE' ? 'vaadin:desktop' : 'vaadin:external-browser', - "mwcicon": service === 'WEBSITE' ? 'desktop_mac' : 'open_in_browser', - "menus": [], - "parent": false - } - })) - - } - render() { - return html`
    - this.goBack()} title="${translate('general.back')}" class="address-bar-button">arrow_back_ios - this.goForward()} title="${translate('browserpage.bchange1')}" class="address-bar-button">arrow_forward_ios - this.refresh()} title="${translate('browserpage.bchange2')}" class="address-bar-button">refresh - this.goBackToList()} title="${translate('browserpage.bchange3')}" class="address-bar-button">home + this.goBack()} title="${translate('general.back')}" class="address-bar-button"> + arrow_back_ios + + this.goForward()} title="${translate('browserpage.bchange1')}" class="address-bar-button"> + arrow_forward_ios + + this.refresh()} title="${translate('browserpage.bchange2')}" class="address-bar-button"> + refresh + + this.goBackToList()} title="${translate('browserpage.bchange3')}" class="address-bar-button"> + home + ${this.renderFullScreen()} - this.delete()} title="${translate('browserpage.bchange4')} ${this.service} ${this.name} ${translate('browserpage.bchange5')}" class="address-bar-button float-right">delete + this.delete()} title="${translate('browserpage.bchange4')} ${this.service} ${this.name} ${translate('browserpage.bchange5')}" class="address-bar-button float-right"> + delete + ${this.renderBlockUnblockButton()} ${this.renderFollowUnfollowButton()}
    @@ -376,358 +210,7 @@ class WebBrowser extends LitElement {
    - `; - } - - renderFullScreen() { - if (window.innerHeight == screen.height) { - return html` - this.exitFullScreen()} - title="${translate('browserpage.bchange38')}" - class="address-bar-button float-right" - > - fullscreen_exit - - ` - } else { - return html` - this.goFullScreen()} - title="${translate('browserpage.bchange37')}" - class="address-bar-button float-right" - > - fullscreen - - ` - } - } - - goFullScreen() { - var elem = this.shadowRoot.getElementById('websitesWrapper') - - if (elem.requestFullscreen) { - elem.requestFullscreen() - } else if (elem.mozRequestFullScreen) { - elem.mozRequestFullScreen() - } else if (elem.webkitRequestFullscreen) { - elem.webkitRequestFullscreen() - } else if (elem.msRequestFullscreen) { - elem.msRequestFullscreen() - } - - this.renderFullScreen() - } - - exitFullScreen() { - if (document.exitFullscreen) { - document.exitFullscreen() - } else if (document.mozCancelFullScreen) { - document.mozCancelFullScreen() - } else if (document.webkitExitFullscreen) { - document.webkitExitFullscreen() - } else if (document.msExitFullscreen) { - document.msExitFullscreen() - } - - this.renderFullScreen() - } - - async unitJoinFee() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/transactions/unitfee?txType=JOIN_GROUP` - const response = await fetch(url) - if (!response.ok) { - throw new Error('Error when fetching join fee') - } - - const data = await response.json() - return (Number(data) / 1e8).toFixed(8) - } - - async deployAtFee() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/transactions/unitfee?txType=DEPLOY_AT` - const response = await fetch(url) - if (!response.ok) { - throw new Error('Error when fetching join fee') - } - - const data = await response.json() - return (Number(data) / 1e8).toFixed(8) - } - - async getArbitraryFee() { - const timestamp = Date.now() - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/transactions/unitfee?txType=ARBITRARY×tamp=${timestamp}` - const response = await fetch(url) - if (!response.ok) { - throw new Error('Error when fetching arbitrary fee') - } - const data = await response.json() - const arbitraryFee = (Number(data) / 1e8).toFixed(8) - return { - timestamp, - fee: Number(data), - feeToShow: arbitraryFee - } - } - async sendQortFee() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/transactions/unitfee?txType=PAYMENT` - const response = await fetch(url) - if (!response.ok) { - throw new Error('Error when fetching join fee') - } - - const data = await response.json() - return (Number(data) / 1e8).toFixed(8) - } - - async unitVoteFee() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/transactions/unitfee?txType=VOTE_ON_POLL` - const response = await fetch(url) - if (!response.ok) { - throw new Error('Error when fetching vote fee') - } - - const data = await response.json() - return (Number(data) / 1e8).toFixed(8) - } - - async unitCreatePollFee() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/transactions/unitfee?txType=CREATE_POLL` - const response = await fetch(url) - if (!response.ok) { - throw new Error('Error when fetching vote fee') - } - - const data = await response.json() - return (Number(data) / 1e8).toFixed(8) - } - - async _joinGroup(groupId, groupName) { - const joinFeeInput = await this.unitJoinFee() - const getLastRef = async () => { - return await parentEpml.request('apiCall', { - type: 'api', - url: `/addresses/lastreference/${this.selectedAddress.address}` - }) - } - - const validateReceiver = async () => { - let lastRef = await getLastRef() - let myTransaction = await makeTransactionRequest(lastRef) - return getTxnRequestResponse(myTransaction) - } - - const makeTransactionRequest = async (lastRef) => { - let groupdialog1 = get("transactions.groupdialog1") - let groupdialog2 = get("transactions.groupdialog2") - return await parentEpml.request('transaction', { - type: 31, - nonce: this.selectedAddress.nonce, - params: { - fee: joinFeeInput, - registrantAddress: this.selectedAddress.address, - rGroupName: groupName, - rGroupId: groupId, - lastReference: lastRef, - groupdialog1: groupdialog1, - groupdialog2: groupdialog2 - }, - apiVersion: 2 - }) - } - - const getTxnRequestResponse = (txnResponse) => { - if (txnResponse.success === false && txnResponse.message) { - throw new Error(txnResponse.message) - } else if (txnResponse.success === true && !txnResponse.data.error) { - return txnResponse.data - } else if (txnResponse.data && txnResponse.data.message) { - throw new Error(txnResponse.data.message) - } else { - throw new Error('Server error. Could not perform action.') - } - } - return await validateReceiver() - - } - - async _deployAt(name, description, tags, creationBytes, amount, assetId, atType) { - const deployAtFee = await this.deployAtFee() - const getLastRef = async () => { - return await parentEpml.request('apiCall', { - type: 'api', - url: `/addresses/lastreference/${this.selectedAddress.address}` - }) - } - - const validateReceiver = async () => { - let lastRef = await getLastRef() - let myTransaction = await makeTransactionRequest(lastRef) - return getTxnRequestResponse(myTransaction) - } - - const makeTransactionRequest = async (lastRef) => { - let deployAtdialog1 = get("transactions.deployAtdialog1") - let deployAtdialog2 = get("transactions.deployAtdialog2") - let deployAtdialog3 = get("transactions.deployAtdialog3") - let deployAtdialog4 = get("walletpage.wchange12") - return await parentEpml.request('transaction', { - type: 16, - nonce: this.selectedAddress.nonce, - params: { - fee: deployAtFee, - rName: name, - rDescription: description, - rTags: tags, - rAmount: amount, - rAssetId: assetId, - rCreationBytes: creationBytes, - atType: atType, - lastReference: lastRef, - atDeployDialog1: deployAtdialog1, - atDeployDialog2: deployAtdialog2, - atDeployDialog3: deployAtdialog3, - atDeployDialog4: deployAtdialog4 - }, - apiVersion: 2 - }) - } - - const getTxnRequestResponse = (txnResponse) => { - if (txnResponse.success === false && txnResponse.message) { - throw new Error(txnResponse.message) - } else if (txnResponse.success === true && !txnResponse.data.error) { - return txnResponse.data - } else if (txnResponse.data && txnResponse.data.message) { - throw new Error(txnResponse.data.message) - } else { - throw new Error('Server error. Could not perform action.') - } - } - return await validateReceiver() - - } - - async _voteOnPoll(pollName, optionIndex) { - const voteFeeInput = await this.unitVoteFee() - const getLastRef = async () => { - return await parentEpml.request('apiCall', { - type: 'api', - url: `/addresses/lastreference/${this.selectedAddress.address}` - }) - } - - const validateReceiver = async () => { - let lastRef = await getLastRef() - let myTransaction = await makeTransactionRequest(lastRef) - return getTxnRequestResponse(myTransaction) - } - - const makeTransactionRequest = async (lastRef) => { - let votedialog1 = get("transactions.votedialog1") - let votedialog2 = get("transactions.votedialog2") - let feeDialog = get("walletpage.wchange12") - - return await parentEpml.request('transaction', { - type: 9, - nonce: this.selectedAddress.nonce, - params: { - fee: voteFeeInput, - voterAddress: this.selectedAddress.address, - rPollName: pollName, - rOptionIndex: optionIndex, - lastReference: lastRef, - votedialog1: votedialog1, - votedialog2: votedialog2, - feeDialog - }, - apiVersion: 2 - }) - } - - const getTxnRequestResponse = (txnResponse) => { - if (txnResponse.success === false && txnResponse.message) { - throw new Error(txnResponse.message) - } else if (txnResponse.success === true && !txnResponse.data.error) { - return txnResponse.data - } else if (txnResponse.data && txnResponse.data.message) { - throw new Error(txnResponse.data.message) - } else { - throw new Error('Server error. Could not perform action.') - } - } - return await validateReceiver() - - } - - async _createPoll(pollName, pollDescription, options, pollOwnerAddress) { - const voteFeeInput = await this.unitCreatePollFee() - const getLastRef = async () => { - return await parentEpml.request('apiCall', { - type: 'api', - url: `/addresses/lastreference/${this.selectedAddress.address}` - }) - } - - const validateReceiver = async () => { - let lastRef = await getLastRef() - let myTransaction = await makeTransactionRequest(lastRef) - return getTxnRequestResponse(myTransaction) - } - - const makeTransactionRequest = async (lastRef) => { - let votedialog3 = get("transactions.votedialog3") - let votedialog4 = get("transactions.votedialog4") - let votedialog5 = get("transactions.votedialog5") - let votedialog6 = get("transactions.votedialog6") - let feeDialog = get("walletpage.wchange12") - - return await parentEpml.request('transaction', { - type: 8, - nonce: this.selectedAddress.nonce, - params: { - fee: voteFeeInput, - ownerAddress: pollOwnerAddress, - rPollName: pollName, - rPollDesc: pollDescription, - rOptions: options, - lastReference: lastRef, - votedialog3: votedialog3, - votedialog4: votedialog4, - votedialog5: votedialog5, - votedialog6: votedialog6, - feeDialog - }, - apiVersion: 2 - }) - } - - const getTxnRequestResponse = (txnResponse) => { - if (txnResponse.success === false && txnResponse.message) { - throw new Error(txnResponse.message) - } else if (txnResponse.success === true && !txnResponse.data.error) { - return txnResponse.data - } else if (txnResponse.data && txnResponse.data.message) { - throw new Error(txnResponse.data.message) - } else { - throw new Error('Server error. Could not perform action.') - } - } - return await validateReceiver() - + ` } firstUpdated() { @@ -752,6 +235,7 @@ class WebBrowser extends LitElement { } else { this.theme = 'light' } + document.querySelector('html').setAttribute('theme', this.theme) }) @@ -764,12 +248,7 @@ class WebBrowser extends LitElement { } window.addEventListener('message', async (event) => { - if ( - event == null || - event.data == null || - event.data.length == 0 || - event.data.action == null - ) { + if (event == null || event.data == null || event.data.length == 0 || event.data.action == null) { return } @@ -778,7 +257,6 @@ class WebBrowser extends LitElement { switch (data.action) { case actions.GET_USER_ACCOUNT: { - let skip = false if (window.parent.reduxStore.getState().app.qAPPAutoAuth) { skip = true @@ -829,16 +307,14 @@ class WebBrowser extends LitElement { if (encryptDataResponse) { data64 = encryptDataResponse response = JSON.stringify(encryptDataResponse) - break; + break } else { dataSentBack['error'] = "Unable to encrypt" response = JSON.stringify(dataSentBack) break } - } catch (error) { - const data = {} data['error'] = error.message || "Error in encrypting data" response = JSON.stringify(data) @@ -847,9 +323,7 @@ class WebBrowser extends LitElement { } case actions.DECRYPT_DATA: { - const { encryptedData, publicKey } = data - try { let data = {} if (!encryptedData) { @@ -861,19 +335,14 @@ class WebBrowser extends LitElement { const uint8Array = base64ToUint8Array(encryptedData) const startsWithQortalEncryptedData = uint8ArrayStartsWith(uint8Array, "qortalEncryptedData") if (startsWithQortalEncryptedData) { - if (!publicKey) { data['error'] = `Missing fields: publicKey` response = JSON.stringify(data) break } - - const decryptedDataToBase64 = decryptDeprecatedSingle(uint8Array, publicKey) response = JSON.stringify(decryptedDataToBase64) break - - } const startsWithQortalGroupEncryptedData = uint8ArrayStartsWith(uint8Array, "qortalGroupEncryptedData") if (startsWithQortalGroupEncryptedData) { @@ -884,12 +353,10 @@ class WebBrowser extends LitElement { break } - data['error'] = "Unable to decrypt" response = JSON.stringify(data) break } catch (error) { - const data = {} data['error'] = error.message || "Error in decrypting data" response = JSON.stringify(data) @@ -900,13 +367,11 @@ class WebBrowser extends LitElement { case actions.GET_LIST_ITEMS: { const requiredFields = ['list_name'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -928,14 +393,11 @@ class WebBrowser extends LitElement { } ) } - - if (res1 && res1.action === 'accept' || skip) { - try { const list = await parentEpml.request('apiCall', { type: 'api', - url: `/lists/${data.list_name}?apiKey=${this.getApiKey()}`, + url: `/lists/${data.list_name}?apiKey=${this.getApiKey()}` }) response = JSON.stringify(list) @@ -946,7 +408,6 @@ class WebBrowser extends LitElement { } finally { break } - } else { const data = {} data['error'] = "User declined to share list" @@ -958,13 +419,11 @@ class WebBrowser extends LitElement { case actions.ADD_LIST_ITEMS: { const requiredFields = ['list_name', 'items'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -982,14 +441,11 @@ class WebBrowser extends LitElement { items: items } ) - if (res && res.action === 'accept') { - try { const body = { items: items, } - const bodyToString = JSON.stringify(body) response = await parentEpml.request('apiCall', { type: 'api', @@ -997,8 +453,8 @@ class WebBrowser extends LitElement { url: `/lists/${list_name}?apiKey=${this.getApiKey()}`, body: bodyToString, headers: { - 'Content-Type': 'application/json', - }, + 'Content-Type': 'application/json' + } }) } catch (error) { const data = {} @@ -1007,7 +463,6 @@ class WebBrowser extends LitElement { } finally { break } - } else { const data = {} data['error'] = "User declined add to list" @@ -1019,13 +474,11 @@ class WebBrowser extends LitElement { case actions.DELETE_LIST_ITEM: { const requiredFields = ['list_name', 'item'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -1043,24 +496,20 @@ class WebBrowser extends LitElement { item: item } ) - if (res && res.action === 'accept') { - try { const body = { - items: [item], + items: [item] } - const bodyToString = JSON.stringify(body) - response = await parentEpml.request('apiCall', { type: 'api', method: 'DELETE', url: `/lists/${list_name}?apiKey=${this.getApiKey()}`, body: bodyToString, headers: { - 'Content-Type': 'application/json', - }, + 'Content-Type': 'application/json' + } }) } catch (error) { const data = {} @@ -1069,7 +518,6 @@ class WebBrowser extends LitElement { } finally { break } - } else { const data = {} data['error'] = "User declined add to list" @@ -1089,13 +537,9 @@ class WebBrowser extends LitElement { actions.GET_FRIENDS_LIST ) } - - if (res1 && res1.action === 'accept' || skip) { - try { let list = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]") - list = list.map((friend) => friend.name || "") response = JSON.stringify(list) } catch (error) { @@ -1103,9 +547,7 @@ class WebBrowser extends LitElement { data['error'] = "Error in retrieving friends list" response = JSON.stringify(data) } - break - } else { const data = {} data['error'] = "User declined to share friends list" @@ -1122,39 +564,30 @@ class WebBrowser extends LitElement { this.displayUrl = translate("appspage.schange40") return } - let url = 'qortal://' + data.service + '/' + data.name - this.path = - data.path != null - ? (data.path.startsWith('/') ? '' : '/') + data.path - : null - if ( - data.identifier != null && - data.identifier != '' && - data.identifier != 'default' - ) + this.path = data.path != null ? (data.path.startsWith('/') ? '' : '/') + data.path : null + if (data.identifier != null && data.identifier != '' && data.identifier != 'default') { url = url.concat('/' + data.identifier) - if (this.path != null && this.path != '/') + } + if (this.path != null && this.path != '/') { url = url.concat(this.path) + } this.name = data.name this.service = data.service this.identifier = data.identifier this.displayUrl = url - const frame = window.frameElement - let tabId = "" + let tabId = '' if (frame && frame.dataset.id) { tabId = frame.dataset.id } - if (data.name === 'Q-Mail') { localStorage.setItem("Q-Mail-last-visited", Date.now()) - } window.parent.reduxStore.dispatch(window.parent.reduxAction.addTabInfo({ name: data.name, service: data.service, - id: tabId ? tabId : "" + id: tabId ? tabId : '' })) return @@ -1168,27 +601,23 @@ class WebBrowser extends LitElement { response['error'] = 'missing count' break } - window.parent.reduxStore.dispatch(window.parent.reduxAction.setTabNotifications({ name: this.name, count: count })) response = true break - } case actions.PUBLISH_QDN_RESOURCE: { // optional fields: encrypt:boolean recipientPublicKey:string const requiredFields = ['service', 'name'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -1221,7 +650,6 @@ class WebBrowser extends LitElement { if (data.identifier == null) { identifier = 'default' } - if (data.encrypt && (!data.publicKeys || (Array.isArray(data.publicKeys) && data.publicKeys.length === 0))) { let data = {} data['error'] = "Encrypting data requires public keys" @@ -1239,7 +667,6 @@ class WebBrowser extends LitElement { } const getArbitraryFee = await this.getArbitraryFee() feeAmount = getArbitraryFee.fee - if (data.encrypt) { try { const encryptDataResponse = encryptDataGroup({ @@ -1248,7 +675,6 @@ class WebBrowser extends LitElement { if (encryptDataResponse) { data64 = encryptDataResponse } - } catch (error) { const obj = {} obj['error'] = error.message || 'Upload failed due to failed encryption' @@ -1257,7 +683,6 @@ class WebBrowser extends LitElement { } } - const res2 = await showModalAndWait( actions.PUBLISH_QDN_RESOURCE, { @@ -1298,7 +723,6 @@ class WebBrowser extends LitElement { withFee: res2.userData.isWithFee === true, feeAmount: feeAmount }) - response = JSON.stringify(resPublish) worker.terminate() } catch (error) { @@ -1330,7 +754,6 @@ class WebBrowser extends LitElement { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -1368,7 +791,6 @@ class WebBrowser extends LitElement { feeAmount: getArbitraryFee.feeToShow } ) - if (res2.action === 'reject') { response = '{"error": "User declined request"}' break @@ -1380,13 +802,11 @@ class WebBrowser extends LitElement { try { const requiredFields = ['service', 'name'] const missingFields = [] - requiredFields.forEach((field) => { if (!resource[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -1396,7 +816,6 @@ class WebBrowser extends LitElement { }) continue } - if (!resource.file && !resource.data64) { const errorMsg = 'No data or file was submitted' failedPublishesIdentifiers.push({ @@ -1405,7 +824,6 @@ class WebBrowser extends LitElement { }) continue } - const service = resource.service const name = resource.name let identifier = resource.identifier @@ -1422,7 +840,6 @@ class WebBrowser extends LitElement { if (resource.identifier == null) { identifier = 'default' } - if (!data.encrypt && service.endsWith("_PRIVATE")) { const errorMsg = "Only encrypted data can go into private services" failedPublishesIdentifiers.push({ @@ -1434,18 +851,14 @@ class WebBrowser extends LitElement { if (data.file) { data64 = await fileToBase64(data.file) } - - if (data.encrypt) { try { - const encryptDataResponse = encryptDataGroup({ data64, publicKeys: data.publicKeys }) if (encryptDataResponse) { data64 = encryptDataResponse } - } catch (error) { const errorMsg = error.message || 'Upload failed due to failed encryption' failedPublishesIdentifiers.push({ @@ -1454,15 +867,12 @@ class WebBrowser extends LitElement { }) continue } - } if (resource.file && !data.encrypt) { data64 = await fileToBase64(resource.file) } - const worker = new WebWorker() try { - await publishData({ registeredName: encodeURIComponent(name), file: data64, @@ -1486,12 +896,11 @@ class WebBrowser extends LitElement { withFee: res2.userData.isWithFee === true, feeAmount: feeAmount }) - worker.terminate() await new Promise((res) => { setTimeout(() => { res() - }, 1000); + }, 1000) }) } catch (error) { worker.terminate() @@ -1501,16 +910,12 @@ class WebBrowser extends LitElement { identifier: resource.identifier }) } - } catch (error) { failedPublishesIdentifiers.push({ reason: "Unknown error", identifier: resource.identifier }) } - - - } this.loader.hide() if (failedPublishesIdentifiers.length > 0) { @@ -1523,23 +928,18 @@ class WebBrowser extends LitElement { this.loader.hide() break } - response = true break - - } case actions.VOTE_ON_POLL: { const requiredFields = ['pollName', 'optionIndex'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field] && data[field] !== 0) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -1548,15 +948,13 @@ class WebBrowser extends LitElement { response = JSON.stringify(data) break } - const pollName = data.pollName const optionIndex = data.optionIndex - let pollInfo = null try { pollInfo = await parentEpml.request("apiCall", { type: "api", - url: `/polls/${encodeURIComponent(pollName)}`, + url: `/polls/${encodeURIComponent(pollName)}` }) } catch (error) { const errorMsg = (error && error.message) || 'Poll not found' @@ -1565,7 +963,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - if (!pollInfo || pollInfo.error) { const errorMsg = (pollInfo && pollInfo.message) || 'Poll not found' let obj = {} @@ -1573,7 +970,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - try { this.loader.show() const resVoteOnPoll = await this._voteOnPoll(pollName, optionIndex) @@ -1585,20 +981,17 @@ class WebBrowser extends LitElement { } finally { this.loader.hide() } - break } case actions.CREATE_POLL: { const requiredFields = ['pollName', 'pollDescription', 'pollOptions', 'pollOwnerAddress'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -1607,12 +1000,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(data) break } - const pollName = data.pollName const pollDescription = data.pollDescription const pollOptions = data.pollOptions const pollOwnerAddress = data.pollOwnerAddress - try { this.loader.show() const resCreatePoll = await this._createPoll(pollName, pollDescription, pollOptions, pollOwnerAddress) @@ -1624,7 +1015,6 @@ class WebBrowser extends LitElement { } finally { this.loader.hide() } - break } @@ -1635,7 +1025,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - try { await this.linkOpenNewTab(data.qortalLink) response = true @@ -1647,12 +1036,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - } case actions.NOTIFICATIONS_PERMISSION: { try { - const res = await showModalAndWait( actions.NOTIFICATIONS_PERMISSION, { @@ -1667,11 +1054,9 @@ class WebBrowser extends LitElement { response = false break } - } catch (error) { break } - } case actions.SEND_LOCAL_NOTIFICATION: { @@ -1685,7 +1070,6 @@ class WebBrowser extends LitElement { const interval = appInfo.interval if (lastNotification && interval) { const timeDifference = Date.now() - lastNotification - if (timeDifference > interval) { parentEpml.request('showNotification', { title, type: "qapp-local-notification", sound: '', url, options: { body: message, icon, badge: icon } @@ -1706,29 +1090,25 @@ class WebBrowser extends LitElement { } else { throw new Error(`invalid data`) } - } catch (error) { const obj = {} obj['error'] = error.message || "error in pushing notification" response = JSON.stringify(obj) break - } - } + case actions.SEND_CHAT_MESSAGE: { const message = data.message const recipient = data.destinationAddress const groupId = data.groupId const isRecipient = !groupId const sendMessage = async (messageText, chatReference) => { - let _reference = new Uint8Array(64) window.crypto.getRandomValues(_reference) let reference = window.parent.Base58.encode(_reference) const sendMessageRequest = async () => { let chatResponse - if (isRecipient) { chatResponse = await parentEpml.request('chat', { type: 18, @@ -1746,10 +1126,7 @@ class WebBrowser extends LitElement { isText: 1 } }) - - } - if (!isRecipient) { chatResponse = await parentEpml.request('chat', { type: 181, @@ -1767,20 +1144,15 @@ class WebBrowser extends LitElement { isText: 1 } }) - - } - return await _computePow(chatResponse) } - const _computePow = async (chatBytes) => { const difficulty = 8 const path = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full' const worker = new WebWorkerChat() let nonce = null let chatBytesArray = null - await new Promise((res) => { worker.postMessage({ chatBytes, path, difficulty }) worker.onmessage = e => { @@ -1789,17 +1161,14 @@ class WebBrowser extends LitElement { res() } }) - let _response = await parentEpml.request('sign_chat', { nonce: this.selectedAddress.nonce, chatBytesArray: chatBytesArray, chatNonce: nonce, apiVersion: 2 }) - return getSendChatResponse(_response) } - const getSendChatResponse = (res) => { if (res.signature) { return res @@ -1809,22 +1178,18 @@ class WebBrowser extends LitElement { throw new Error('ERROR: Could not send message') } } - return await sendMessageRequest() } - const result = await showModalAndWait( actions.SEND_CHAT_MESSAGE ) if (result.action === "accept") { let hasPublicKey = true - if (isRecipient) { const res = await parentEpml.request('apiCall', { type: 'api', url: `/addresses/publickey/${recipient}` }) - if (res.error === 102) { this._publicKey.key = '' this._publicKey.hasPubKey = false @@ -1838,46 +1203,27 @@ class WebBrowser extends LitElement { hasPublicKey = false } } - - if (!hasPublicKey && isRecipient) { response = '{"error": "Cannot send an encrypted message to this user since they do not have their publickey on chain."}' break } - - - const tiptapJson = { type: 'doc', - content: [ - { - type: 'paragraph', - content: [ - { - type: 'text', - text: message, - }, - - ], - }, - ], + content: [{ + type: 'paragraph', + content: [{ + type: 'text', + text: message + }] + }] } - const messageObject = { messageText: tiptapJson, images: [''], repliedTo: '', version: 3 } - const stringifyMessageObject = JSON.stringify(messageObject) - // if (this.balance < 4) { - // this.myTrimmedMeassage = '' - // this.myTrimmedMeassage = stringifyMessageObject - // this.shadowRoot.getElementById('confirmDialog').open() - // } else { - // this.sendMessage(stringifyMessageObject, typeMessage) - // } try { this.loader.show() response = await sendMessage(stringifyMessageObject) @@ -1892,9 +1238,7 @@ class WebBrowser extends LitElement { response = '{"error": "Request could not be fulfilled"}' } finally { this.loader.hide() - } - } else { response = '{"error": "User declined request"}' } @@ -1909,13 +1253,11 @@ class WebBrowser extends LitElement { case actions.JOIN_GROUP: { const requiredFields = ['groupId'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -1925,13 +1267,11 @@ class WebBrowser extends LitElement { break } const groupId = data.groupId - - let groupInfo = null try { groupInfo = await parentEpml.request("apiCall", { type: "api", - url: `/groups/${groupId}`, + url: `/groups/${groupId}` }) } catch (error) { const errorMsg = (error && error.message) || 'Group not found' @@ -1940,7 +1280,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - if (!groupInfo || groupInfo.error) { const errorMsg = (groupInfo && groupInfo.message) || 'Group not found' let obj = {} @@ -1948,7 +1287,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - try { this.loader.show() const resJoinGroup = await this._joinGroup(groupId, groupInfo.groupName) @@ -1960,7 +1298,6 @@ class WebBrowser extends LitElement { } finally { this.loader.hide() } - // Params: data.groupId // TODO: prompt user to join group. If they confirm, sign+process a JOIN_GROUP transaction // then set the response string from the core to the `response` variable (defined above) @@ -1970,16 +1307,13 @@ class WebBrowser extends LitElement { case actions.SAVE_FILE: { try { - const requiredFields = ['filename', 'blob'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -1988,25 +1322,18 @@ class WebBrowser extends LitElement { response = JSON.stringify(data) break } - - - const filename = data.filename const blob = data.blob - const res = await showModalAndWait( actions.SAVE_FILE, { filename } ) - if (res.action === 'reject') { response = '{"error": "User declined request"}' break - } - const mimeType = blob.type || data.mimeType let backupExention = filename.split('.').pop() if (backupExention) { @@ -2033,7 +1360,6 @@ class WebBrowser extends LitElement { } } } - try { const fileHandle = await self.showSaveFilePicker({ suggestedName: filename, @@ -2041,10 +1367,8 @@ class WebBrowser extends LitElement { { description: mimeType, ...fileHandleOptions - }, + } ] - - }) const writeFile = async (fileHandle, contents) => { const writable = await fileHandle.createWritable() @@ -2061,7 +1385,6 @@ class WebBrowser extends LitElement { } FileSaver.saveAs(blob, filename) } - response = JSON.stringify(true) } catch (error) { const obj = {} @@ -2071,16 +1394,14 @@ class WebBrowser extends LitElement { break } - case 'DEPLOY_AT': { + case actions.DEPLOY_AT: { const requiredFields = ['name', 'description', 'tags', 'creationBytes', 'amount', 'assetId', 'type'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field] && data[field] !== 0) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -2089,11 +1410,8 @@ class WebBrowser extends LitElement { response = JSON.stringify(data) break } - - try { this.loader.show() - const resDeployAt = await this._deployAt(data.name, data.description, data.tags, data.creationBytes, data.amount, data.assetId, data.type) response = JSON.stringify(resDeployAt) } catch (error) { @@ -2106,27 +1424,23 @@ class WebBrowser extends LitElement { break } - case 'GET_PROFILE_DATA': { + case actions.GET_PROFILE_DATA: { const defaultProperties = ['tagline', 'bio', 'wallets'] - const requiredFields = ['property']; - const missingFields = []; - + const requiredFields = ['property'] + const missingFields = [] requiredFields.forEach((field) => { if (!data[field] && data[field] !== 0) { - missingFields.push(field); + missingFields.push(field) } - }); - + }) if (missingFields.length > 0) { - const missingFieldsString = missingFields.join(', '); + const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` - let data = {}; - data['error'] = errorMsg; - response = JSON.stringify(data); + let data = {} + data['error'] = errorMsg + response = JSON.stringify(data) break } - - try { const profileData = window.parent.reduxStore.getState().app.profileData if (!profileData) { @@ -2137,25 +1451,22 @@ class WebBrowser extends LitElement { if (propertyIndex !== -1) { const requestedData = profileData[property] if (requestedData) { - response = JSON.stringify(requestedData); + response = JSON.stringify(requestedData) break } else { throw new Error('Cannot find requested data') } } - if (property.includes('-private')) { const resPrivateProperty = await showModalAndWait( actions.GET_PROFILE_DATA, { - property - } - ); - + property + } + ) if (resPrivateProperty.action === 'accept') { - const requestedData = profileData.customData[property] if (requestedData) { - response = JSON.stringify(requestedData); + response = JSON.stringify(requestedData) break } else { throw new Error('Cannot find requested data') @@ -2166,42 +1477,38 @@ class WebBrowser extends LitElement { } else { const requestedData = profileData.customData[property] if (requestedData) { - response = JSON.stringify(requestedData); + response = JSON.stringify(requestedData) break } else { throw new Error('Cannot find requested data') } } - } catch (error) { - const obj = {}; - obj['error'] = error.message || 'Failed to join the group.'; - response = JSON.stringify(obj); + const obj = {} + obj['error'] = error.message || 'Failed to join the group.' + response = JSON.stringify(obj) } finally { - this.loader.hide(); + this.loader.hide() } - break; + break } - case 'SET_PROFILE_DATA': { - const requiredFields = ['property', 'data']; - const missingFields = []; + case actions.SET_PROFILE_DATA: { + const requiredFields = ['property', 'data'] + const missingFields = [] requiredFields.forEach((field) => { if (!data[field] && data[field] !== 0) { - missingFields.push(field); + missingFields.push(field) } - }); - + }) if (missingFields.length > 0) { - const missingFieldsString = missingFields.join(', '); + const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` - let data = {}; - data['error'] = errorMsg; - response = JSON.stringify(data); + let data = {} + data['error'] = errorMsg + response = JSON.stringify(data) break } - - try { const property = data.property const payload = data.data @@ -2209,16 +1516,12 @@ class WebBrowser extends LitElement { const fee = await this.getArbitraryFee() const resSetPrivateProperty = await showModalAndWait( actions.SET_PROFILE_DATA, { - property, - fee: fee.feeToShow - } - ); - - + property, + fee: fee.feeToShow + } + ) if (resSetPrivateProperty.action !== 'accept') throw new Error('User declined permission') - //dispatch event and wait until I get a response to continue - // Create and dispatch custom event const customEvent = new CustomEvent('qortal-request-set-profile-data', { detail: { @@ -2226,102 +1529,91 @@ class WebBrowser extends LitElement { payload, uniqueId } - }); - window.parent.dispatchEvent(customEvent); - + }) + window.parent.dispatchEvent(customEvent) // Wait for response event const res = await new Promise((resolve, reject) => { function handleResponseEvent(event) { // Handle the data from the event, if any - const responseData = event.detail; + const responseData = event.detail if (responseData && responseData.uniqueId !== uniqueId) return // Clean up by removing the event listener once we've received the response - window.removeEventListener('qortal-request-set-profile-data-response', handleResponseEvent); + window.removeEventListener('qortal-request-set-profile-data-response', handleResponseEvent) if (responseData.response === 'saved') { - resolve(responseData); + resolve(responseData) } else { - reject(new Error('not saved')); + reject(new Error('not saved')) } } - // Set up an event listener to wait for the response - window.addEventListener('qortal-request-set-profile-data-response', handleResponseEvent); - }); + window.addEventListener('qortal-request-set-profile-data-response', handleResponseEvent) + }) if (!res.response) throw new Error('Failed to set property') - response = JSON.stringify(res.response); - + response = JSON.stringify(res.response) } catch (error) { - const obj = {}; - obj['error'] = error.message || 'Failed to set property.'; - response = JSON.stringify(obj); + const obj = {} + obj['error'] = error.message || 'Failed to set property.' + response = JSON.stringify(obj) } finally { - this.loader.hide(); + this.loader.hide() } - break; + break } - case 'OPEN_PROFILE': { - const requiredFields = ['name']; - const missingFields = []; - + case actions.OPEN_PROFILE: { + const requiredFields = ['name'] + const missingFields = [] requiredFields.forEach((field) => { if (!data[field] && data[field] !== 0) { - missingFields.push(field); + missingFields.push(field) } - }); - + }) if (missingFields.length > 0) { - const missingFieldsString = missingFields.join(', '); + const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` - let data = {}; - data['error'] = errorMsg; - response = JSON.stringify(data); + let data = {} + data['error'] = errorMsg + response = JSON.stringify(data) break } - - try { const customEvent = new CustomEvent('open-visiting-profile', { detail: data.name - }); - window.parent.dispatchEvent(customEvent); - response = JSON.stringify(true); + }) + window.parent.dispatchEvent(customEvent) + response = JSON.stringify(true) } catch (error) { - const obj = {}; - obj['error'] = error.message || 'Failed to open profile'; - response = JSON.stringify(obj); + const obj = {} + obj['error'] = error.message || 'Failed to open profile' + response = JSON.stringify(obj) } - break; + break } - case actions.GET_USER_WALLET: { - const requiredFields = ['coin']; - const missingFields = []; - + const requiredFields = ['coin'] + const missingFields = [] requiredFields.forEach((field) => { if (!data[field]) { - missingFields.push(field); + missingFields.push(field) } - }); - + }) if (missingFields.length > 0) { - const missingFieldsString = missingFields.join(', '); + const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` - let data = {}; - data['error'] = errorMsg; - response = JSON.stringify(data); + let data = {} + data['error'] = errorMsg + response = JSON.stringify(data) break } const res3 = await showModalAndWait( actions.GET_USER_WALLET - ); - + ) if (res3.action === 'accept') { - let coin = data.coin; - let userWallet = {}; - let arrrAddress = ""; + let coin = data.coin + let userWallet = {} + let arrrAddress = "" if (coin === "ARRR") { arrrAddress = await parentEpml.request('apiCall', { url: `/crosschain/arrr/walletaddress?apiKey=${this.getApiKey()}`, @@ -2360,24 +1652,22 @@ class WebBrowser extends LitElement { default: break } - response = JSON.stringify(userWallet); - break; + response = JSON.stringify(userWallet) + break } else if (res3.action === 'reject') { - response = '{"error": "User declined request"}'; + response = '{"error": "User declined request"}' } - break; + break } case actions.GET_WALLET_BALANCE: { const requiredFields = ['coin'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -2393,7 +1683,6 @@ class WebBrowser extends LitElement { const res3 = await showModalAndWait( actions.GET_WALLET_BALANCE ) - if (res3.action === 'accept') { let coin = data.coin if (coin === "QORT") { @@ -2401,7 +1690,7 @@ class WebBrowser extends LitElement { try { this.loader.show() response = await parentEpml.request('apiCall', { - url: `/addresses/balance/${qortAddress}?apiKey=${this.getApiKey()}`, + url: `/addresses/balance/${qortAddress}?apiKey=${this.getApiKey()}` }) @@ -2417,7 +1706,6 @@ class WebBrowser extends LitElement { } else { let _url = `` let _body = null - switch (coin) { case 'BTC': _url = `/crosschain/btc/walletbalance?apiKey=${this.getApiKey()}` @@ -2451,7 +1739,7 @@ class WebBrowser extends LitElement { const res = await parentEpml.request('apiCall', { url: _url, method: 'POST', - body: _body, + body: _body }) if (isNaN(Number(res))) { const data = {} @@ -2474,19 +1762,17 @@ class WebBrowser extends LitElement { } else if (res3.action === 'reject') { response = '{"error": "User declined request"}' } - break } + case actions.GET_USER_WALLET_INFO: { const requiredFields = ['coin'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -2495,23 +1781,17 @@ class WebBrowser extends LitElement { response = JSON.stringify(data) break } - const userWallet = await showModalAndWait( actions.GET_USER_WALLET ) - if (userWallet.action === 'accept') { - let coin = data.coin; - let walletKeys = this.getUserWallet(coin); - + let coin = data.coin + let walletKeys = this.getUserWallet(coin) let _url = `/crosschain/` + data.coin.toLowerCase() + `/addressinfos?apiKey=${this.getApiKey()}` - let _body = { - xpub58: walletKeys['publickey'] - } - + let _body = { xpub58: walletKeys['publickey'] } try { this.loader.show() - const bodyToString = JSON.stringify(_body); + const bodyToString = JSON.stringify(_body) const res = await parentEpml.request('apiCall', { url: _url, method: 'POST', @@ -2519,9 +1799,9 @@ class WebBrowser extends LitElement { 'Accept': '*/*', 'Content-Type': 'application/json' }, - body: bodyToString, + body: bodyToString }) - response = JSON.stringify(res); + response = JSON.stringify(res) } catch (error) { console.error(error) const data = {} @@ -2534,20 +1814,16 @@ class WebBrowser extends LitElement { } else if (userWallet.action === 'reject') { response = '{"error": "User declined request"}' } - break } - case actions.GET_CROSSCHAIN_SERVER_INFO: { const requiredFields = ['coin'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -2556,7 +1832,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(data) break } - let _url = `/crosschain/` + data.coin.toLowerCase() + `/serverinfos` try { this.loader.show() @@ -2567,30 +1842,27 @@ class WebBrowser extends LitElement { 'Accept': '*/*' } }) - response = JSON.stringify(res.servers); + response = JSON.stringify(res.servers) } catch (error) { - console.error(error) - const data = {} + console.error(error) + const data = {} data['error'] = error.message || 'Error in retrieving server info' - response = JSON.stringify(data) - return - } finally { - this.loader.hide() - } - + response = JSON.stringify(data) + return + } finally { + this.loader.hide() + } break } case actions.GET_TX_ACTIVITY_SUMMARY: { const requiredFields = ['coin'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -2599,9 +1871,8 @@ class WebBrowser extends LitElement { response = JSON.stringify(data) break } - try { - let coin = data.coin; + let coin = data.coin response = await parentEpml.request('apiCall', { type: 'api', method: 'POST', @@ -2609,7 +1880,7 @@ class WebBrowser extends LitElement { headers: { 'Accept': '*/*', 'Content-Type': 'application/json' - }, + } }) } catch (error) { const data = {} @@ -2620,11 +1891,87 @@ class WebBrowser extends LitElement { } } + case actions.GET_FOREIGN_FEE: { + const requiredFields = ['coin','type'] + const missingFields = [] + requiredFields.forEach((field) => { + if (!data[field]) { + missingFields.push(field) + } + }) + if (missingFields.length > 0) { + const missingFieldsString = missingFields.join(', ') + const errorMsg = `Missing fields: ${missingFieldsString}` + let data = {} + data['error'] = errorMsg + response = JSON.stringify(data) + break + } + try { + let coin = data.coin; + let type = data.type; + response = await parentEpml.request('apiCall', { + type: 'api', + method: 'GET', + url: `/crosschain/${coin}/${type}?apiKey=${this.getApiKey()}`, + headers: { + 'Accept': '*/*', + 'Content-Type': 'application/json' + }, + }) + } catch (error) { + const data = {} + data['error'] = "Error in get foreign fee" + response = JSON.stringify(data) + } finally { + break + } + } + + case actions.UPDATE_FOREIGN_FEE: { + const requiredFields = ['coin','type'] + const missingFields = [] + requiredFields.forEach((field) => { + if (!data[field]) { + missingFields.push(field) + } + }) + if (missingFields.length > 0) { + const missingFieldsString = missingFields.join(', ') + const errorMsg = `Missing fields: ${missingFieldsString}` + let data = {} + data['error'] = errorMsg + response = JSON.stringify(data) + break + } + try { + let coin = data.coin; + let type = data.type; + let value = data.value; + response = await parentEpml.request('apiCall', { + type: 'api', + method: 'POST', + url: `/crosschain/${coin}/update${type}?apiKey=${this.getApiKey()}`, + headers: { + 'Accept': '*/*', + 'Content-Type': 'application/json' + }, + body: `${value}` + }) + } catch (error) { + const data = {} + data['error'] = "Error in update foreign fee" + response = JSON.stringify(data) + } finally { + break + } + } + case actions.GET_DAY_SUMMARY: { try { response = await parentEpml.request('apiCall', { type: 'api', - url: `/admin/summary?apiKey=${this.getApiKey()}`, + url: `/admin/summary?apiKey=${this.getApiKey()}` }) } catch (error) { const data = {} @@ -2638,13 +1985,11 @@ class WebBrowser extends LitElement { case actions.SEND_COIN: { const requiredFields = ['coin', 'destinationAddress', 'amount'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -2654,9 +1999,7 @@ class WebBrowser extends LitElement { response = JSON.stringify(data) break } - let checkCoin = data.coin - if (checkCoin === "QORT") { // Params: data.coin, data.destinationAddress, data.amount, data.fee // TODO: prompt user to send. If they confirm, call `POST /crosschain/:coin/send`, or for QORT, broadcast a PAYMENT transaction @@ -2665,11 +2008,9 @@ class WebBrowser extends LitElement { const amount = Number(data.amount) const recipient = data.destinationAddress const coin = data.coin - const walletBalance = await parentEpml.request('apiCall', { - url: `/addresses/balance/${this.myAddress.address}`, + url: `/addresses/balance/${this.myAddress.address}` }) - if (isNaN(Number(walletBalance))) { let errorMsg = "Failed to Fetch QORT Balance. Try again!" let failedMsg = get("walletpage.wchange33") + " QORT " + get("general.balance") @@ -2680,18 +2021,15 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - const myRef = await parentEpml.request("apiCall", { type: "api", - url: `/addresses/lastreference/${this.myAddress.address}`, + url: `/addresses/lastreference/${this.myAddress.address}` }) - const transformDecimals = (Number(walletBalance) * QORT_DECIMALS).toFixed(0) const walletBalanceDecimals = Number(transformDecimals) const amountDecimals = Number(amount) * QORT_DECIMALS const balance = (Number(transformDecimals) / 1e8).toFixed(8) const fee = await this.sendQortFee() - if (amountDecimals + (fee * QORT_DECIMALS) > walletBalanceDecimals) { let errorMsg = "Insufficient Funds!" let failedMsg = get("walletpage.wchange26") @@ -2702,7 +2040,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - if (amount <= 0) { let errorMsg = "Invalid Amount!" await showErrorAndWait("INVALID_AMOUNT", errorMsg) @@ -2711,7 +2048,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - if (recipient.length === 0) { let errorMsg = "Receiver cannot be empty!" await showErrorAndWait("NO_RECEIVER", errorMsg) @@ -2720,7 +2056,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - const processPayment = await showModalAndWait( actions.SEND_COIN, { @@ -2731,7 +2066,6 @@ class WebBrowser extends LitElement { fee } ) - if (processPayment.action === 'reject') { let errorMsg = "User declined request" let myMsg1 = get("transactions.declined") @@ -2740,14 +2074,12 @@ class WebBrowser extends LitElement { response = '{"error": "User declined request"}' break } - const validateName = async (receiverName) => { let myRes let myNameRes = await parentEpml.request('apiCall', { type: 'api', - url: `/names/${receiverName}`, + url: `/names/${receiverName}` }) - if (myNameRes.error === 401) { myRes = false } else { @@ -2755,21 +2087,17 @@ class WebBrowser extends LitElement { } return myRes } - const validateAddress = async (receiverAddress) => { return await window.parent.validateAddress(receiverAddress) } - const validateReceiver = async (recipient) => { let lastRef = myRef let isAddress - try { isAddress = await validateAddress(recipient) } catch (err) { isAddress = false } - if (isAddress) { let myTransaction = await makeTransactionRequest(recipient, lastRef) return getTxnRequestResponse(myTransaction) @@ -2787,26 +2115,22 @@ class WebBrowser extends LitElement { } } } - const getName = async (recipient) => { try { const getNames = await parentEpml.request("apiCall", { type: "api", url: `/names/address/${recipient}` }) - if (getNames.length > 0) { return getNames[0].name } else { return '' } } catch (error) { - return "" + return '' } } - this.loader.show() - const makeTransactionRequest = async (receiver, lastRef) => { let myReceiver = receiver let mylastRef = lastRef @@ -2832,7 +2156,6 @@ class WebBrowser extends LitElement { apiVersion: 2 }) } - const getTxnRequestResponse = (txnResponse) => { if (txnResponse.success === false && txnResponse.message) { this.loader.hide() @@ -2844,9 +2167,7 @@ class WebBrowser extends LitElement { this.loader.hide() throw new Error('Error: could not send coin') } - } - try { response = await validateReceiver(recipient) } catch (error) { @@ -2863,13 +2184,11 @@ class WebBrowser extends LitElement { const coin = data.coin const xprv58 = this.btcWallet.derivedMasterPrivateKey const feePerByte = data.fee ? data.fee : this.btcFeePerByte - const btcWalletBalance = await parentEpml.request('apiCall', { url: `/crosschain/btc/walletbalance?apiKey=${this.getApiKey()}`, method: 'POST', body: `${this.btcWallet.derivedMasterPublicKey}` }) - if (isNaN(Number(btcWalletBalance))) { this.loader.hide() let errorMsg = "Failed to Fetch BTC Balance. Try again!" @@ -2881,12 +2200,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - const btcWalletBalanceDecimals = Number(btcWalletBalance) const btcAmountDecimals = Number(amount) * QORT_DECIMALS const balance = (Number(btcWalletBalance) / 1e8).toFixed(8) const fee = feePerByte * 500 // default 0.00050000 - if (btcAmountDecimals + (fee * QORT_DECIMALS) > btcWalletBalanceDecimals) { this.loader.hide() let errorMsg = "Insufficient Funds!" @@ -2898,9 +2215,7 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - this.loader.hide() - const processPayment = await showModalAndWait( actions.SEND_COIN, { @@ -2911,7 +2226,6 @@ class WebBrowser extends LitElement { fee } ) - if (processPayment.action === 'reject') { let errorMsg = "User declined request" let myMsg1 = get("transactions.declined") @@ -2920,9 +2234,7 @@ class WebBrowser extends LitElement { response = '{"error": "User declined request"}' break } - this.loader.show() - const makeRequest = async () => { const opts = { xprv58: xprv58, @@ -2932,7 +2244,6 @@ class WebBrowser extends LitElement { } return await parentEpml.request('sendBtc', opts) } - const manageResponse = (response) => { if (response.length === 64) { this.loader.hide() @@ -2953,7 +2264,6 @@ class WebBrowser extends LitElement { throw new Error(response) } } - try { const res = await makeRequest() manageResponse(res) @@ -2972,13 +2282,11 @@ class WebBrowser extends LitElement { const coin = data.coin const xprv58 = this.ltcWallet.derivedMasterPrivateKey const feePerByte = data.fee ? data.fee : this.ltcFeePerByte - const ltcWalletBalance = await parentEpml.request('apiCall', { url: `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}`, method: 'POST', body: `${this.ltcWallet.derivedMasterPublicKey}` }) - if (isNaN(Number(ltcWalletBalance))) { this.loader.hide() let errorMsg = "Failed to Fetch LTC Balance. Try again!" @@ -2990,12 +2298,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - const ltcWalletBalanceDecimals = Number(ltcWalletBalance) const ltcAmountDecimals = Number(amount) * QORT_DECIMALS const balance = (Number(ltcWalletBalance) / 1e8).toFixed(8) const fee = feePerByte * 1000 // default 0.00030000 - if (ltcAmountDecimals + (fee * QORT_DECIMALS) > ltcWalletBalanceDecimals) { this.loader.hide() let errorMsg = "Insufficient Funds!" @@ -3007,9 +2313,7 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - this.loader.hide() - const processPayment = await showModalAndWait( actions.SEND_COIN, { @@ -3020,7 +2324,6 @@ class WebBrowser extends LitElement { fee } ) - if (processPayment.action === 'reject') { let errorMsg = "User declined request" let myMsg1 = get("transactions.declined") @@ -3029,9 +2332,7 @@ class WebBrowser extends LitElement { response = '{"error": "User declined request"}' break } - this.loader.show() - const makeRequest = async () => { const opts = { xprv58: xprv58, @@ -3041,7 +2342,6 @@ class WebBrowser extends LitElement { } return await parentEpml.request('sendLtc', opts) } - const manageResponse = (response) => { if (response.length === 64) { this.loader.hide() @@ -3062,7 +2362,6 @@ class WebBrowser extends LitElement { throw new Error(response) } } - try { const res = await makeRequest() manageResponse(res) @@ -3081,13 +2380,11 @@ class WebBrowser extends LitElement { const coin = data.coin const xprv58 = this.dogeWallet.derivedMasterPrivateKey const feePerByte = data.fee ? data.fee : this.dogeFeePerByte - const dogeWalletBalance = await parentEpml.request('apiCall', { url: `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}`, method: 'POST', body: `${this.dogeWallet.derivedMasterPublicKey}` }) - if (isNaN(Number(dogeWalletBalance))) { this.loader.hide() let errorMsg = "Failed to Fetch DOGE Balance. Try again!" @@ -3099,12 +2396,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - const dogeWalletBalanceDecimals = Number(dogeWalletBalance) const dogeAmountDecimals = Number(amount) * QORT_DECIMALS const balance = (Number(dogeWalletBalance) / 1e8).toFixed(8) const fee = feePerByte * 5000 // default 0.05000000 - if (dogeAmountDecimals + (fee * QORT_DECIMALS) > dogeWalletBalanceDecimals) { this.loader.hide() let errorMsg = "Insufficient Funds!" @@ -3116,9 +2411,7 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - this.loader.hide() - const processPayment = await showModalAndWait( actions.SEND_COIN, { @@ -3129,7 +2422,6 @@ class WebBrowser extends LitElement { fee } ) - if (processPayment.action === 'reject') { let errorMsg = "User declined request" let myMsg1 = get("transactions.declined") @@ -3138,9 +2430,7 @@ class WebBrowser extends LitElement { response = '{"error": "User declined request"}' break } - this.loader.show() - const makeRequest = async () => { const opts = { xprv58: xprv58, @@ -3150,7 +2440,6 @@ class WebBrowser extends LitElement { } return await parentEpml.request('sendDoge', opts) } - const manageResponse = (response) => { if (response.length === 64) { this.loader.hide() @@ -3171,7 +2460,6 @@ class WebBrowser extends LitElement { throw new Error(response) } } - try { const res = await makeRequest() manageResponse(res) @@ -3190,13 +2478,11 @@ class WebBrowser extends LitElement { const coin = data.coin const xprv58 = this.dgbWallet.derivedMasterPrivateKey const feePerByte = data.fee ? data.fee : this.dgbFeePerByte - const dgbWalletBalance = await parentEpml.request('apiCall', { url: `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}`, method: 'POST', body: `${this.dgbWallet.derivedMasterPublicKey}` }) - if (isNaN(Number(dgbWalletBalance))) { this.loader.hide() let errorMsg = "Failed to Fetch DGB Balance. Try again!" @@ -3208,12 +2494,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - const dgbWalletBalanceDecimals = Number(dgbWalletBalance) const dgbAmountDecimals = Number(amount) * QORT_DECIMALS const balance = (Number(dgbWalletBalance) / 1e8).toFixed(8) const fee = feePerByte * 500 // default 0.00005000 - if (dgbAmountDecimals + (fee * QORT_DECIMALS) > dgbWalletBalanceDecimals) { this.loader.hide() let errorMsg = "Insufficient Funds!" @@ -3225,9 +2509,7 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - this.loader.hide() - const processPayment = await showModalAndWait( actions.SEND_COIN, { @@ -3238,7 +2520,6 @@ class WebBrowser extends LitElement { fee } ) - if (processPayment.action === 'reject') { let errorMsg = "User declined request" let myMsg1 = get("transactions.declined") @@ -3247,9 +2528,7 @@ class WebBrowser extends LitElement { response = '{"error": "User declined request"}' break } - this.loader.show() - const makeRequest = async () => { const opts = { xprv58: xprv58, @@ -3259,7 +2538,6 @@ class WebBrowser extends LitElement { } return await parentEpml.request('sendDgb', opts) } - const manageResponse = (response) => { if (response.length === 64) { this.loader.hide() @@ -3280,7 +2558,6 @@ class WebBrowser extends LitElement { throw new Error(response) } } - try { const res = await makeRequest() manageResponse(res) @@ -3299,13 +2576,11 @@ class WebBrowser extends LitElement { const coin = data.coin const xprv58 = this.rvnWallet.derivedMasterPrivateKey const feePerByte = data.fee ? data.fee : this.rvnFeePerByte - const rvnWalletBalance = await parentEpml.request('apiCall', { url: `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}`, method: 'POST', body: `${this.rvnWallet.derivedMasterPublicKey}` }) - if (isNaN(Number(rvnWalletBalance))) { this.loader.hide() let errorMsg = "Failed to Fetch RVN Balance. Try again!" @@ -3317,12 +2592,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - const rvnWalletBalanceDecimals = Number(rvnWalletBalance) const rvnAmountDecimals = Number(amount) * QORT_DECIMALS const balance = (Number(rvnWalletBalance) / 1e8).toFixed(8) const fee = feePerByte * 500 // default 0.00562500 - if (rvnAmountDecimals + (fee * QORT_DECIMALS) > rvnWalletBalanceDecimals) { this.loader.hide() let errorMsg = "Insufficient Funds!" @@ -3334,9 +2607,7 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - this.loader.hide() - const processPayment = await showModalAndWait( actions.SEND_COIN, { @@ -3347,7 +2618,6 @@ class WebBrowser extends LitElement { fee } ) - if (processPayment.action === 'reject') { let errorMsg = "User declined request" let myMsg1 = get("transactions.declined") @@ -3356,9 +2626,7 @@ class WebBrowser extends LitElement { response = '{"error": "User declined request"}' break } - this.loader.show() - const makeRequest = async () => { const opts = { xprv58: xprv58, @@ -3368,7 +2636,6 @@ class WebBrowser extends LitElement { } return await parentEpml.request('sendRvn', opts) } - const manageResponse = (response) => { if (response.length === 64) { this.loader.hide() @@ -3389,7 +2656,6 @@ class WebBrowser extends LitElement { throw new Error(response) } } - try { const res = await makeRequest() manageResponse(res) @@ -3408,13 +2674,11 @@ class WebBrowser extends LitElement { const coin = data.coin const memo = data.memo const seed58 = this.arrrWallet.seed58 - const arrrWalletBalance = await parentEpml.request('apiCall', { url: `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}`, method: 'POST', body: `${this.arrrWallet.seed58}` }) - if (isNaN(Number(arrrWalletBalance))) { this.loader.hide() let errorMsg = "Failed to Fetch ARRR Balance. Try again!" @@ -3426,12 +2690,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - const arrrWalletBalanceDecimals = Number(arrrWalletBalance) const arrrAmountDecimals = Number(amount) * QORT_DECIMALS const balance = (Number(arrrWalletBalance) / 1e8).toFixed(8) const fee = 0.00010000 - if (arrrAmountDecimals + (fee * QORT_DECIMALS) > arrrWalletBalanceDecimals) { this.loader.hide() let errorMsg = "Insufficient Funds!" @@ -3443,9 +2705,7 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - this.loader.hide() - const processPayment = await showModalAndWait( actions.SEND_COIN, { @@ -3456,7 +2716,6 @@ class WebBrowser extends LitElement { fee } ) - if (processPayment.action === 'reject') { let errorMsg = "User declined request" let myMsg1 = get("transactions.declined") @@ -3465,9 +2724,7 @@ class WebBrowser extends LitElement { response = '{"error": "User declined request"}' break } - this.loader.show() - const makeRequest = async () => { const opts = { entropy58: seed58, @@ -3477,7 +2734,6 @@ class WebBrowser extends LitElement { } return await parentEpml.request('sendArrr', opts) } - const manageResponse = (response) => { if (response.length === 64) { this.loader.hide() @@ -3498,7 +2754,6 @@ class WebBrowser extends LitElement { throw new Error(response) } } - try { const res = await makeRequest() manageResponse(res) @@ -3513,7 +2768,7 @@ class WebBrowser extends LitElement { break } } - break; + break default: console.log('Unhandled message: ' + JSON.stringify(data)) return @@ -3531,24 +2786,446 @@ class WebBrowser extends LitElement { if (responseObj.error != null) { event.ports[0].postMessage({ result: null, - error: responseObj, + error: responseObj }) } else { event.ports[0].postMessage({ result: responseObj, - error: null, + error: null }) } }) + this.clearConsole() + setInterval(() => { this.clearConsole() }, 60000) } - getUserWallet(coin) { - let userWallet = {}; + renderFullScreen() { + if (window.innerHeight == screen.height) { + return html` + this.exitFullScreen()} + title="${translate('browserpage.bchange38')}" + class="address-bar-button float-right" + > + fullscreen_exit + + ` + } else { + return html` + this.goFullScreen()} + title="${translate('browserpage.bchange37')}" + class="address-bar-button float-right" + > + fullscreen + + ` + } + } + goFullScreen() { + var elem = this.shadowRoot.getElementById('websitesWrapper') + if (elem.requestFullscreen) { + elem.requestFullscreen() + } else if (elem.mozRequestFullScreen) { + elem.mozRequestFullScreen() + } else if (elem.webkitRequestFullscreen) { + elem.webkitRequestFullscreen() + } else if (elem.msRequestFullscreen) { + elem.msRequestFullscreen() + } + this.renderFullScreen() + } + + exitFullScreen() { + if (document.exitFullscreen) { + document.exitFullscreen() + } else if (document.mozCancelFullScreen) { + document.mozCancelFullScreen() + } else if (document.webkitExitFullscreen) { + document.webkitExitFullscreen() + } else if (document.msExitFullscreen) { + document.msExitFullscreen() + } + this.renderFullScreen() + } + + async unitJoinFee() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/transactions/unitfee?txType=JOIN_GROUP` + const response = await fetch(url) + if (!response.ok) { + throw new Error('Error when fetching join fee') + } + const data = await response.json() + return (Number(data) / 1e8).toFixed(8) + } + + async deployAtFee() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/transactions/unitfee?txType=DEPLOY_AT` + const response = await fetch(url) + if (!response.ok) { + throw new Error('Error when fetching join fee') + } + const data = await response.json() + return (Number(data) / 1e8).toFixed(8) + } + + async getArbitraryFee() { + const timestamp = Date.now() + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/transactions/unitfee?txType=ARBITRARY×tamp=${timestamp}` + const response = await fetch(url) + if (!response.ok) { + throw new Error('Error when fetching arbitrary fee') + } + const data = await response.json() + const arbitraryFee = (Number(data) / 1e8).toFixed(8) + return { + timestamp, + fee: Number(data), + feeToShow: arbitraryFee + } + } + async sendQortFee() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/transactions/unitfee?txType=PAYMENT` + const response = await fetch(url) + if (!response.ok) { + throw new Error('Error when fetching join fee') + } + const data = await response.json() + return (Number(data) / 1e8).toFixed(8) + } + + async unitVoteFee() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/transactions/unitfee?txType=VOTE_ON_POLL` + const response = await fetch(url) + if (!response.ok) { + throw new Error('Error when fetching vote fee') + } + const data = await response.json() + return (Number(data) / 1e8).toFixed(8) + } + + async unitCreatePollFee() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/transactions/unitfee?txType=CREATE_POLL` + const response = await fetch(url) + if (!response.ok) { + throw new Error('Error when fetching vote fee') + } + const data = await response.json() + return (Number(data) / 1e8).toFixed(8) + } + + async _joinGroup(groupId, groupName) { + const joinFeeInput = await this.unitJoinFee() + const getLastRef = async () => { + return await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/lastreference/${this.selectedAddress.address}` + }) + } + const validateReceiver = async () => { + let lastRef = await getLastRef() + let myTransaction = await makeTransactionRequest(lastRef) + return getTxnRequestResponse(myTransaction) + } + const makeTransactionRequest = async (lastRef) => { + let groupdialog1 = get("transactions.groupdialog1") + let groupdialog2 = get("transactions.groupdialog2") + return await parentEpml.request('transaction', { + type: 31, + nonce: this.selectedAddress.nonce, + params: { + fee: joinFeeInput, + registrantAddress: this.selectedAddress.address, + rGroupName: groupName, + rGroupId: groupId, + lastReference: lastRef, + groupdialog1: groupdialog1, + groupdialog2: groupdialog2 + }, + apiVersion: 2 + }) + } + const getTxnRequestResponse = (txnResponse) => { + if (txnResponse.success === false && txnResponse.message) { + throw new Error(txnResponse.message) + } else if (txnResponse.success === true && !txnResponse.data.error) { + return txnResponse.data + } else if (txnResponse.data && txnResponse.data.message) { + throw new Error(txnResponse.data.message) + } else { + throw new Error('Server error. Could not perform action.') + } + } + return await validateReceiver() + } + + async _deployAt(name, description, tags, creationBytes, amount, assetId, atType) { + const deployAtFee = await this.deployAtFee() + const getLastRef = async () => { + return await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/lastreference/${this.selectedAddress.address}` + }) + } + const validateReceiver = async () => { + let lastRef = await getLastRef() + let myTransaction = await makeTransactionRequest(lastRef) + return getTxnRequestResponse(myTransaction) + } + const makeTransactionRequest = async (lastRef) => { + let deployAtdialog1 = get("transactions.deployAtdialog1") + let deployAtdialog2 = get("transactions.deployAtdialog2") + let deployAtdialog3 = get("transactions.deployAtdialog3") + let deployAtdialog4 = get("walletpage.wchange12") + return await parentEpml.request('transaction', { + type: 16, + nonce: this.selectedAddress.nonce, + params: { + fee: deployAtFee, + rName: name, + rDescription: description, + rTags: tags, + rAmount: amount, + rAssetId: assetId, + rCreationBytes: creationBytes, + atType: atType, + lastReference: lastRef, + atDeployDialog1: deployAtdialog1, + atDeployDialog2: deployAtdialog2, + atDeployDialog3: deployAtdialog3, + atDeployDialog4: deployAtdialog4 + }, + apiVersion: 2 + }) + } + const getTxnRequestResponse = (txnResponse) => { + if (txnResponse.success === false && txnResponse.message) { + throw new Error(txnResponse.message) + } else if (txnResponse.success === true && !txnResponse.data.error) { + return txnResponse.data + } else if (txnResponse.data && txnResponse.data.message) { + throw new Error(txnResponse.data.message) + } else { + throw new Error('Server error. Could not perform action.') + } + } + return await validateReceiver() + } + + async _voteOnPoll(pollName, optionIndex) { + const voteFeeInput = await this.unitVoteFee() + const getLastRef = async () => { + return await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/lastreference/${this.selectedAddress.address}` + }) + } + const validateReceiver = async () => { + let lastRef = await getLastRef() + let myTransaction = await makeTransactionRequest(lastRef) + return getTxnRequestResponse(myTransaction) + } + const makeTransactionRequest = async (lastRef) => { + let votedialog1 = get("transactions.votedialog1") + let votedialog2 = get("transactions.votedialog2") + let feeDialog = get("walletpage.wchange12") + + return await parentEpml.request('transaction', { + type: 9, + nonce: this.selectedAddress.nonce, + params: { + fee: voteFeeInput, + voterAddress: this.selectedAddress.address, + rPollName: pollName, + rOptionIndex: optionIndex, + lastReference: lastRef, + votedialog1: votedialog1, + votedialog2: votedialog2, + feeDialog + }, + apiVersion: 2 + }) + } + const getTxnRequestResponse = (txnResponse) => { + if (txnResponse.success === false && txnResponse.message) { + throw new Error(txnResponse.message) + } else if (txnResponse.success === true && !txnResponse.data.error) { + return txnResponse.data + } else if (txnResponse.data && txnResponse.data.message) { + throw new Error(txnResponse.data.message) + } else { + throw new Error('Server error. Could not perform action.') + } + } + return await validateReceiver() + } + + async _createPoll(pollName, pollDescription, options, pollOwnerAddress) { + const voteFeeInput = await this.unitCreatePollFee() + const getLastRef = async () => { + return await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/lastreference/${this.selectedAddress.address}` + }) + } + const validateReceiver = async () => { + let lastRef = await getLastRef() + let myTransaction = await makeTransactionRequest(lastRef) + return getTxnRequestResponse(myTransaction) + } + const makeTransactionRequest = async (lastRef) => { + let votedialog3 = get("transactions.votedialog3") + let votedialog4 = get("transactions.votedialog4") + let votedialog5 = get("transactions.votedialog5") + let votedialog6 = get("transactions.votedialog6") + let feeDialog = get("walletpage.wchange12") + return await parentEpml.request('transaction', { + type: 8, + nonce: this.selectedAddress.nonce, + params: { + fee: voteFeeInput, + ownerAddress: pollOwnerAddress, + rPollName: pollName, + rPollDesc: pollDescription, + rOptions: options, + lastReference: lastRef, + votedialog3: votedialog3, + votedialog4: votedialog4, + votedialog5: votedialog5, + votedialog6: votedialog6, + feeDialog + }, + apiVersion: 2 + }) + } + const getTxnRequestResponse = (txnResponse) => { + if (txnResponse.success === false && txnResponse.message) { + throw new Error(txnResponse.message) + } else if (txnResponse.success === true && !txnResponse.data.error) { + return txnResponse.data + } else if (txnResponse.data && txnResponse.data.message) { + throw new Error(txnResponse.data.message) + } else { + throw new Error('Server error. Could not perform action.') + } + } + return await validateReceiver() + } + + async extractComponents(url) { + if (!url.startsWith("qortal://")) { + return null + } + url = url.replace(/^(qortal\:\/\/)/, "") + if (url.includes("/")) { + let parts = url.split("/") + const service = parts[0].toUpperCase() + parts.shift() + const name = parts[0] + parts.shift() + let identifier + if (parts.length > 0) { + identifier = parts[0] // Do not shift yet + // Check if a resource exists with this service, name and identifier combination + let responseObj = await parentEpml.request('apiCall', { + url: `/arbitrary/resource/status/${service}/${name}/${identifier}?apiKey=${this.getApiKey()}` + }) + + if (responseObj.totalChunkCount > 0) { + // Identifier exists, so don't include it in the path + parts.shift() + } + else { + identifier = null + } + } + const path = parts.join("/") + const components = {} + components["service"] = service + components["name"] = name + components["identifier"] = identifier + components["path"] = path + return components + } + return null + } + + async _handleKeyDown(e) { + if (e.key === 'Enter') { + let newQuery = e.target.value + if (newQuery.endsWith('/')) { + newQuery = newQuery.slice(0, -1) + } + const res = await this.extractComponents(newQuery) + if (!res) return + const { service, name, identifier, path } = res + let query = `?service=${service}` + if (name) { + query = query + `&name=${name}` + } + if (identifier) { + query = query + `&identifier=${identifier}` + } + if (path) { + query = query + `&path=${path}` + } + window.location = window.location.origin + window.location.pathname + query + } + } + + async linkOpenNewTab(link) { + let newQuery = link + if (newQuery.endsWith('/')) { + newQuery = newQuery.slice(0, -1) + } + const res = await this.extractComponents(newQuery) + if (!res) return + const { service, name, identifier, path } = res + let query = `?service=${service}` + if (name) { + query = query + `&name=${name}` + } + if (identifier) { + query = query + `&identifier=${identifier}` + } + if (path) { + query = query + `&path=${path}` + } + window.parent.reduxStore.dispatch(window.parent.reduxAction.setNewTab({ + url: `qdn/browser/index.html${query}`, + id: this.uid.rnd(), + myPlugObj: { + "url": service === 'WEBSITE' ? "websites" : "qapps", + "domain": "core", + "page": `qdn/browser/index.html${query}`, + "title": name, + "icon": service === 'WEBSITE' ? 'vaadin:desktop' : 'vaadin:external-browser', + "mwcicon": service === 'WEBSITE' ? 'desktop_mac' : 'open_in_browser', + "menus": [], + "parent": false + } + })) + } + + getUserWallet(coin) { + let userWallet = {} switch (coin) { case 'QORT': userWallet['address'] = window.parent.reduxStore.getState().app.selectedAddress.address @@ -3579,7 +3256,7 @@ class WebBrowser extends LitElement { default: break } - return userWallet; + return userWallet } clearConsole() { @@ -3602,7 +3279,6 @@ class WebBrowser extends LitElement { changeLanguage() { const checkLanguage = localStorage.getItem('qortalLanguage') - if (checkLanguage === null || checkLanguage.length === 0) { localStorage.setItem('qortalLanguage', 'us') use('us') @@ -3615,20 +3291,19 @@ class WebBrowser extends LitElement { if (!appName) throw new Error('unknown app name') const id = `appNotificationList-${this.selectedAddress.address}` const checkData = localStorage.getItem(id) ? JSON.parse(localStorage.getItem(id)) : null - if (!checkData) { const newData = { [appName]: { interval: 900000, // 15mins in milliseconds - lastNotification: null, - }, + lastNotification: null + } } localStorage.setItem(id, JSON.stringify(newData)) } else { const copyData = { ...checkData } copyData[appName] = { interval: 900000, // 15mins in milliseconds - lastNotification: null, + lastNotification: null } localStorage.setItem(id, JSON.stringify(copyData)) } @@ -3636,7 +3311,6 @@ class WebBrowser extends LitElement { updateLastNotification(id, appName) { const checkData = localStorage.getItem(id) ? JSON.parse(localStorage.getItem(id)) : null - if (checkData) { const copyData = { ...checkData } if (copyData[appName]) { @@ -3644,7 +3318,7 @@ class WebBrowser extends LitElement { } else { copyData[appName] = { interval: 900000, // 15mins in milliseconds - lastNotification: Date.now(), + lastNotification: Date.now() } } localStorage.setItem(id, JSON.stringify(copyData)) @@ -3657,23 +3331,28 @@ class WebBrowser extends LitElement { if (this.followedNames == null || !Array.isArray(this.followedNames)) { return html`` } - if (this.followedNames.indexOf(this.name) === -1) { // render follow button - return html` this.follow()} - title="${translate('browserpage.bchange7')} ${this.name}" - class="address-bar-button float-right" - >add_to_queue` + return html` + this.follow()} + title="${translate('browserpage.bchange7')} ${this.name}" + class="address-bar-button float-right" + > + add_to_queue + + ` } else { // render unfollow button - return html` this.unfollow()} - title="${translate('browserpage.bchange8')} ${this.name}" - class="address-bar-button float-right" - >remove_from_queue` + return html` + this.unfollow()} + title="${translate('browserpage.bchange8')} ${this.name}" + class="address-bar-button float-right" + > + remove_from_queue + + ` } } @@ -3682,28 +3361,32 @@ class WebBrowser extends LitElement { if (this.blockedNames == null || !Array.isArray(this.blockedNames)) { return html`` } - if (this.blockedNames.indexOf(this.name) === -1) { // render block button - return html` this.block()} - title="${translate('browserpage.bchange9')} ${this.name}" - class="address-bar-button float-right" - >block` + return html` + this.block()} + title="${translate('browserpage.bchange9')} ${this.name}" + class="address-bar-button float-right" + > + block + + ` } else { // render unblock button - return html` this.unblock()} - title="${translate('browserpage.bchange10')} ${this.name}" - class="address-bar-button float-right" - >radio_button_unchecked` + return html` + this.unblock()} + title="${translate('browserpage.bchange10')} ${this.name}" + class="address-bar-button float-right" + > + radio_button_unchecked + + ` } } // Navigation - goBack() { window.history.back() } @@ -3718,9 +3401,7 @@ class WebBrowser extends LitElement { if (this.dev === 'FRAMEWORK') { this.url = `${this.link}?time=${new Date().getMilliseconds()}` } else { - this.url = `${nodeUrl}/render/${this.service}/${this.name}${this.path != null ? this.path : '' - }?theme=${this.theme}&identifier=${this.identifier != null ? this.identifier : '' - }&time=${new Date().getMilliseconds()}` + this.url = `${nodeUrl}/render/${this.service}/${this.name}${this.path != null ? this.path : ''}?theme=${this.theme}&identifier=${this.identifier != null ? this.identifier : ''}&time=${new Date().getMilliseconds()}` } } @@ -3731,7 +3412,7 @@ class WebBrowser extends LitElement { } else { // Default to websites list this.exitFullScreen() - window.location = '../index.html' + window.location = '../../q-website/index.html' } } @@ -3758,16 +3439,14 @@ class WebBrowser extends LitElement { async followName(name) { let items = [name] let namesJsonString = JSON.stringify({ items: items }) - let ret = await parentEpml.request('apiCall', { url: `/lists/followedNames?apiKey=${this.getApiKey()}`, method: 'POST', headers: { - 'Content-Type': 'application/json', + 'Content-Type': 'application/json' }, - body: `${namesJsonString}`, + body: `${namesJsonString}` }) - if (ret === true) { // Successfully followed - add to local list // Remove it first by filtering the list - doing it this way ensures the UI updates @@ -3780,23 +3459,20 @@ class WebBrowser extends LitElement { let err1string = get('browserpage.bchange11') parentEpml.request('showSnackBar', `${err1string}`) } - return ret } async unfollowName(name) { let items = [name] let namesJsonString = JSON.stringify({ items: items }) - let ret = await parentEpml.request('apiCall', { url: `/lists/followedNames?apiKey=${this.getApiKey()}`, method: 'DELETE', headers: { - 'Content-Type': 'application/json', + 'Content-Type': 'application/json' }, - body: `${namesJsonString}`, + body: `${namesJsonString}` }) - if (ret === true) { // Successfully unfollowed - remove from local list this.followedNames = this.followedNames.filter( @@ -3806,23 +3482,20 @@ class WebBrowser extends LitElement { let err2string = get('browserpage.bchange12') parentEpml.request('showSnackBar', `${err2string}`) } - return ret } async blockName(name) { let items = [name] let namesJsonString = JSON.stringify({ items: items }) - let ret = await parentEpml.request('apiCall', { url: `/lists/blockedNames?apiKey=${this.getApiKey()}`, method: 'POST', headers: { - 'Content-Type': 'application/json', + 'Content-Type': 'application/json' }, - body: `${namesJsonString}`, + body: `${namesJsonString}` }) - if (ret === true) { // Successfully blocked - add to local list // Remove it first by filtering the list - doing it this way ensures the UI updates @@ -3835,33 +3508,27 @@ class WebBrowser extends LitElement { let err3string = get('browserpage.bchange13') parentEpml.request('showSnackBar', `${err3string}`) } - return ret } async unblockName(name) { let items = [name] let namesJsonString = JSON.stringify({ items: items }) - let ret = await parentEpml.request('apiCall', { url: `/lists/blockedNames?apiKey=${this.getApiKey()}`, method: 'DELETE', headers: { - 'Content-Type': 'application/json', + 'Content-Type': 'application/json' }, - body: `${namesJsonString}`, + body: `${namesJsonString}` }) - if (ret === true) { // Successfully unblocked - remove from local list - this.blockedNames = this.blockedNames.filter( - (item) => item != name - ) + this.blockedNames = this.blockedNames.filter((item) => item != name) } else { let err4string = get('browserpage.bchange14') parentEpml.request('showSnackBar', `${err4string}`) } - return ret } @@ -3872,32 +3539,34 @@ class WebBrowser extends LitElement { parentEpml.request('showSnackBar', `${err5string}`) return } - let identifier = (this.identifier == null || this.identifier.length == 0) ? 'default' : this.identifier - let ret = await parentEpml.request('apiCall', { - url: `/arbitrary/resource/${this.service}/${this.name - }/${identifier}?apiKey=${this.getApiKey()}`, - method: 'DELETE', + url: `/arbitrary/resource/${this.service}/${this.name}/${identifier}?apiKey=${this.getApiKey()}`, + method: 'DELETE' }) - if (ret === true) { this.goBackToList() } else { let err6string = get('browserpage.bchange16') parentEpml.request('showSnackBar', `${err6string}`) } - return ret } + // Standard functions getApiKey() { - const myNode = - window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] return myNode.apiKey } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } window.customElements.define('web-browser', WebBrowser) @@ -3913,7 +3582,6 @@ async function showModalAndWait(type, data) {
    -

    ${translate('sponsorshipspage.schange6')}

    @@ -236,10 +235,9 @@ class SponsorshipList extends LitElement { dialogAction='cancel' class='red' > - ${translate('general.close')} + ${translate('general.close')} -
    @@ -303,7 +301,7 @@ class SponsorshipList extends LitElement { `}
    { this.openDialogRewardShare = false this.errorMessage = '' @@ -311,12 +309,11 @@ class SponsorshipList extends LitElement { this.privateRewardShareKey = '' this.atMount() }} - class='red' - > - ${translate('general.close')} + class='red' + > + ${translate('general.close')} -

    ${translate('sponsorshipspage.schange10')}

    @@ -345,13 +342,13 @@ class SponsorshipList extends LitElement { this.lookUpPublicAddressFunc() }}' > - ${translate('sponsorshipspage.schange10')} + ${translate('sponsorshipspage.schange10')}
    ${this.lookupPublicAddressValue ? html`
    ${this.lookupPublicAddressValue} -
    +
    - ${translate('general.close')} + ${translate('general.close')}
    @@ -409,11 +406,12 @@ class SponsorshipList extends LitElement { }) } + this.clearConsole() + setInterval(() => { this.atMount() }, 180000) - this.clearConsole() setInterval(() => { this.clearConsole() }, 60000) @@ -480,11 +478,6 @@ class SponsorshipList extends LitElement { this.saveToClipboard(this.privateRewardShareKey, `${copystring1}`) } - getApiKey() { - const apiNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - return apiNode.apiKey - } - async atMount() { this.addressInfo = window.parent.reduxStore.getState().app.accountInfo.addressInfo this.isPageLoading = true @@ -505,7 +498,9 @@ class SponsorshipList extends LitElement { type: 'api', url: `/names/address/${rs.recipient}` }) + let url = '' + if(getNames.length > 0 ) { const avatarNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] const avatarUrl = avatarNode.protocol + '://' + avatarNode.domain + ':' + avatarNode.port @@ -519,7 +514,7 @@ class SponsorshipList extends LitElement { ...rs, name: getNames.length > 0 ? getNames[0].name : '', url, - blocksRemaining: blocksRemaining, + blocksRemaining: blocksRemaining } }) @@ -562,7 +557,6 @@ class SponsorshipList extends LitElement { } async removeRewardShare(rewardShareObject) { - const selectedAddress = window.parent.reduxStore.getState().app.selectedAddress const myPercentageShare = -1 @@ -601,8 +595,8 @@ class SponsorshipList extends LitElement { percentageShare: myPercentageShare, lastReference: mylastRef, rewarddialog5: rewarddialog5, - rewarddialog6: rewarddialog6, - }, + rewarddialog6: rewarddialog6 + } }) } @@ -611,10 +605,7 @@ class SponsorshipList extends LitElement { this.removeRewardShareLoading = false parentEpml.request('showSnackBar', txnResponse.message) throw new Error(txnResponse) - } else if ( - txnResponse.success === true && - !txnResponse.data.error - ) { + } else if (txnResponse.success === true && !txnResponse.data.error) { let err7tring = get('rewardsharepage.rchange22') this.removeRewardShareLoading = false parentEpml.request('showSnackBar', `${err7tring}`) @@ -625,6 +616,7 @@ class SponsorshipList extends LitElement { throw new Error(txnResponse) } } + await removeReceiver() } @@ -704,38 +696,37 @@ class SponsorshipList extends LitElement { rewarddialog1: rewarddialog1, rewarddialog2: rewarddialog2, rewarddialog3: rewarddialog3, - rewarddialog4: rewarddialog4, + rewarddialog4: rewarddialog4 }, disableModal: true }) } const getTxnRequestResponse = (txnResponse) => { + const extraData = txnResponse && txnResponse.extraData + const data = txnResponse && txnResponse.data + const dataMessage = data && data.message + const extraDataPrivateKey = extraData && extraData.rewardSharePrivateKey + const txnSuccess = txnResponse && txnResponse.success - const extraData = txnResponse && txnResponse.extraData; - const data = txnResponse && txnResponse.data; - const dataMessage = data && data.message; - const extraDataPrivateKey = extraData && extraData.rewardSharePrivateKey; - const txnSuccess = txnResponse && txnResponse.success; - - if (extraDataPrivateKey && typeof dataMessage === 'string' && - (dataMessage.includes('multiple') || dataMessage.includes('SELF_SHARE_EXISTS'))) { - this.privateRewardShareKey = extraDataPrivateKey; - this.confirmRelationship(publicKeyValue, isCopy); + if (extraDataPrivateKey && typeof dataMessage === 'string' && (dataMessage.includes('multiple') || dataMessage.includes('SELF_SHARE_EXISTS'))) { + this.privateRewardShareKey = extraDataPrivateKey + this.confirmRelationship(publicKeyValue, isCopy) } else if (txnSuccess === false && txnResponse.message) { - this.errorMessage = txnResponse.message; - this.isLoadingCreateSponsorship = false; - throw new Error(txnResponse.message); + this.errorMessage = txnResponse.message + this.isLoadingCreateSponsorship = false + throw new Error(txnResponse.message) } else if (txnSuccess === true && !(data && data.error)) { - this.privateRewardShareKey = extraDataPrivateKey; - this.confirmRelationship(publicKeyValue, isCopy); + this.privateRewardShareKey = extraDataPrivateKey + this.confirmRelationship(publicKeyValue, isCopy) } else { - const defaultErrorMessage = 'An unknown error occurred.'; - this.errorMessage = dataMessage || txnResponse.message || defaultErrorMessage; - this.isLoadingCreateSponsorship = false; - throw new Error(dataMessage || txnResponse.message || defaultErrorMessage); + const defaultErrorMessage = 'An unknown error occurred.' + this.errorMessage = dataMessage || txnResponse.message || defaultErrorMessage + this.isLoadingCreateSponsorship = false + throw new Error(dataMessage || txnResponse.message || defaultErrorMessage) } } + await validateReceiver() } @@ -745,13 +736,13 @@ class SponsorshipList extends LitElement { let stop = false const getAnswer = async () => { - if (!stop) { stop= true try { const recipientAddress = window.parent.base58PublicKeyToAddress(recipientPublicKey) const minterAddress = window.parent.reduxStore.getState().app.selectedAddress.address + const myRewardShareArray = await parentEpml.request('apiCall', { type: 'api', url: `/addresses/rewardshares?minters=${minterAddress}&recipients=${recipientAddress}` @@ -767,16 +758,19 @@ class SponsorshipList extends LitElement { stop = false } } + interval = setInterval(getAnswer, 5000) } async lookUpPublicAddressFunc() { this.errorLookup = '' + try { const response = await parentEpml.request('apiCall', { type: 'api', url: `/addresses/publickey/${this.lookupAddressValue}` }) + if(response.error) { throw(response.message) } @@ -785,6 +779,21 @@ class SponsorshipList extends LitElement { this.errorLookup = error } } + + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } -window.customElements.define('sponsorship-list', SponsorshipList) +window.customElements.define('sponsorship-list', SponsorshipList) \ No newline at end of file diff --git a/plugins/plugins/core/streams/AddressWatcher.js b/plugins/plugins/core/streams/AddressWatcher.js index c2411aa6..771b5f5b 100644 --- a/plugins/plugins/core/streams/AddressWatcher.js +++ b/plugins/plugins/core/streams/AddressWatcher.js @@ -1,4 +1,4 @@ -import {parentEpml} from '../connect.js' +import { parentEpml } from '../connect' // Tests to see if a block or transaction should trigger an address reload...but we're not doing that yet, because of no time for good testing const transactionTests = [] @@ -7,73 +7,73 @@ const blockTests = [] const DEFAULT_ADDRESS_INFO = {} transactionTests.push((tx, addr) => { - return tx.recipient === addr || tx.sender === addr + return tx.recipient === addr || tx.sender === addr }) blockTests.push((block, addr) => { - return block.generator === addr + return block.generator === addr }) export class AddressWatcher { - constructor(addresses) { - addresses = addresses || [] - this.reset() + constructor(addresses) { + addresses = addresses || [] + this.reset() - addresses.forEach(addr => this.addAddress(addr)) - } + addresses.forEach(addr => this.addAddress(addr)) + } - reset() { - this._addresses = {} - this._addressStreams = {} - } + reset() { + this._addresses = {} + this._addressStreams = {} + } - // Adds an address to watch - addAddress(address) { - const addr = address.address - this._addresses[addr] = address + // Adds an address to watch + addAddress(address) { + const addr = address.address + this._addresses[addr] = address - this._addressStreams[addr] = new EpmlStream(`address/${addr}`, () => this._addresses[addr]) + this._addressStreams[addr] = new EpmlStream(`address/${addr}`, () => this._addresses[addr]) - this.updateAddress(addr) - } + this.updateAddress(addr) + } - async testBlock(block) { - const pendingUpdateAddresses = [] - const transactions = await parentEpml.request('apiCall', { url: `/transactions/block/${block.signature}` }) - transactions.forEach(transaction => { - // Guess the block needs transactions - for (const addr of Object.keys(this._addresses)) { - const addrChanged = true // Just update it every block...for now - if (!addrChanged) return + async testBlock(block) { + const pendingUpdateAddresses = [] + const transactions = await parentEpml.request('apiCall', { url: `/transactions/block/${block.signature}` }) + transactions.forEach(transaction => { + // Guess the block needs transactions + for (const addr of Object.keys(this._addresses)) { + const addrChanged = true // Just update it every block...for now + if (!addrChanged) return - if (!(addr in pendingUpdateAddresses)) pendingUpdateAddresses.push(addr) - /** - * In the future transactions are potentially stored from here...and address is updated excluding transactions...and also somehow manage tx pages... - * Probably will just make wallet etc. listen for address change and then do the api call itself. If tx. page is on, say, page 3...and there's a new transaction... - * it will refresh, changing the "page" to have 1 extra transaction at the top and losing 1 at the bottom (pushed to next page) - */ - } - }) - pendingUpdateAddresses.forEach(addr => this.updateAddress(addr)) - } + if (!(addr in pendingUpdateAddresses)) pendingUpdateAddresses.push(addr) + /** + * In the future transactions are potentially stored from here...and address is updated excluding transactions...and also somehow manage tx pages... + * Probably will just make wallet etc. listen for address change and then do the api call itself. If tx. page is on, say, page 3...and there's a new transaction... + * it will refresh, changing the "page" to have 1 extra transaction at the top and losing 1 at the bottom (pushed to next page) + */ + } + }) + pendingUpdateAddresses.forEach(addr => this.updateAddress(addr)) + } - async updateAddress(addr) { - let addressRequest = await parentEpml.request('apiCall', { - type: 'explorer', - data: { - addr: addr, - txOnPage: 10 - } - }) - const addressInfo = addressRequest.success ? addressRequest.data : DEFAULT_ADDRESS_INFO - addressInfo.transactions = [] + async updateAddress(addr) { + let addressRequest = await parentEpml.request('apiCall', { + type: 'explorer', + data: { + addr: addr, + txOnPage: 10 + } + }) + const addressInfo = addressRequest.success ? addressRequest.data : DEFAULT_ADDRESS_INFO + addressInfo.transactions = [] - for (let i = addressInfo.start; i >= addressInfo.end; i--) { - addressInfo.transactions.push(addressInfo[i]) - delete addressInfo[i] - } - if (!(addr in this._addresses)) return - this._addresses[addr] = addressInfo - this._addressStreams[addr].emit(addressInfo) - } -} + for (let i = addressInfo.start; i >= addressInfo.end; i--) { + addressInfo.transactions.push(addressInfo[i]) + delete addressInfo[i] + } + if (!(addr in this._addresses)) return + this._addresses[addr] = addressInfo + this._addressStreams[addr].emit(addressInfo) + } +} \ No newline at end of file diff --git a/plugins/plugins/core/streams/UnconfirmedTransactionWatcher.js b/plugins/plugins/core/streams/UnconfirmedTransactionWatcher.js index 528ada42..59181c2e 100644 --- a/plugins/plugins/core/streams/UnconfirmedTransactionWatcher.js +++ b/plugins/plugins/core/streams/UnconfirmedTransactionWatcher.js @@ -1,46 +1,46 @@ -import {parentEpml} from '../connect.js' +import { parentEpml } from '../connect' export class UnconfirmedTransactionWatcher { - constructor() { - this._unconfirmedTransactionStreams = {} - this.reset() // Sets defaults + constructor() { + this._unconfirmedTransactionStreams = {} + this.reset() // Sets defaults - setInterval(() => { - Object.entries(this._addresses).forEach((addr) => this._addressTransactionCheck(addr[0])) - }, 10 * 1000) - } + setInterval(() => { + Object.entries(this._addresses).forEach((addr) => this._addressTransactionCheck(addr[0])) + }, 10 * 1000) + } - reset() { - this._addresses = {} - this._addressesUnconfirmedTransactions = {} - } + reset() { + this._addresses = {} + this._addressesUnconfirmedTransactions = {} + } - // Adds an address to watch - addAddress(address) { - const addr = address.address - this._addresses[addr] = address - this._addressesUnconfirmedTransactions[addr] = [] - if (this._unconfirmedTransactionStreams[addr]) return - this._unconfirmedTransactionStreams[addr] = new EpmlStream(`unconfirmedOfAddress/${addr}`, () => this._addressesUnconfirmedTransactions[addr]) - } + // Adds an address to watch + addAddress(address) { + const addr = address.address + this._addresses[addr] = address + this._addressesUnconfirmedTransactions[addr] = [] + if (this._unconfirmedTransactionStreams[addr]) return + this._unconfirmedTransactionStreams[addr] = new EpmlStream(`unconfirmedOfAddress/${addr}`, () => this._addressesUnconfirmedTransactions[addr]) + } - check() { - const c = this._addressTransactionCheck() - .then(() => setTimeout(() => this.check(), 5000)) - .catch(() => setTimeout(() => this.check(), 5000)) - } + check() { + const c = this._addressTransactionCheck() + .then(() => setTimeout(() => this.check(), 5000)) + .catch(() => setTimeout(() => this.check(), 5000)) + } - async _addressTransactionCheck() { - return Promise.all(Object.keys(this._addresses).map(addr => { - return parentEpml.request('apiCall', { - type: 'api', - url: `/transactions/unconfirmed` - }).then(unconfirmedTransactions => { - unconfirmedTransactions.filter(tx => { - tx.creatorAddress === addr || tx.recipient === addr - }) - this._unconfirmedTransactionStreams[addr].emit(unconfirmedTransactions) - }) - })) - } -} + async _addressTransactionCheck() { + return Promise.all(Object.keys(this._addresses).map(addr => { + return parentEpml.request('apiCall', { + type: 'api', + url: `/transactions/unconfirmed` + }).then(unconfirmedTransactions => { + unconfirmedTransactions.filter(tx => { + tx.creatorAddress === addr || tx.recipient === addr + }) + this._unconfirmedTransactionStreams[addr].emit(unconfirmedTransactions) + }) + })) + } +} \ No newline at end of file diff --git a/plugins/plugins/core/streams/onNewBlock.js b/plugins/plugins/core/streams/onNewBlock.js index 70b4068d..dda6e70f 100644 --- a/plugins/plugins/core/streams/onNewBlock.js +++ b/plugins/plugins/core/streams/onNewBlock.js @@ -1,6 +1,7 @@ -import {parentEpml} from '../connect.js' -const MIN_RECONNECT_INTERVAL = 1000; // 1 second -const MAX_RECONNECT_INTERVAL = 60000; // 1 minute +import { parentEpml } from '../connect' + +const MIN_RECONNECT_INTERVAL = 1000 // 1 second +const MAX_RECONNECT_INTERVAL = 60000 // 1 minute let socketObject let activeBlockSocketTimeout @@ -15,227 +16,242 @@ let nodeStatusRetryOnClose = false let nodeStateCall = false let isLoggedIn = false let oldAccountInfo -let blockSocketReconnectInterval = MIN_RECONNECT_INTERVAL; -let nodeStatusSocketReconnectInterval = MIN_RECONNECT_INTERVAL; +let blockSocketReconnectInterval = MIN_RECONNECT_INTERVAL +let nodeStatusSocketReconnectInterval = MIN_RECONNECT_INTERVAL parentEpml.subscribe('logged_in', loggedIn => { - isLoggedIn = loggedIn === 'true'; + isLoggedIn = loggedIn === 'true' }) - const setAccountInfo = async (addr) => { - const names = await parentEpml.request('apiCall', { - url: `/names/address/${addr}` - }) - const addressInfo = await parentEpml.request('apiCall', { - url: `/addresses/${addr}` - }) - let accountInfo = { - names: names, - addressInfo: addressInfo - } - if (window.parent._.isEqual(oldAccountInfo, accountInfo) === true) { + const names = await parentEpml.request('apiCall', { + url: `/names/address/${addr}` + }) - } else { - parentEpml.request('setAccountInfo', accountInfo) - oldAccountInfo = accountInfo - } + const addressInfo = await parentEpml.request('apiCall', { + url: `/addresses/${addr}` + }) + + let accountInfo = { + names: names, + addressInfo: addressInfo + } + + if (window.parent._.isEqual(oldAccountInfo, accountInfo) === true) { + } else { + parentEpml.request('setAccountInfo', accountInfo) + oldAccountInfo = accountInfo + } } const doNodeInfo = async () => { - const nodeInfo = await parentEpml.request('apiCall', { - url: '/admin/info' - }) - parentEpml.request('updateNodeInfo', nodeInfo) + const nodeInfo = await parentEpml.request('apiCall', { + url: '/admin/info' + }) + + parentEpml.request('updateNodeInfo', nodeInfo) } let initStateCount = 0 let oldState const closeSockets = () => { - socketObject.close() - closeGracefully = true - nodeStatusSocketObject.close() - nodeStatusSocketcloseGracefully = true + socketObject.close() + closeGracefully = true + nodeStatusSocketObject.close() + nodeStatusSocketcloseGracefully = true } export const startConfigWatcher = () => { - parentEpml.ready().then(() => { - parentEpml.subscribe('node_config', c => { - if (initStateCount === 0) { - let _oldState = JSON.parse(c) - oldState = { node: _oldState.node, knownNodes: _oldState.knownNodes } - initStateCount = initStateCount + 1 - nodeStateCall = true - isCalled = true - socketObject !== undefined ? closeSockets() : undefined - nodeStatusSocketObject !== undefined ? closeSockets() : undefined - initNodeStatusCall(oldState) - pingactiveBlockSocket() - // Call doNodeInfo - doNodeInfo() - } - let _newState = JSON.parse(c) - let newState = { node: _newState.node, knownNodes: _newState.knownNodes } - if (window.parent._.isEqual(oldState, newState) === true) { + parentEpml.ready().then(() => { + parentEpml.subscribe('node_config', c => { + if (initStateCount === 0) { + let _oldState = JSON.parse(c) + oldState = { node: _oldState.node, knownNodes: _oldState.knownNodes } + initStateCount = initStateCount + 1 + nodeStateCall = true + isCalled = true + socketObject !== undefined ? closeSockets() : undefined + nodeStatusSocketObject !== undefined ? closeSockets() : undefined + initNodeStatusCall(oldState) + pingactiveBlockSocket() + // Call doNodeInfo + doNodeInfo() + } - } else { - oldState = newState - nodeStateCall = true - isCalled = true - socketObject !== undefined ? closeSockets() : undefined - nodeStatusSocketObject !== undefined ? closeSockets() : undefined - initNodeStatusCall(newState) - pingactiveBlockSocket() - // Call doNodeInfo - doNodeInfo() - } - }) - }) - parentEpml.imReady() + let _newState = JSON.parse(c) + let newState = { node: _newState.node, knownNodes: _newState.knownNodes } + + if (window.parent._.isEqual(oldState, newState) === true) { + } else { + oldState = newState + nodeStateCall = true + isCalled = true + socketObject !== undefined ? closeSockets() : undefined + nodeStatusSocketObject !== undefined ? closeSockets() : undefined + initNodeStatusCall(newState) + pingactiveBlockSocket() + // Call doNodeInfo + doNodeInfo() + } + }) + }) + + parentEpml.imReady() } const processBlock = (blockObject) => { - parentEpml.request('updateBlockInfo', blockObject) + parentEpml.request('updateBlockInfo', blockObject) } const doNodeStatus = async (nodeStatusObject) => { - parentEpml.request('updateNodeStatus', nodeStatusObject) + parentEpml.request('updateNodeStatus', nodeStatusObject) } const initNodeStatusCall = (nodeConfig) => { - if (nodeConfig.node >= 0) { - pingNodeStatusSocket() - } else if (nodeStatusSocketObject !== undefined) { - nodeStatusSocketObject.close() - nodeStatusSocketcloseGracefully = true - } else { - // ... - } + if (nodeConfig.node >= 0) { + pingNodeStatusSocket() + } else if (nodeStatusSocketObject !== undefined) { + nodeStatusSocketObject.close() + nodeStatusSocketcloseGracefully = true + } else { + // ... + } } function attemptReconnectBlockSocket() { - setTimeout(() => { - initBlockSocket(); - blockSocketReconnectInterval = Math.min(blockSocketReconnectInterval * 2, MAX_RECONNECT_INTERVAL); - }, blockSocketReconnectInterval); + setTimeout(() => { + initBlockSocket() + blockSocketReconnectInterval = Math.min(blockSocketReconnectInterval * 2, MAX_RECONNECT_INTERVAL) + }, blockSocketReconnectInterval) } function attemptReconnectNodeStatusSocket() { - setTimeout(() => { - initNodeStatusSocket(); - nodeStatusSocketReconnectInterval = Math.min(nodeStatusSocketReconnectInterval * 2, MAX_RECONNECT_INTERVAL); - }, nodeStatusSocketReconnectInterval); + setTimeout(() => { + initNodeStatusSocket() + nodeStatusSocketReconnectInterval = Math.min(nodeStatusSocketReconnectInterval * 2, MAX_RECONNECT_INTERVAL) + }, nodeStatusSocketReconnectInterval) } - const initBlockSocket = () => { - let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - let nodeUrl = myNode.domain + ":" + myNode.port - let activeBlockSocketLink - if (window.parent.location.protocol === "https:") { - activeBlockSocketLink = `wss://${nodeUrl}/websockets/blocks` - } else { - activeBlockSocketLink = `ws://${nodeUrl}/websockets/blocks` - } - const activeBlockSocket = new WebSocket(activeBlockSocketLink) - // Open Connection - activeBlockSocket.onopen = (e) => { - blockSocketReconnectInterval = MIN_RECONNECT_INTERVAL; - closeGracefully = false - socketObject = activeBlockSocket - } - // Message Event - activeBlockSocket.onmessage = (e) => { - processBlock(JSON.parse(e.data)) - if (isLoggedIn) { - // Call Set Account Info... - setAccountInfo(window.parent.reduxStore.getState().app.selectedAddress.address) - } - } - // Closed Event - activeBlockSocket.onclose = () => { - processBlock({}); - blockFirstCall = true; - attemptReconnectBlockSocket(); - }; - // Error Event - activeBlockSocket.onerror = (e) => { - blockFirstCall = true - processBlock({}) - } - if (blockFirstCall) { - parentEpml.request('apiCall', { - url: '/blocks/last' - }).then(res => { - processBlock(res) - blockFirstCall = false - }) - } + let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + let nodeUrl = myNode.domain + ":" + myNode.port + let activeBlockSocketLink + + if (window.parent.location.protocol === "https:") { + activeBlockSocketLink = `wss://${nodeUrl}/websockets/blocks` + } else { + activeBlockSocketLink = `ws://${nodeUrl}/websockets/blocks` + } + + const activeBlockSocket = new WebSocket(activeBlockSocketLink) + + // Open Connection + activeBlockSocket.onopen = (e) => { + blockSocketReconnectInterval = MIN_RECONNECT_INTERVAL + closeGracefully = false + socketObject = activeBlockSocket + } + + // Message Event + activeBlockSocket.onmessage = (e) => { + processBlock(JSON.parse(e.data)) + if (isLoggedIn) { + // Call Set Account Info... + setAccountInfo(window.parent.reduxStore.getState().app.selectedAddress.address) + } + } + + // Closed Event + activeBlockSocket.onclose = () => { + processBlock({}) + blockFirstCall = true + attemptReconnectBlockSocket() + } + + // Error Event + activeBlockSocket.onerror = (e) => { + blockFirstCall = true + processBlock({}) + } + + if (blockFirstCall) { + parentEpml.request('apiCall', { + url: '/blocks/last' + }).then(res => { + processBlock(res) + blockFirstCall = false + }) + } } const pingactiveBlockSocket = () => { - if (isCalled) { - isCalled = false - initBlockSocket() - activeBlockSocketTimeout = setTimeout(pingactiveBlockSocket, 295000) - } else if (retryOnClose) { - retryOnClose = false - clearTimeout(activeBlockSocketTimeout) - initBlockSocket() - isCalled = true - activeBlockSocketTimeout = setTimeout(pingactiveBlockSocket, 295000) - } else { - socketObject.send("non-integer ping") - activeBlockSocketTimeout = setTimeout(pingactiveBlockSocket, 295000) - } + if (isCalled) { + isCalled = false + initBlockSocket() + activeBlockSocketTimeout = setTimeout(pingactiveBlockSocket, 295000) + } else if (retryOnClose) { + retryOnClose = false + clearTimeout(activeBlockSocketTimeout) + initBlockSocket() + isCalled = true + activeBlockSocketTimeout = setTimeout(pingactiveBlockSocket, 295000) + } else { + socketObject.send("non-integer ping") + activeBlockSocketTimeout = setTimeout(pingactiveBlockSocket, 295000) + } } const initNodeStatusSocket = () => { - let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - let nodeUrl = myNode.domain + ":" + myNode.port - let activeNodeStatusSocketLink - if (window.parent.location.protocol === "https:") { - activeNodeStatusSocketLink = `wss://${nodeUrl}/websockets/admin/status` - } else { - activeNodeStatusSocketLink = `ws://${nodeUrl}/websockets/admin/status` - } - const activeNodeStatusSocket = new WebSocket(activeNodeStatusSocketLink) - // Open Connection - activeNodeStatusSocket.onopen = (e) => { - nodeStatusSocketReconnectInterval = MIN_RECONNECT_INTERVAL; + let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + let nodeUrl = myNode.domain + ":" + myNode.port + let activeNodeStatusSocketLink - nodeStatusSocketcloseGracefully = false - nodeStatusSocketObject = activeNodeStatusSocket - } - // Message Event - activeNodeStatusSocket.onmessage = (e) => { - doNodeStatus(JSON.parse(e.data)) - } - // Closed Event - activeNodeStatusSocket.onclose = () => { - doNodeStatus({}); - attemptReconnectNodeStatusSocket(); - }; - // Error Event - activeNodeStatusSocket.onerror = (e) => { - doNodeStatus({}) - } + if (window.parent.location.protocol === "https:") { + activeNodeStatusSocketLink = `wss://${nodeUrl}/websockets/admin/status` + } else { + activeNodeStatusSocketLink = `ws://${nodeUrl}/websockets/admin/status` + } + + const activeNodeStatusSocket = new WebSocket(activeNodeStatusSocketLink) + + // Open Connection + activeNodeStatusSocket.onopen = (e) => { + nodeStatusSocketReconnectInterval = MIN_RECONNECT_INTERVAL + nodeStatusSocketcloseGracefully = false + nodeStatusSocketObject = activeNodeStatusSocket + } + + // Message Event + activeNodeStatusSocket.onmessage = (e) => { + doNodeStatus(JSON.parse(e.data)) + } + + // Closed Event + activeNodeStatusSocket.onclose = () => { + doNodeStatus({}) + attemptReconnectNodeStatusSocket() + } + + // Error Event + activeNodeStatusSocket.onerror = (e) => { + doNodeStatus({}) + } } const pingNodeStatusSocket = () => { - if (nodeStateCall) { - clearTimeout(nodeStatusSocketTimeout) - initNodeStatusSocket() - nodeStateCall = false - nodeStatusSocketTimeout = setTimeout(pingNodeStatusSocket, 295000) - } else if (nodeStatusRetryOnClose) { - nodeStatusRetryOnClose = false - clearTimeout(nodeStatusSocketTimeout) - initNodeStatusSocket() - nodeStatusSocketTimeout = setTimeout(pingNodeStatusSocket, 295000) - } else { - nodeStatusSocketObject.send("non-integer ping") - nodeStatusSocketTimeout = setTimeout(pingNodeStatusSocket, 295000) - } -} + if (nodeStateCall) { + clearTimeout(nodeStatusSocketTimeout) + initNodeStatusSocket() + nodeStateCall = false + nodeStatusSocketTimeout = setTimeout(pingNodeStatusSocket, 295000) + } else if (nodeStatusRetryOnClose) { + nodeStatusRetryOnClose = false + clearTimeout(nodeStatusSocketTimeout) + initNodeStatusSocket() + nodeStatusSocketTimeout = setTimeout(pingNodeStatusSocket, 295000) + } else { + nodeStatusSocketObject.send("non-integer ping") + nodeStatusSocketTimeout = setTimeout(pingNodeStatusSocket, 295000) + } +} \ No newline at end of file diff --git a/plugins/plugins/core/streams/streams.js b/plugins/plugins/core/streams/streams.js index 7b382a63..30a5ea3f 100644 --- a/plugins/plugins/core/streams/streams.js +++ b/plugins/plugins/core/streams/streams.js @@ -1,107 +1,102 @@ -import {parentEpml} from '../connect.js' +import { parentEpml } from '../connect' -import {startConfigWatcher} from './onNewBlock.js' +import { startConfigWatcher } from './onNewBlock' const setAccountInfo = async (addr) => { + const names = await parentEpml.request('apiCall', { + url: `/names/address/${addr}` + }) - const names = await parentEpml.request('apiCall', { - url: `/names/address/${addr}` - }) - const addressInfo = await parentEpml.request('apiCall', { - url: `/addresses/${addr}` - }) + const addressInfo = await parentEpml.request('apiCall', { + url: `/addresses/${addr}` + }) - let accountInfo = { - names: names, - addressInfo: addressInfo - } + let accountInfo = { + names: names, + addressInfo: addressInfo + } - parentEpml.request('setAccountInfo', accountInfo) + parentEpml.request('setAccountInfo', accountInfo) } - const objectToArray = (object) => { + let groupList = object.groups.map(group => group.groupId === 0 ? { + groupId: group.groupId, + url: `group/${group.groupId}`, + groupName: "Qortal General Chat", + sender: group.sender, + senderName: group.senderName, + timestamp: group.timestamp === undefined ? 2 : group.timestamp + } : { + ...group, url: `group/${group.groupId}` + }) + + let directList = object.direct.map(dc => { + return { ...dc, url: `direct/${dc.address}` } + }) - let groupList = object.groups.map(group => group.groupId === 0 ? { groupId: group.groupId, url: `group/${group.groupId}`, groupName: "Qortal General Chat", sender: group.sender, senderName: group.senderName, timestamp: group.timestamp === undefined ? 1 : group.timestamp } : { ...group, url: `group/${group.groupId}` }) - let directList = object.direct.map(dc => { - return { ...dc, url: `direct/${dc.address}` } - }) return [...groupList, ...directList] } const sortActiveChat = (activeChatObject, localChatHeads) => { + let oldChatHeads = JSON.parse(localChatHeads) - let oldChatHeads = JSON.parse(localChatHeads) + if (window.parent._.isEqual(oldChatHeads, activeChatObject) === true) { + } else { + let oldActiveChats = objectToArray(oldChatHeads) + let newActiveChats = objectToArray(activeChatObject) - if (window.parent._.isEqual(oldChatHeads, activeChatObject) === true) { - - } else { - - let oldActiveChats = objectToArray(oldChatHeads) - let newActiveChats = objectToArray(activeChatObject) - - let results = newActiveChats.filter(newChat => { - let value = oldActiveChats.some(oldChat => newChat.timestamp === oldChat.timestamp) - return !value - }) - - results.forEach(chat => { - - if (chat.sender !== window.parent.reduxStore.getState().app.selectedAddress.address) { - - if (chat.sender !== undefined) parentEpml.request('showNotification', chat) - } else { - // ... - } - }) - - } + let results = newActiveChats.filter(newChat => { + let value = oldActiveChats.some(oldChat => newChat.timestamp === oldChat.timestamp) + return !value + }) + results.forEach(chat => { + if (chat.sender !== window.parent.reduxStore.getState().app.selectedAddress.address) { + if (chat.sender !== undefined) parentEpml.request('showNotification', chat) + } else { + // ... + } + }) + } } - let initialChatWatch = 0 const chatHeadWatcher = (activeChats) => { + let addr = window.parent.reduxStore.getState().app.selectedAddress.address + let key = `${addr.substr(0, 10)}_chat-heads` - let addr = window.parent.reduxStore.getState().app.selectedAddress.address + try { + let localChatHeads = localStorage.getItem(key) - let key = `${addr.substr(0, 10)}_chat-heads` + if (localChatHeads === null) { + parentEpml.request('setLocalStorage', { + key: key, + dataObj: activeChats + }).then(ms => { + parentEpml.request('setChatHeads', activeChats).then(ret => { + // ... + }) + }) + } else { + parentEpml.request('setLocalStorage', { + key: key, + dataObj: activeChats + }).then(ms => { + parentEpml.request('setChatHeads', activeChats).then(ret => { + // ... + }) + }) - try { - let localChatHeads = localStorage.getItem(key) - - if (localChatHeads === null) { - parentEpml.request('setLocalStorage', { - key: key, - dataObj: activeChats - }).then(ms => { - parentEpml.request('setChatHeads', activeChats).then(ret => { - // ... - }) - }) - } else { - - parentEpml.request('setLocalStorage', { - key: key, - dataObj: activeChats - }).then(ms => { - parentEpml.request('setChatHeads', activeChats).then(ret => { - // ... - }) - }) - - if (initialChatWatch >= 1) { - - sortActiveChat(activeChats, localChatHeads) - } else { - - initialChatWatch = initialChatWatch + 1 - } - } - - } catch (e) { - } + if (initialChatWatch >= 1) { + sortActiveChat(activeChats, localChatHeads) + } else { + initialChatWatch = initialChatWatch + 1 + } + } + } catch (e) { + } } let socketObject @@ -114,120 +109,102 @@ let canPing = false let timeoutId parentEpml.subscribe('logged_in', async isLoggedIn => { + const initChatHeadSocket = () => { + let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + let nodeUrl = myNode.domain + ":" + myNode.port + let activeChatSocketLink - const initChatHeadSocket = () => { + if (window.parent.location.protocol === "https:") { + activeChatSocketLink = `wss://${nodeUrl}/websockets/chat/active/${window.parent.reduxStore.getState().app.selectedAddress.address}?encoding=BASE64` + } else { + activeChatSocketLink = `ws://${nodeUrl}/websockets/chat/active/${window.parent.reduxStore.getState().app.selectedAddress.address}?encoding=BASE64` + } - let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - let nodeUrl = myNode.domain + ":" + myNode.port + const activeChatSocket = new WebSocket(activeChatSocketLink) - let activeChatSocketLink + // Open Connection + activeChatSocket.onopen = () => { + socketObject = activeChatSocket + initial = initial + 1 + canPing = true + } - if (window.parent.location.protocol === "https:") { + // Message Event + activeChatSocket.onmessage = (e) => { + if (e.data === 'pong') { + clearTimeout(timeoutId) + activeChatSocketTimeout = setTimeout(pingActiveChatSocket, 45000) + return + } - activeChatSocketLink = `wss://${nodeUrl}/websockets/chat/active/${window.parent.reduxStore.getState().app.selectedAddress.address}?encoding=BASE64` - } else { + try { + chatHeadWatcher(JSON.parse(e.data)) + } catch (error) { + } + } - activeChatSocketLink = `ws://${nodeUrl}/websockets/chat/active/${window.parent.reduxStore.getState().app.selectedAddress.address}?encoding=BASE64` - } + // Closed Event + activeChatSocket.onclose = () => { + clearInterval(activeChatSocketTimeout) - const activeChatSocket = new WebSocket(activeChatSocketLink) + if (closeGracefully === false) { + retryOnClose = true + setTimeout(pingActiveChatSocket, 10000) + } + } - // Open Connection - activeChatSocket.onopen = () => { - socketObject = activeChatSocket + // Error Event + activeChatSocket.onerror = (e) => { + } + } - initial = initial + 1 - canPing = true - } + const pingActiveChatSocket = () => { + if (window.parent.reduxStore.getState().app.loggedIn === true) { + if (!onceLoggedIn) { + initChatHeadSocket() + onceLoggedIn = true + activeChatSocketTimeout = setTimeout(pingActiveChatSocket, 45000) + } else if (retryOnClose) { + retryOnClose = false + clearTimeout(activeChatSocketTimeout) + initChatHeadSocket() + onceLoggedIn = true + activeChatSocketTimeout = setTimeout(pingActiveChatSocket, 45000) + } else if (canPing) { + socketObject.send('ping') + timeoutId = setTimeout(() => { + socketObject.close() + clearTimeout(activeChatSocketTimeout) + }, 5000) + } + } else { + if (onceLoggedIn && !closeGracefully) { + closeGracefully = true + socketObject.close() + clearTimeout(activeChatSocketTimeout) + onceLoggedIn = false + canPing = false + } + } + } - // Message Event - activeChatSocket.onmessage = (e) => { - if (e.data === 'pong') { - clearTimeout(timeoutId) - activeChatSocketTimeout = setTimeout(pingActiveChatSocket, 45000) - return - } - try { - chatHeadWatcher(JSON.parse(e.data)) - } catch (error) { - } - } + if (isLoggedIn === 'true') { + // Call Set Account Info... + await setAccountInfo(window.parent.reduxStore.getState().app.selectedAddress.address) - // Closed Event - activeChatSocket.onclose = () => { - clearInterval(activeChatSocketTimeout) + // Start Chat Watcher Socket + pingActiveChatSocket() + } else { + if (onceLoggedIn) { + closeGracefully = true + socketObject.close() + clearTimeout(activeChatSocketTimeout) + onceLoggedIn = false + canPing = false + } - if (closeGracefully === false) { - retryOnClose = true - setTimeout(pingActiveChatSocket, 10000) - } - } - - // Error Event - activeChatSocket.onerror = (e) => { - } - } - - - const pingActiveChatSocket = () => { - - if (window.parent.reduxStore.getState().app.loggedIn === true) { - - if (!onceLoggedIn) { - - initChatHeadSocket() - onceLoggedIn = true - activeChatSocketTimeout = setTimeout(pingActiveChatSocket, 45000) - } else if (retryOnClose) { - - retryOnClose = false - clearTimeout(activeChatSocketTimeout) - initChatHeadSocket() - onceLoggedIn = true - activeChatSocketTimeout = setTimeout(pingActiveChatSocket, 45000) - } else if (canPing) { - - socketObject.send('ping') - timeoutId = setTimeout(() => { - socketObject.close() - clearTimeout(activeChatSocketTimeout) - }, 5000) - } - - } else { - - if (onceLoggedIn && !closeGracefully) { - - closeGracefully = true - socketObject.close() - clearTimeout(activeChatSocketTimeout) - onceLoggedIn = false - canPing = false - } - } - } - - - if (isLoggedIn === 'true') { - - // Call Set Account Info... - await setAccountInfo(window.parent.reduxStore.getState().app.selectedAddress.address) - - // Start Chat Watcher Socket - pingActiveChatSocket() - } else { - - if (onceLoggedIn) { - - closeGracefully = true - socketObject.close() - clearTimeout(activeChatSocketTimeout) - onceLoggedIn = false - canPing = false - } - - initialChatWatch = 0 - } + initialChatWatch = 0 + } }) -startConfigWatcher() +startConfigWatcher() \ No newline at end of file diff --git a/plugins/plugins/core/trade-bot/trade-bot-portal-css.js b/plugins/plugins/core/trade-bot/trade-bot-portal-css.js deleted file mode 100644 index d769c8fb..00000000 --- a/plugins/plugins/core/trade-bot/trade-bot-portal-css.js +++ /dev/null @@ -1,679 +0,0 @@ -import {css} from 'lit' - -export const tradebotStyles = css` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --mdc-theme-error: rgb(255, 89, 89); - --mdc-text-field-outlined-idle-border-color: var(--txtfieldborder); - --mdc-text-field-outlined-hover-border-color: var(--txtfieldhoverborder); - --mdc-text-field-label-ink-color: var(--black); - --mdc-text-field-ink-color: var(--black); - --mdc-select-outlined-idle-border-color: var(--txtfieldborder); - --mdc-select-outlined-hover-border-color: var(--txtfieldhoverborder); - --mdc-select-label-ink-color: var(--black); - --mdc-select-ink-color: var(--black); - --mdc-theme-surface: var(--white); - --mdc-dialog-content-ink-color: var(--black); - --mdc-dialog-shape-radius: 25px; - --paper-input-container-focus-color: var(--mdc-theme-primary); - --lumo-primary-text-color: rgb(0, 167, 245); - --lumo-primary-color-50pct: rgba(0, 167, 245, 0.5); - --lumo-primary-color-10pct: rgba(0, 167, 245, 0.1); - --lumo-primary-color: hsl(199, 100%, 48%); - --lumo-base-color: var(--white); - --lumo-body-text-color: var(--black); - --lumo-secondary-text-color: var(--sectxt); - --lumo-contrast-60pct: var(--vdicon); - --_lumo-grid-border-color: var(--border); - --_lumo-grid-secondary-border-color: var(--border2); - } - - paper-spinner-lite { - height: 30px; - width: 30px; - --paper-spinner-color: var(--mdc-theme-primary); - --paper-spinner-stroke-width: 3px; - } - - mwc-tab-bar { - --mdc-text-transform: none; - --mdc-tab-color-default: var(--black); - --mdc-tab-text-label-color-default: var(--black); - } - - #tabs-1 { - --mdc-tab-height: 42px; - border-left: 1px solid var(--tradeborder); - border-top: 1px solid var(--tradeborder); - border-right: 1px solid var(--tradeborder); - color: var(--black); - } - - #tab-buy[active] { - --mdc-theme-primary: rgba(55, 160, 51, 0.9); - } - - #tabs-1-content { - height: 100%; - padding-bottom: 10px; - } - - #tabs-1-content>div { - height: 100%; - border: 1px solid var(--tradeborder); - } - - #tabs-1-content .card { - border: none; - } - - #tabs-1-content .btn-clear { - --mdc-icon-button-size: 32px; - color: var(--black); - } - - .btn-clear-bot { - --mdc-icon-button-size: 32px; - color: var(--black); - float: right; - } - - .btn-info { - color: #03a9f4; - --mdc-icon-size: 16px; - padding-top: 3px; - } - - #tab-sell[active] { - --mdc-theme-primary: rgb(255, 89, 89); - } - - #trade-portal-page { - background: var(--white); - padding: 12px 24px; - } - - .divCard { - border: 1px solid var(--black); - padding: 1em; - box-shadow: 0 0.3px 1px 0 rgba(0, 0, 0, 0.14), 0 1px 1px -1px rgba(0, 0, 0, 0.12), 0 1px 2px 0 rgba(0, 0, 0, 0.2); - } - - h2 { - margin: 10px 0; - } - - h4 { - margin: 5px 0; - } - - p { - font-size: 14px; - line-height: 21px; - } - - .card-body { - background-color: var(--white); - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; - min-height: 100vh; - margin: 0; - } - - .card-container { - background-color: var(--white); - border-radius: 5px; - color: var(--black); - padding-top: 30px; - position: relative; - width: 350px; - max-width: 100%; - text-align: center; - } - - .card-container .level { - color: #ffffff; - background-color: #03a9f4; - border-radius: 3px; - font-size: 14px; - font-weight: bold; - padding: 3px 7px; - position: absolute; - top: 30px; - left: 30px; - } - - .card-container .founder { - color: #ffffff; - background-color: #03a9f4; - border-radius: 3px; - font-size: 14px; - font-weight: bold; - padding: 3px 7px; - position: absolute; - top: 30px; - right: 30px; - } - - .card-container .round { - width: 96px; - height: 96px; - border: 1px solid #03a9f4; - border-radius: 50%; - padding: 2px; - } - - .card-container .badge { - width: 200px; - height: 135px; - border: 1px solid transparent; - border-radius: 10%; - padding: 2px; - } - - .userdata { - background-color: #1F1A36; - text-align: left; - padding: 15px; - margin-top: 30px; - } - - .userdata ul { - list-style-type: none; - margin: 0; - padding: 0; - } - - .userdata ul li { - border: 1px solid #2D2747; - border-radius: 2px; - display: inline-block; - font-size: 12px; - margin: 0 7px 7px 0; - padding: 7px; - } - - h2, - h3, - h4, - h5 { - color: var(--black); - font-weight: 400; - } - - header { - display: flex; - flex: 0 1 auto; - align-items: center; - justify-content: center; - padding: 0px 10px; - font-size: 16px; - color: var(--white); - background-color: var(--tradehead); - border-left: 1px solid var(--tradeborder); - border-top: 1px solid var(--tradeborder); - border-right: 1px solid var(--tradeborder); - min-height: 40px; - } - - p { - margin-bottom: 12px; - } - - #trade-portal { - max-width: 100vw; - margin-left: auto; - margin-right: auto; - } - - .box { - margin: 0; - padding: 0; - display: flex; - flex-flow: column; - height: 100%; - } - - .box-bot { - margin: 0; - padding: 0; - display: flex; - flex-flow: column; - height: 150px; - } - - #first-trade-section { - margin-bottom: 10px; - } - - #first-trade-section>div {} - - #second-trade-section { - margin-bottom: 10px; - } - - #second-trade-section>div {} - - #third-trade-section { - margin-bottom: 10px; - } - - #third-trade-section>div {} - - .trade-chart { - background-color: var(--white); - border: 2px #ddd solid; - text-align: center; - } - - .open-trades { - text-align: center; - } - - .open-market-container { - text-align: center; - } - - .trade-bot-container { - text-align: center; - } - - .no-last-seen { - background: rgb(255, 89, 89); - padding: 9px 1.3px; - border-radius: 50%; - width: 1rem; - margin: 0 auto; - } - - .card { - padding: 1em; - border: 1px var(--tradeborder) solid; - flex: 1 1 auto; - display: flex; - flex-flow: column; - justify-content: space-evenly; - min-height: inherit; - } - - .card-bot { - padding: 1em; - flex: 1 1 auto; - display: flex; - flex-flow: column; - justify-content: space-evenly; - width: 350px; - min-height: inherit; - } - - .cancel { - --mdc-theme-primary: rgb(255, 89, 89); - } - - .border-wrapper { - border: 1px var(--tradeborder) solid; - overflow: hidden; - } - - .amt-text { - color: var(--tradehave); - font-size: 15px; - margin-top: 5px; - margin-bottom: 12px; - } - - .exchange { - color: var(--black); - font-size: 18px; - font-weight: bold; - margin-top: 5px; - margin-bottom: 10px; - } - - .clear-button { - display: inline; - float: right; - margin-bottom: 5px; - } - - .exhcnage-text { - display: inline; - float: left; - margin-bottom: 5px; - } - - .balance-text { - display: inline; - float: right; - margin-bottom: 5px; - } - - .fee-text { - display: inline; - float: left; - margin-bottom: 5px; - } - - .tab-text { - color: var(--tradehave); - font-size: 12px; - text-align: left; - margin-top: 2px; - margin-bottom: -12px; - } - - .historic-trades { - text-align: center; - } - - .my-open-orders { - text-align: center; - } - - .my-historic-trades { - text-align: center; - } - - .buttons { - width: auto !important; - } - - .buy-button { - --mdc-theme-primary: rgba(55, 160, 51, 0.9); - } - - .sell-button { - --mdc-theme-primary: rgb(255, 89, 89); - } - - .trade-bot-button { - margin-top: 20px; - margin-bottom: 20px; - --mdc-theme-primary: rgba(55, 160, 51, 0.9); - } - - .full-width { - background-color: var(--white); - border: 2px var(--black); - height: 200px; - text-align: center; - } - - vaading-grid { - font-size: .8em; - } - - vaadin-grid-column { - flex-grow: 1; - } - - .loadingContainer { - height: 100%; - width: 100%; - } - - .loading, - .loading:after { - border-radius: 50%; - width: 5em; - height: 5em; - } - - .loading { - margin: 10px auto; - border-width: .6em; - border-style: solid; - border-color: rgba(3, 169, 244, 0.2) rgba(3, 169, 244, 0.2) rgba(3, 169, 244, 0.2) rgb(3, 169, 244); - font-size: 10px; - position: relative; - text-indent: -9999em; - transform: translateZ(0px); - animation: 1.1s linear 0s infinite normal none running loadingAnimation; - } - - mwc-select#coinSelectionMenu { - font-size: 24px; - width: 220px; - } - - mwc-select#coinSelectionMenu mwc-list-item { - line-height: 30px; - } - - .coinName::before { - content: ""; - display: inline-block; - height: 26px; - width: 45px; - position: absolute; - background-repeat: no-repeat; - background-size: cover; - left: 10px; - top: 10px; - } - - .btc.coinName:before { - background-image: url('/img/qortbtc.png'); - } - - .ltc.coinName:before { - background-image: url('/img/qortltc.png'); - } - - .doge.coinName:before { - background-image: url('/img/qortdoge.png'); - } - - .dgb.coinName:before { - background-image: url('/img/qortdgb.png'); - } - - .rvn.coinName:before { - background-image: url('/img/qortrvn.png'); - } - - .arrr.coinName:before { - background-image: url('/img/qortarrr.png'); - } - - .coinName { - display: inline-block; - height: 26px; - padding-left: 45px; - } - - .warning-text { - animation: blinker 1.5s linear infinite; - display: inline; - float: left; - margin-bottom: 5px; - color: rgb(255, 89, 89); - } - - .warning-bot-text { - animation: blinker 1.5s linear infinite; - display: inline; - text-align: center; - color: rgb(255, 89, 89); - } - - .red { - --mdc-theme-primary: #F44336; - } - - @-webkit-keyframes loadingAnimation { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } - } - - @keyframes loadingAnimation { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } - } - - @keyframes blinker { - 50% { - opacity: 0; - } - } - - paper-dialog.info { - width: 75%; - max-width: 75vw; - height: 50%; - max-height: 50vh; - background-color: var(--white); - color: var(--black); - border: 1px solid var(--black); - border-radius: 15px; - line-height: 1.6; - overflow-y: auto; - } - - .actions { - display: flex; - justify-content: space-between; - padding: 0 1em; - margin: 12px 0 -6px 0; - } - - .close-icon { - font-size: 36px; - } - - .close-icon:hover { - cursor: pointer; - opacity: .6; - } - - .setpass-wrapper { - width: 100%; - min-width: 400px; - max-width: 450px; - text-align: center; - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - padding: 10px 10px 0px; - box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1); - } - - .lock-wrapper { - width: 100%; - height: 100%; - min-width: 600px; - max-width: 600px; - min-height: 400px; - max-height: 400px; - text-align: center; - background: url("/img/qortal-lock.jpg"); - border: 1px solid var(--black); - border-radius: 25px; - padding: 10px 10px 0px; - } - - .text-wrapper { - width: 100%; - height: 100%; - min-width: 280px; - max-width: 280px; - min-height: 64px; - max-height: 64px; - text-align: center; - margin-left: 35px; - margin-top: 125px; - overflow: hidden; - } - - .lock-title-white { - font-family: 'magistralbold'; - font-weight: 700; - font-size: 26px; - line-height: 32px; - color: #ffffff; - } - - .lock-title-red { - font-family: 'magistralbold'; - font-weight: 700; - font-size: 26px; - line-height: 32px; - color: #df3636; - } - - @media (min-width: 701px) { - * {} - - #trade-bot-portal { - display: grid; - grid-template-columns: 2fr 4fr 2fr; - grid-auto-rows: max(80px); - column-gap: 0.5em; - row-gap: 0.4em; - justify-items: stretch; - align-items: stretch; - margin-bottom: 20px; - } - - #first-trade-section { - display: grid; - grid-template-columns: 1fr 4fr 1fr; - grid-auto-rows: max(250px); - column-gap: 0.5em; - row-gap: 0.4em; - justify-items: stretch; - align-items: stretch; - margin-bottom: 10px; - } - - #second-trade-section { - display: grid; - grid-template-columns: 1fr 4fr 1fr; - grid-auto-rows: max(250px); - column-gap: 0.5em; - row-gap: 0.4em; - justify-items: stretch; - align-items: stretch; - margin-bottom: 10px; - } - - #third-trade-section { - display: grid; - grid-template-columns: 1fr 4fr 1fr; - grid-auto-rows: max(150px); - column-gap: 0.5em; - row-gap: 0.4em; - justify-items: stretch; - align-items: stretch; - margin-bottom: 10px; - } - - #fourth-trade-section { - display: grid; - grid-template-columns: 1fr 4fr 1fr; - grid-auto-rows: max(150px); - column-gap: 0.5em; - row-gap: 0.4em; - justify-items: stretch; - align-items: stretch; - margin-bottom: 10px; - } - } -` \ No newline at end of file diff --git a/plugins/plugins/core/trade-bot/trade-bot-portal.src.js b/plugins/plugins/core/trade-bot/trade-bot-portal.src.js index d8296e49..909a40e5 100644 --- a/plugins/plugins/core/trade-bot/trade-bot-portal.src.js +++ b/plugins/plugins/core/trade-bot/trade-bot-portal.src.js @@ -1,11 +1,10 @@ -import {html, LitElement} from 'lit' -import {render} from 'lit/html.js' -import {Epml} from '../../../epml.js' +import { html, LitElement } from 'lit' +import { render } from 'lit/html.js' +import { Epml } from '../../../epml' +import { decryptData, encryptData } from '../../../../core/src/lockScreen' +import { tradeBotStyles } from '../components/plugins-css' import isElectron from 'is-electron' -import {get, registerTranslateConfig, translate, use} from '../../../../core/translate' -import Base58 from '../../../../crypto/api/deps/Base58.js' -import {decryptData, encryptData} from '../../../../core/src/lockScreen.js' -import {tradebotStyles} from './trade-bot-portal-css.js' +import Base58 from '../../../../crypto/api/deps/Base58' import '@material/mwc-button' import '@material/mwc-textfield' import '@material/mwc-icon' @@ -24,8 +23,10 @@ import '@vaadin/grid' import '@vaadin/grid/vaadin-grid-sorter' import '@vaadin/password-field' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) @@ -33,3283 +34,3331 @@ const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) let workers = new Map() class TradeBotPortal extends LitElement { - static get properties() { - return { - selectedAddress: { type: Object }, - config: { type: Object }, - listedCoins: { type: Map }, - blockedTradesList: { type: Array }, - tradesPresenceCleaned: { type: Array }, - sellBtnDisable: { type: Boolean }, - isSellLoading: { type: Boolean }, - isBuyLoading: { type: Boolean }, - buyBtnDisable: { type: Boolean }, - autoBuyWarning: { type: Boolean }, - autoBuyBtnDisable: { type: Boolean }, - autoBuyBotDisable: { type: Boolean }, - initialAmount: { type: Number }, - cancelBtnDisable: { type: Boolean }, - cancelStuckOfferBtnDisable: { type: Boolean }, - selectedCoin: { type: String }, - isLoadingHistoricTrades: { type: Boolean }, - isLoadingOpenTrades: { type: Boolean }, - isLoadingMyOpenOrders: { type: Boolean }, - showGetWalletBance: { type: Boolean }, - showAddAutoBuy: { type: Boolean }, - theme: { type: String, reflect: true }, - btcWallet: { type: String }, - ltcWallet: { type: String }, - dogeWallet: { type: String }, - dgbWallet: { type: String }, - rvnWallet: { type: String }, - arrrWallet: { type: String }, - arrrWalletAddress: { type: String }, - qortbtc: { type: Number }, - qortltc: { type: Number }, - qortdoge: { type: Number }, - qortdgb: { type: Number }, - qortrvn: { type: Number }, - qortarrr: { type: Number }, - btcqort: { type: Number }, - ltcqort: { type: Number }, - dogeqort: { type: Number }, - dgbqort: { type: Number }, - rvnqort: { type: Number }, - arrrqort: { type: Number }, - tradeBotBtcBook: { type: Array }, - tradeBotLtcBook: { type: Array }, - tradeBotDogeBook: { type: Array }, - tradeBotDgbBook: { type: Array }, - tradeBotRvnBook: { type: Array }, - tradeBotArrrBook: { type: Array }, - autoSalt: { type: String }, - autoStorageData: { type: String }, - autoLockScreenPass: { type: String }, - autoLockScreenSet: { type: String }, - autoLockPass: { type: String }, - autoLockSet: { type: String }, - myAutoLockScreenPass: { type: String }, - myAutoLockScreenSet: { type: String }, - autoHelperMessage: { type: String } - } - } + static get properties() { + return { + selectedAddress: { type: Object }, + config: { type: Object }, + listedCoins: { type: Map }, + blockedTradesList: { type: Array }, + tradesPresenceCleaned: { type: Array }, + sellBtnDisable: { type: Boolean }, + isSellLoading: { type: Boolean }, + isBuyLoading: { type: Boolean }, + buyBtnDisable: { type: Boolean }, + autoBuyWarning: { type: Boolean }, + autoBuyBtnDisable: { type: Boolean }, + autoBuyBotDisable: { type: Boolean }, + initialAmount: { type: Number }, + cancelBtnDisable: { type: Boolean }, + cancelStuckOfferBtnDisable: { type: Boolean }, + selectedCoin: { type: String }, + isLoadingHistoricTrades: { type: Boolean }, + isLoadingOpenTrades: { type: Boolean }, + isLoadingMyOpenOrders: { type: Boolean }, + showGetWalletBance: { type: Boolean }, + showAddAutoBuy: { type: Boolean }, + theme: { type: String, reflect: true }, + btcWallet: { type: String }, + ltcWallet: { type: String }, + dogeWallet: { type: String }, + dgbWallet: { type: String }, + rvnWallet: { type: String }, + arrrWallet: { type: String }, + arrrWalletAddress: { type: String }, + qortbtc: { type: Number }, + qortltc: { type: Number }, + qortdoge: { type: Number }, + qortdgb: { type: Number }, + qortrvn: { type: Number }, + qortarrr: { type: Number }, + btcqort: { type: Number }, + ltcqort: { type: Number }, + dogeqort: { type: Number }, + dgbqort: { type: Number }, + rvnqort: { type: Number }, + arrrqort: { type: Number }, + tradeBotBtcBook: { type: Array }, + tradeBotLtcBook: { type: Array }, + tradeBotDogeBook: { type: Array }, + tradeBotDgbBook: { type: Array }, + tradeBotRvnBook: { type: Array }, + tradeBotArrrBook: { type: Array }, + autoSalt: { type: String }, + autoStorageData: { type: String }, + autoLockScreenPass: { type: String }, + autoLockScreenSet: { type: String }, + autoLockPass: { type: String }, + autoLockSet: { type: String }, + myAutoLockScreenPass: { type: String }, + myAutoLockScreenSet: { type: String }, + autoHelperMessage: { type: String } + } + } - static get styles() { - return [tradebotStyles] - } + static get styles() { + return [tradeBotStyles] + } - constructor() { - super() - let qortal = { - name: "QORTAL", - balance: "0", - coinCode: "QORT", - coinAmount: this.amountString, - tradeFee: "0.002" - } + constructor() { + super() + let qortal = { + name: "QORTAL", + balance: "0", + coinCode: "QORT", + coinAmount: this.amountString, + tradeFee: "0.002" + } - let bitcoin = { - name: "BITCOIN", - balance: "0", - coinCode: "BTC", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - myGridBoughtItems: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.0001" - } + let bitcoin = { + name: "BITCOIN", + balance: "0", + coinCode: "BTC", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + myGridBoughtItems: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.0001" + } - let litecoin = { - name: "LITECOIN", - balance: "0", - coinCode: "LTC", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - myGridBoughtItems: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.00005" - } + let litecoin = { + name: "LITECOIN", + balance: "0", + coinCode: "LTC", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + myGridBoughtItems: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.00005" + } - let dogecoin = { - name: "DOGECOIN", - balance: "0", - coinCode: "DOGE", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - myGridBoughtItems: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.005" - } + let dogecoin = { + name: "DOGECOIN", + balance: "0", + coinCode: "DOGE", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + myGridBoughtItems: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.005" + } - let digibyte = { - name: "DIGIBYTE", - balance: "0", - coinCode: "DGB", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - myGridBoughtItems: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.0005" - } + let digibyte = { + name: "DIGIBYTE", + balance: "0", + coinCode: "DGB", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + myGridBoughtItems: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.0005" + } - let ravencoin = { - name: "RAVENCOIN", - balance: "0", - coinCode: "RVN", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - myGridBoughtItems: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.006" - } + let ravencoin = { + name: "RAVENCOIN", + balance: "0", + coinCode: "RVN", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + myGridBoughtItems: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.006" + } - let piratechain = { - name: "PIRATECHAIN", - balance: "0", - coinCode: "ARRR", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - myGridBoughtItems: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.0002" - } + let piratechain = { + name: "PIRATECHAIN", + balance: "0", + coinCode: "ARRR", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + myGridBoughtItems: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.0002" + } - this.listedCoins = new Map() - this.listedCoins.set("QORTAL", qortal) - this.listedCoins.set("BITCOIN", bitcoin) - this.listedCoins.set("LITECOIN", litecoin) - this.listedCoins.set("DOGECOIN", dogecoin) - this.listedCoins.set("DIGIBYTE", digibyte) - this.listedCoins.set("RAVENCOIN", ravencoin) - this.listedCoins.set("PIRATECHAIN", piratechain) + this.listedCoins = new Map() + this.listedCoins.set("QORTAL", qortal) + this.listedCoins.set("BITCOIN", bitcoin) + this.listedCoins.set("LITECOIN", litecoin) + this.listedCoins.set("DOGECOIN", dogecoin) + this.listedCoins.set("DIGIBYTE", digibyte) + this.listedCoins.set("RAVENCOIN", ravencoin) + this.listedCoins.set("PIRATECHAIN", piratechain) - workers.set("QORTAL", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("QORTAL", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("BITCOIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("BITCOIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("LITECOIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("LITECOIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("DOGECOIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("DOGECOIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("DIGIBYTE", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("DIGIBYTE", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("RAVENCOIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("RAVENCOIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("PIRATECHAIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("PIRATECHAIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - this.selectedCoin = "LITECOIN" - this.selectedAddress = {} - this.config = {} - this.blockedTradesList = [] - this.tradesPresenceCleaned = [] - this.sellBtnDisable = false - this.isSellLoading = false - this.buyBtnDisable = true - this.autoBuyWarning = false - this.autoBuyBtnDisable = true - this.autoBuyBotDisable = false - this.isBuyLoading = false - this.initialAmount = 0 - this.cancelBtnDisable = false - this.cancelStuckOfferBtnDisable = false - this.isLoadingHistoricTrades = true - this.isLoadingOpenTrades = true - this.isLoadingMyOpenOrders = false - this.showGetWalletBance = true - this.showAddAutoBuy = false - this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' - this.btcWallet = '' - this.ltcWallet = '' - this.dogeWallet = '' - this.dgbWallet = '' - this.rvnWallet = '' - this.arrrWallet = '' - this.arrrWalletAddress = '' - this.qortbtc = 0 - this.qortltc = 0 - this.qortdoge = 0 - this.qortdgb = 0 - this.qortrvn = 0 - this.qortarrr = 0 - this.btcqort = 0 - this.ltcqort = 0 - this.dogeqort = 0 - this.dgbqort = 0 - this.rvnqort = 0 - this.arrrqort = 0 - this.tradeBotBtcBook = [] - this.tradeBotLtcBook = [] - this.tradeBotDogeBook = [] - this.tradeBotDgbBook = [] - this.tradeBotRvnBook = [] - this.tradeBotArrrBook = [] - this.autoSalt = '' - this.autoStorageData = '' - this.autoLockScreenPass = '' - this.autoLockScreenSet = '' - this.autoLockPass = '' - this.autoLockSet = '' - this.myAutoLockScreenPass = '' - this.myAutoLockScreenSet = '' - this.autoHelperMessage = '' - } + this.selectedCoin = "LITECOIN" + this.selectedAddress = {} + this.config = {} + this.blockedTradesList = [] + this.tradesPresenceCleaned = [] + this.sellBtnDisable = false + this.isSellLoading = false + this.buyBtnDisable = true + this.autoBuyWarning = false + this.autoBuyBtnDisable = true + this.autoBuyBotDisable = false + this.isBuyLoading = false + this.initialAmount = 0 + this.cancelBtnDisable = false + this.cancelStuckOfferBtnDisable = false + this.isLoadingHistoricTrades = true + this.isLoadingOpenTrades = true + this.isLoadingMyOpenOrders = false + this.showGetWalletBance = true + this.showAddAutoBuy = false + this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' + this.btcWallet = '' + this.ltcWallet = '' + this.dogeWallet = '' + this.dgbWallet = '' + this.rvnWallet = '' + this.arrrWallet = '' + this.arrrWalletAddress = '' + this.qortbtc = 0 + this.qortltc = 0 + this.qortdoge = 0 + this.qortdgb = 0 + this.qortrvn = 0 + this.qortarrr = 0 + this.btcqort = 0 + this.ltcqort = 0 + this.dogeqort = 0 + this.dgbqort = 0 + this.rvnqort = 0 + this.arrrqort = 0 + this.tradeBotBtcBook = [] + this.tradeBotLtcBook = [] + this.tradeBotDogeBook = [] + this.tradeBotDgbBook = [] + this.tradeBotRvnBook = [] + this.tradeBotArrrBook = [] + this.autoSalt = '' + this.autoStorageData = '' + this.autoLockScreenPass = '' + this.autoLockScreenSet = '' + this.autoLockPass = '' + this.autoLockSet = '' + this.myAutoLockScreenPass = '' + this.myAutoLockScreenSet = '' + this.autoHelperMessage = '' + } - openTradesTemplate() { - return html` -
    -
    -
    ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange42")}
    -
    -
    ${translate("login.loading")}
    - - { - render(html`${this.round(data.item.qortAmount)}`, root) - }} - > - - { - render(html`${this.round(data.item.price)}`, root) - }} - > - - { - render(html`${data.item.foreignAmount}`, root) - }} - > - - { - render(html`${data.item.qortalCreator}`, root) - }} - > - - + render() { + return html` +
    +
    +
    +
    +

    ${translate("info.inf13")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode} -  

    + + BTC / QORT + LTC / QORT + DOGE / QORT + DGB / QORT + RVN / QORT + ARRR / QORT + +
    + this.shadowRoot.getElementById('buyInfoDialog').open()}> +
    +
    + ${this.renderAutoLockButton()} +
    +
    +
    +
    +
    +
    +
    + ${this.openTradesTemplate()} +
    +
    +
    +
    + ${this.myDoneTradesTemplate()} +
    +
    +
    +
    + ${this.myOpenOrdersTemplate()} +
    +
    +
    +
    + ${this.showAutoBuyGrid()} +
    +
    +
    +

    ${translate("tradepage.tchange33")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange40")}

    +

    1 QORT = ${this.exchangeRateQort()} ${this.listedCoins.get(this.selectedCoin).coinCode}

    +
    -
    - ` - } + +
    +

    + ${this.renderFetchText()} + +

    +
    +
    +
    +

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    +
    +
    +
    +
    ${this.renderWarning()}
    + +
    + ${translate("tradepage.tchange8")} (QORT)* +

    + + +

    + ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + + ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} + +
    +
    + + ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} + +
    +
    +
    + ${translate("general.close")} +
    + +
    +

    + ${this.renderFetchText()} + +

    +
    +
    +
    +

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    +
    +
    +
    +
    ${this.renderWarning()}
    + +
    + ${translate("tradepage.tchange8")} (QORT)* +

    + + +

    + ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + + ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} + +
    +
    + + ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} + +
    +
    +
    + ${translate("general.close")} +
    + +
    +

    + ${this.renderFetchText()} + +

    +
    +
    +
    +

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    +
    +
    +
    +
    ${this.renderWarning()}
    + +
    + ${translate("tradepage.tchange8")} (QORT)* +

    + + +

    + ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + + ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} + +
    +
    + + ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} + +
    +
    +
    + ${translate("general.close")} +
    + +
    +

    + ${this.renderFetchText()} + +

    +
    +
    +
    +

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    +
    +
    +
    +
    ${this.renderWarning()}
    + +
    + ${translate("tradepage.tchange8")} (QORT)* +

    + + +

    + ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + + ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} + +
    +
    + + ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} + +
    +
    +
    + ${translate("general.close")} +
    + +
    +

    + ${this.renderFetchText()} + +

    +
    +
    +
    +

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    +
    +
    +
    +
    ${this.renderWarning()}
    + +
    + ${translate("tradepage.tchange8")} (QORT)* +

    + + +

    + ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + + ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} + +
    +
    + + ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} + +
    +
    +
    + ${translate("general.close")} +
    + +
    +

    + ${this.renderFetchText()} + +

    +
    +
    +
    +

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    +
    +
    +
    +
    ${this.renderWarning()}
    + +
    + ${translate("tradepage.tchange8")} (QORT)* +

    + + +

    + ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + + ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} + +
    +
    + + ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} + +
    +
    +
    + ${translate("general.close")} +
    + +
    +

    + this.shadowRoot.getElementById('buyInfoDialog').close()} title="${translate("info.inf8")}">highlight_off +
    +
    +

    ${translate("info.inf7")}

    +

    ${translate("info.inf9")}

    +

    ${translate("info.inf10")}

    +

    ${translate("info.inf11")}

    +

    ${translate("info.inf12")}

    +
    +
    + +
    +

    Qortal ${translate("tabmenu.tm6")} ${translate("login.lp1")}

    +
    +
    +
    +

    ${translate("login.lp2")}

    +

    ${translate("login.lp3")}

    +
    +
    + password + +
    +
    + password + +
    +
    + ${translate("login.lp4")} + ${translate("login.lp5")} +
    +
    + +
    +

    Qortal ${translate("tabmenu.tm6")} ${translate("login.lp1")}

    +
    +
    +
    +

    ${translate("login.lessthen8")}

    +
    +
    + ${translate("login.lp4")} + ${translate("login.lp5")} +
    +
    + +
    + ${translate("tradepage.tchange46")}
    + ${translate("login.lp9")} + ${translate("login.lp10")} +
    +
    + password + +
    + ${this.autoHelperMessage} +
    +
    +
    +
    + +
    +
    + ` + } - myOpenOrdersTemplate() { - return html` -
    -
    -
    ${translate("info.inf15")}
    -
    -
    ${translate("login.loading")}
    - - { - const dateString = new Date(data.item.timestamp).toLocaleString() - render(html`${dateString}`, root) - }} - > - - { - render(html` ${data.item._tradeState} `, root) - }} - > - - { - const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) - render(html`${price}`, root) - }} - > - - - - - - + async firstUpdated() { + let _this = this + + this.changeTheme() + this.changeLanguage() + + await this.tradeFee() + await this.getNewBlockedTrades() + + this.autoHelperMessage = this.renderAutoHelperPass() + + this.autoSalt = '' + this.autoSalt = Base58.encode(window.parent.reduxStore.getState().app.wallet._addresses[0].keyPair.privateKey) + + this.autoStorageData = '' + this.autoStorageData = window.parent.reduxStore.getState().app.selectedAddress.address + + this.autoLockScreenPass = '' + this.autoLockScreenPass = 'autoLockScreenPass-' + this.autoStorageData + + this.autoLockScreenSet = '' + this.autoLockScreenSet = 'autoLockScreenSet-' + this.autoStorageData + + this.autoLockPass = '' + this.autoLockPass = encryptData(false, this.autoSalt) + + this.autoLockSet = '' + this.autoLockSet = encryptData(false, this.autoSalt) + + if (localStorage.getItem(this.autoLockScreenPass) === null && localStorage.getItem(this.autoLockScreenSet) === null) { + localStorage.setItem(this.autoLockScreenPass, this.autoLockPass) + localStorage.setItem(this.autoLockScreenSet, this.autoLockSet) + this.myAutoLockScreenPass = '' + this.myAutoLockScreenPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt) + this.myAutoLockScreenSet = '' + this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt) + } else { + this.myAutoLockScreenPass = '' + this.myAutoLockScreenPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt) + this.myAutoLockScreenSet = '' + this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt) + } + + if (this.myAutoLockScreenSet === true) { + this.shadowRoot.getElementById('autoLockScreenActive').open() + } + + await this.updateWalletBalance() + await this.fetchWalletAddress(this.selectedCoin) + + this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + this._openOrdersGrid = this.shadowRoot.getElementById('openOrdersGrid') + + this._openOrdersGrid.querySelector('#priceColumn').headerRenderer = function (root) { + const priceString = get("tradepage.tchange9") + root.innerHTML = '' + priceString + ' (' + _this.listedCoins.get(_this.selectedCoin).coinCode + ')' + } + + this._openOrdersGrid.querySelector('#qortAmountColumn').headerRenderer = function (root) { + const amountString = get("tradepage.tchange8") + root.innerHTML = '' + amountString + ' (QORT)' + } + + this._myOrdersGrid = this.shadowRoot.getElementById('myOrdersGrid') + + const getQortBtcPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/BITCOIN?inverse=true` }).then((res) => { + setTimeout(() => { this.qortbtc = (Number(res) / 1e8).toFixed(8) }, 1) + }) + setTimeout(getQortBtcPrice, 300000) + } + + const getQortLtcPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/LITECOIN?inverse=true` }).then((res) => { + setTimeout(() => { this.qortltc = (Number(res) / 1e8).toFixed(8) }, 1) + }) + setTimeout(getQortLtcPrice, 300000) + } + + const getQortDogePrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/DOGECOIN?inverse=true` }).then((res) => { + setTimeout(() => { this.qortdoge = (Number(res) / 1e8).toFixed(8) }, 1) + }) + setTimeout(getQortDogePrice, 300000) + } + + const getQortDgbPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/DIGIBYTE?inverse=true` }).then((res) => { + setTimeout(() => { this.qortdgb = (Number(res) / 1e8).toFixed(8) }, 1) + }) + setTimeout(getQortDgbPrice, 300000) + } + + const getQortRvnPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/RAVENCOIN?inverse=true` }).then((res) => { + setTimeout(() => { this.qortrvn = (Number(res) / 1e8).toFixed(8) }, 1) + }) + setTimeout(getQortRvnPrice, 300000) + } + + const getQortArrrPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/PIRATECHAIN?inverse=true` }).then((res) => { + setTimeout(() => { this.qortarrr = (Number(res) / 1e8).toFixed(8) }, 1) + }) + setTimeout(getQortArrrPrice, 300000) + } + + window.addEventListener('storage', () => { + this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") + this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") + this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") + this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") + const checkLanguage = localStorage.getItem('qortalLanguage') + const checkTheme = localStorage.getItem('qortalTheme') + + use(checkLanguage) + + this.theme = (checkTheme === 'dark') ? 'dark' : 'light' + document.querySelector('html').setAttribute('theme', this.theme) + }) + + if (!isElectron()) { + } else { + window.addEventListener('contextmenu', (event) => { + event.preventDefault() + window.parent.electronAPI.showMyMenu() + }) + } + + this.btcWallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address + this.ltcWallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address + this.dogeWallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address + this.dgbWallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address + this.rvnWallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address + this.arrrWallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address + + let configLoaded = false + + parentEpml.ready().then(() => { + parentEpml.subscribe('selected_address', async (selectedAddress) => { + this.selectedAddress = {} + selectedAddress = JSON.parse(selectedAddress) + if (!selectedAddress || Object.entries(selectedAddress).length === 0) return + this.selectedAddress = selectedAddress + + this.btcWallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address + this.ltcWwallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address + this.dogeWallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address + this.dgbWallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address + this.rvnWallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address + this.arrrWallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address + + this.updateAccountBalance() + }) + + parentEpml.subscribe('config', (c) => { + if (!configLoaded) { + setTimeout(getQortBtcPrice, 1) + setTimeout(getQortLtcPrice, 1) + setTimeout(getQortDogePrice, 1) + setTimeout(getQortDgbPrice, 1) + setTimeout(getQortRvnPrice, 1) + setTimeout(getQortArrrPrice, 1) + configLoaded = true + } + this.config = JSON.parse(c) + }) + + let coinSelectionMenu = this.shadowRoot.getElementById("coinSelectionMenu") + + coinSelectionMenu.addEventListener('change', function () { + _this.setForeignCoin(coinSelectionMenu.value, false) + }) + + _this.setForeignCoin(coinSelectionMenu.value, true) + }) + parentEpml.imReady() + + this.btcTradebook() + this.ltcTradebook() + this.dogeTradebook() + this.dgbTradebook() + this.rvnTradebook() + this.arrrTradebook() + + this.clearConsole() + + setInterval(() => { + this.clearConsole() + }, 60000) + + setInterval(() => { + this.getNewBlockedTrades() + }, 300000) + } + + openTradesTemplate() { + return html` +
    +
    +
    ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange42")}
    +
    +
    +
    + ${translate("login.loading")} +
    + + { + render(html`${this.round(data.item.qortAmount)}`, root) + }} + > + + { + render(html`${this.round(data.item.price)}`, root) + }} + > + + { + render(html`${data.item.foreignAmount}`, root) + }} + > + + { + render(html`${data.item.qortalCreator}`, root) + }} + > + + +
    -
    - ` - } + ` + } - myDoneTradesTemplate() { - return html` -
    -
    -
    ${translate("tradepage.tchange43")} (${this.listedCoins.get(this.selectedCoin).coinCode})
    -
    -
    ${translate("login.loading")}
    - - { - const dateString = new Date(data.item.timestamp).toLocaleString() - render(html`${dateString}`, root) - }} - > - - { - return render(html` ${translate("tradepage.tchange32")} `, root) - }} - > - - { - const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) - render(html`${price}`, root) - }} - > - - - - { + myOpenOrdersTemplate() { + return html` +
    +
    +
    ${translate("info.inf15")}
    +
    +
    +
    + ${translate("login.loading")} +
    + + { + const dateString = new Date(data.item.timestamp).toLocaleString() + render(html`${dateString}`, root) + }} + > + + { + render(html` ${data.item._tradeState} `, root) + }} + > + + { + const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) + render(html`${price}`, root) + }} + > + + + + + + +
    +
    +
    + ` + } + + myDoneTradesTemplate() { + return html` +
    +
    +
    ${translate("tradepage.tchange43")} (${this.listedCoins.get(this.selectedCoin).coinCode})
    +
    +
    +
    + ${translate("login.loading")} +
    + + { + const dateString = new Date(data.item.timestamp).toLocaleString() + render(html`${dateString}`, root) + }} + > + + { + return render(html` ${translate("tradepage.tchange32")} `, root) + }} + > + + { + const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) + render(html`${price}`, root) + }} + > + + + + { + render(html` ${data.item.foreignAmount} `, root) + }} + > + + +
    +
    +
    + ` + } + + myHistoricTradesTemplate() { + return html` +
    +
    +
    ${translate("tradepage.tchange4")}
    +
    + + { + const dateString = new Date(data.item.timestamp).toLocaleString() + render(html`${dateString}`, root) + }} + > + + { + if (data.item.mode === 'SOLD') return render(html` ${translate("tradepage.tchange31")} `, root) + if (data.item.mode === 'BOUGHT') return render(html` ${translate("tradepage.tchange32")} `, root) + return render(html` ${data.item.mode} `, root) + }} + > + + { + const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) + render(html`${price}`, root) + }} + > + + + + { render(html` ${data.item.foreignAmount} `, root) - }} - > - - -
    -
    -
    - ` - } - - myHistoricTradesTemplate() { - return html` -
    -
    -
    ${translate("tradepage.tchange4")}
    -
    - - { - const dateString = new Date(data.item.timestamp).toLocaleString() - render(html`${dateString}`, root) - }} - > - - { - if (data.item.mode === 'SOLD') return render(html` ${translate("tradepage.tchange31")} `, root) - if (data.item.mode === 'BOUGHT') return render(html` ${translate("tradepage.tchange32")} `, root) - return render(html` ${data.item.mode} `, root) - }} - > - - { - const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) - render(html`${price}`, root) - }} - > - - - - { - render(html` ${data.item.foreignAmount} `, root) - }} - > - - -
    -
    -
    - ` - } - - tradeBotBTCTemplate() { - return html` -
    -
    -
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    -
    - - { - render(html`${data.item.botBtcQortAmount}`, root) - }} - > - - { - render(html`${data.item.botBtcPrice}`, root) - }} - > - - { - const totalCoins = this.round(parseFloat(data.item.botBtcQortAmount) * parseFloat(data.item.botBtcPrice)) - const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myBotFunds) > Number(totalCoins)) { - this.autoBuyBotDisable = false - render(html`${totalCoins}`, root) - } else { - this.autoBuyBotDisable = true - render(html`${totalCoins}`, root) - } - }} - > - - { - render(html` this.removeBTCTradebook()}>delete ${translate("nodepage.nchange12")}`, root) - }} - > - - - ${this.isEmptyArray(this.tradeBotBtcBook) ? html` - - ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} - - `: ''} -
    - ${this.autoBuyBotDisable ? html` -
    ${this.renderBotWarning()}
    - `: ''} -
    -
    - ` - } - - tradeBotLTCTemplate() { - return html` -
    -
    -
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    -
    - - { - render(html`${data.item.botLtcQortAmount}`, root) - }} - > - - { - render(html`${data.item.botLtcPrice}`, root) - }} - > - - { - const totalCoins = this.round(parseFloat(data.item.botLtcQortAmount) * parseFloat(data.item.botLtcPrice)) - const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myBotFunds) > Number(totalCoins)) { - this.autoBuyBotDisable = false - render(html`${totalCoins}`, root) - } else { - this.autoBuyBotDisable = true - render(html`${totalCoins}`, root) - } - }} - > - - { - render(html` this.removeLTCTradebook()}>delete ${translate("nodepage.nchange12")}`, root) - }} - > - - - ${this.isEmptyArray(this.tradeBotLtcBook) ? html` - - ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} - - `: ''} -
    - ${this.autoBuyBotDisable ? html` -
    ${this.renderBotWarning()}
    - `: ''} -
    -
    - ` - } - - tradeBotDOGETemplate() { - return html` -
    -
    -
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    -
    - - { - render(html`${data.item.botDogeQortAmount}`, root) - }} - > - - { - render(html`${data.item.botDogePrice}`, root) - }} - > - - { - const totalCoins = this.round(parseFloat(data.item.botDogeQortAmount) * parseFloat(data.item.botDogePrice)) - const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myBotFunds) > Number(totalCoins)) { - this.autoBuyBotDisable = false - render(html`${totalCoins}`, root) - } else { - this.autoBuyBotDisable = true - render(html`${totalCoins}`, root) - } - }} - > - - { - render(html` this.removeDOGETradebook()}>delete ${translate("nodepage.nchange12")}`, root) - }} - > - - - ${this.isEmptyArray(this.tradeBotDogeBook) ? html` - - ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} - - `: ''} -
    - ${this.autoBuyBotDisable ? html` -
    ${this.renderBotWarning()}
    - `: ''} -
    -
    - ` - } - - tradeBotDGBTemplate() { - return html` -
    -
    -
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    -
    - - { - render(html`${data.item.botDgbQortAmount}`, root) - }} - > - - { - render(html`${data.item.botDgbPrice}`, root) - }} - > - - { - const totalCoins = this.round(parseFloat(data.item.botDgbQortAmount) * parseFloat(data.item.botDgbPrice)) - const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myBotFunds) > Number(totalCoins)) { - this.autoBuyBotDisable = false - render(html`${totalCoins}`, root) - } else { - this.autoBuyBotDisable = true - render(html`${totalCoins}`, root) - } - }} - > - - { - render(html` this.removeDGBTradebook()}>delete ${translate("nodepage.nchange12")}`, root) - }} - > - - - ${this.isEmptyArray(this.tradeBotDgbBook) ? html` - - ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} - - `: ''} -
    - ${this.autoBuyBotDisable ? html` -
    ${this.renderBotWarning()}
    - `: ''} -
    -
    - ` - } - - tradeBotRVNTemplate() { - return html` -
    -
    -
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    -
    - - { - render(html`${data.item.botRvnQortAmount}`, root) - }} - > - - { - render(html`${data.item.botRvnPrice}`, root) - }} - > - - { - const totalCoins = this.round(parseFloat(data.item.botRvnQortAmount) * parseFloat(data.item.botRvnPrice)) - const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myBotFunds) > Number(totalCoins)) { - this.autoBuyBotDisable = false - render(html`${totalCoins}`, root) - } else { - this.autoBuyBotDisable = true - render(html`${totalCoins}`, root) - } - }} - > - - { - render(html` this.removeRVNTradebook()}>delete ${translate("nodepage.nchange12")}`, root) - }} - > - - - ${this.isEmptyArray(this.tradeBotRvnBook) ? html` - - ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} - - `: ''} -
    - ${this.autoBuyBotDisable ? html` -
    ${this.renderBotWarning()}
    - `: ''} -
    -
    - ` - } - - tradeBotARRRTemplate() { - return html` -
    -
    -
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    -
    - - { - render(html`${data.item.botArrrQortAmount}`, root) - }} - > - - { - render(html`${data.item.botArrrPrice}`, root) - }} - > - - { - const totalCoins = this.round(parseFloat(data.item.botArrrQortAmount) * parseFloat(data.item.botArrrPrice)) - const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myBotFunds) > Number(totalCoins)) { - this.autoBuyBotDisable = false - render(html`${totalCoins}`, root) - } else { - this.autoBuyBotDisable = true - render(html`${totalCoins}`, root) - } - }} - > - - { - render(html` this.removeARRRTradebook()}>delete ${translate("nodepage.nchange12")}`, root) - }} - > - - - ${this.isEmptyArray(this.tradeBotArrrBook) ? html` - - ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} - - `: ''} -
    - ${this.autoBuyBotDisable ? html` -
    ${this.renderBotWarning()}
    - `: ''} -
    -
    - ` - } - - render() { - return html` -
    -
    -
    -
    -

    ${translate("info.inf13")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode} -  

    - - BTC / QORT - LTC / QORT - DOGE / QORT - DGB / QORT - RVN / QORT - ARRR / QORT - -
    - this.shadowRoot.getElementById('buyInfoDialog').open()}> -
    -
    - ${this.renderAutoLockButton()} -
    -
    -
    -
    -
    -
    -
    - ${this.openTradesTemplate()} -
    -
    -
    -
    - ${this.myDoneTradesTemplate()} -
    -
    -
    -
    - ${this.myOpenOrdersTemplate()} -
    -
    -
    -
    - ${this.showAutoBuyGrid()} -
    -
    -
    -

    ${translate("tradepage.tchange33")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange40")}

    -

    1 QORT = ${this.exchangeRateQort()} ${this.listedCoins.get(this.selectedCoin).coinCode}

    -
    -
    -
    - - -
    -

    ${this.renderFetchText()}

    -
    -
    -
    -

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    -
    -
    -
    -
    ${this.renderWarning()}
    - -
    - ${translate("tradepage.tchange8")} (QORT)* -

    - - -

    - ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - - ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} - -
    -
    - - ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} - + }} + > + +
    - ${translate("general.close")} -
    + ` + } - -
    -

    ${this.renderFetchText()}

    -
    -
    -
    -

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    -
    -
    -
    -
    ${this.renderWarning()}
    - -
    - ${translate("tradepage.tchange8")} (QORT)* -

    - - -

    - ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - - ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} - -
    -
    - - ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} - + tradeBotBTCTemplate() { + return html` +
    +
    +
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    +
    + + { + render(html`${data.item.botBtcQortAmount}`, root) + }} + > + + { + render(html`${data.item.botBtcPrice}`, root) + }} + > + + { + const totalCoins = this.round(parseFloat(data.item.botBtcQortAmount) * parseFloat(data.item.botBtcPrice)) + const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myBotFunds) > Number(totalCoins)) { + this.autoBuyBotDisable = false + render(html`${totalCoins}`, root) + } else { + this.autoBuyBotDisable = true + render(html`${totalCoins}`, root) + } + }} + > + + { + render(html` + this.removeBTCTradebook()}> + delete ${translate("nodepage.nchange12")} + + `, root) + }} + > + + + ${this.isEmptyArray(this.tradeBotBtcBook) ? html` + + ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} + + `: ''}
    + ${this.autoBuyBotDisable ? html` +
    ${this.renderBotWarning()}
    + `: ''}
    - ${translate("general.close")} - + ` + } - -
    -

    ${this.renderFetchText()}

    -
    -
    -
    -

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    -
    -
    -
    -
    ${this.renderWarning()}
    - -
    - ${translate("tradepage.tchange8")} (QORT)* -

    - - -

    - ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - - ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} - -
    -
    - - ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} - + tradeBotLTCTemplate() { + return html` +
    +
    +
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    +
    + + { + render(html`${data.item.botLtcQortAmount}`, root) + }} + > + + { + render(html`${data.item.botLtcPrice}`, root) + }} + > + + { + const totalCoins = this.round(parseFloat(data.item.botLtcQortAmount) * parseFloat(data.item.botLtcPrice)) + const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myBotFunds) > Number(totalCoins)) { + this.autoBuyBotDisable = false + render(html`${totalCoins}`, root) + } else { + this.autoBuyBotDisable = true + render(html`${totalCoins}`, root) + } + }} + > + + { + render(html` + this.removeLTCTradebook()}> + delete ${translate("nodepage.nchange12")} + + `, root) + }} + > + + + ${this.isEmptyArray(this.tradeBotLtcBook) ? html` + + ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} + + `: ''}
    + ${this.autoBuyBotDisable ? html` +
    ${this.renderBotWarning()}
    + `: ''}
    - ${translate("general.close")} - + ` + } - -
    -

    ${this.renderFetchText()}

    -
    -
    -
    -

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    -
    -
    -
    -
    ${this.renderWarning()}
    - -
    - ${translate("tradepage.tchange8")} (QORT)* -

    - - -

    - ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - - ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} - -
    -
    - - ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} - + tradeBotDOGETemplate() { + return html` +
    +
    +
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    +
    + + { + render(html`${data.item.botDogeQortAmount}`, root) + }} + > + + { + render(html`${data.item.botDogePrice}`, root) + }} + > + + { + const totalCoins = this.round(parseFloat(data.item.botDogeQortAmount) * parseFloat(data.item.botDogePrice)) + const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myBotFunds) > Number(totalCoins)) { + this.autoBuyBotDisable = false + render(html`${totalCoins}`, root) + } else { + this.autoBuyBotDisable = true + render(html`${totalCoins}`, root) + } + }} + > + + { + render(html` + this.removeDOGETradebook()}> + delete ${translate("nodepage.nchange12")} + + `, root) + }} + > + + + ${this.isEmptyArray(this.tradeBotDogeBook) ? html` + + ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} + + `: ''}
    + ${this.autoBuyBotDisable ? html` +
    ${this.renderBotWarning()}
    + `: ''}
    - ${translate("general.close")} - + ` + } - -
    -

    ${this.renderFetchText()}

    -
    -
    -
    -

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    -
    -
    -
    -
    ${this.renderWarning()}
    - -
    - ${translate("tradepage.tchange8")} (QORT)* -

    - - -

    - ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - - ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} - -
    -
    - - ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} - + tradeBotDGBTemplate() { + return html` +
    +
    +
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    +
    + + { + render(html`${data.item.botDgbQortAmount}`, root) + }} + > + + { + render(html`${data.item.botDgbPrice}`, root) + }} + > + + { + const totalCoins = this.round(parseFloat(data.item.botDgbQortAmount) * parseFloat(data.item.botDgbPrice)) + const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myBotFunds) > Number(totalCoins)) { + this.autoBuyBotDisable = false + render(html`${totalCoins}`, root) + } else { + this.autoBuyBotDisable = true + render(html`${totalCoins}`, root) + } + }} + > + + { + render(html` + this.removeDGBTradebook()}> + delete ${translate("nodepage.nchange12")} + + `, root) + }} + > + + + ${this.isEmptyArray(this.tradeBotDgbBook) ? html` + + ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} + + `: ''}
    + ${this.autoBuyBotDisable ? html` +
    ${this.renderBotWarning()}
    + `: ''}
    - ${translate("general.close")} - + ` + } - -
    -

    ${this.renderFetchText()}

    -
    -
    -
    -

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    -
    -
    -
    -
    ${this.renderWarning()}
    - -
    - ${translate("tradepage.tchange8")} (QORT)* -

    - - -

    - ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - - ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} - -
    -
    - - ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} - + tradeBotRVNTemplate() { + return html` +
    +
    +
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    +
    + + { + render(html`${data.item.botRvnQortAmount}`, root) + }} + > + + { + render(html`${data.item.botRvnPrice}`, root) + }} + > + + { + const totalCoins = this.round(parseFloat(data.item.botRvnQortAmount) * parseFloat(data.item.botRvnPrice)) + const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myBotFunds) > Number(totalCoins)) { + this.autoBuyBotDisable = false + render(html`${totalCoins}`, root) + } else { + this.autoBuyBotDisable = true + render(html`${totalCoins}`, root) + } + }} + > + + { + render(html` + this.removeRVNTradebook()}> + delete ${translate("nodepage.nchange12")} + + `, root) + }} + > + + + ${this.isEmptyArray(this.tradeBotRvnBook) ? html` + + ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} + + `: ''}
    + ${this.autoBuyBotDisable ? html` +
    ${this.renderBotWarning()}
    + `: ''}
    - ${translate("general.close")} - - - -
    -

    - this.shadowRoot.getElementById('buyInfoDialog').close()} title="${translate("info.inf8")}">highlight_off -
    -
    -

    ${translate("info.inf7")}

    -

    ${translate("info.inf9")}

    -

    ${translate("info.inf10")}

    -

    ${translate("info.inf11")}

    -

    ${translate("info.inf12")}

    -
    -
    - -
    -

    Qortal ${translate("tabmenu.tm6")} ${translate("login.lp1")}

    -
    -
    -
    -

    ${translate("login.lp2")}

    -

    ${translate("login.lp3")}

    -
    -
    - password - -
    -
    - password - -
    -
    - ${translate("login.lp4")} - ${translate("login.lp5")} -
    -
    - -
    -

    Qortal ${translate("tabmenu.tm6")} ${translate("login.lp1")}

    -
    -
    -
    -

    ${translate("login.lessthen8")}

    -
    -
    - ${translate("login.lp4")} - ${translate("login.lp5")} -
    -
    - -
    - ${translate("tradepage.tchange46")}
    - ${translate("login.lp9")} - ${translate("login.lp10")} -
    -
    - password - -
    - ${this.autoHelperMessage} -
    -
    -
    -
    - -
    -
    - ` - } - - async firstUpdated() { - let _this = this - - this.changeTheme() - this.changeLanguage() - await this.tradeFee() - await this.getNewBlockedTrades() - - this.autoHelperMessage = this.renderAutoHelperPass() - - this.autoSalt = '' - this.autoSalt = Base58.encode(window.parent.reduxStore.getState().app.wallet._addresses[0].keyPair.privateKey) - - this.autoStorageData = '' - this.autoStorageData = window.parent.reduxStore.getState().app.selectedAddress.address - - this.autoLockScreenPass = '' - this.autoLockScreenPass = 'autoLockScreenPass-' + this.autoStorageData - - this.autoLockScreenSet = '' - this.autoLockScreenSet = 'autoLockScreenSet-' + this.autoStorageData - - this.autoLockPass = '' - this.autoLockPass = encryptData(false, this.autoSalt) - - this.autoLockSet = '' - this.autoLockSet = encryptData(false, this.autoSalt) - - if (localStorage.getItem(this.autoLockScreenPass) === null && localStorage.getItem(this.autoLockScreenSet) === null) { - localStorage.setItem(this.autoLockScreenPass, this.autoLockPass) - localStorage.setItem(this.autoLockScreenSet, this.autoLockSet) - this.myAutoLockScreenPass = '' - this.myAutoLockScreenPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt) - this.myAutoLockScreenSet = '' - this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt) - } else { - this.myAutoLockScreenPass = '' - this.myAutoLockScreenPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt) - this.myAutoLockScreenSet = '' - this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt) - } - - if (this.myAutoLockScreenSet === true) { - this.shadowRoot.getElementById('autoLockScreenActive').open() - } - - await this.updateWalletBalance() - await this.fetchWalletAddress(this.selectedCoin) - this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') - this._openOrdersGrid = this.shadowRoot.getElementById('openOrdersGrid') - - this._openOrdersGrid.querySelector('#priceColumn').headerRenderer = function (root) { - const priceString = get("tradepage.tchange9") - root.innerHTML = '' + priceString + ' (' + _this.listedCoins.get(_this.selectedCoin).coinCode + ')' - } - - this._openOrdersGrid.querySelector('#qortAmountColumn').headerRenderer = function (root) { - const amountString = get("tradepage.tchange8") - root.innerHTML = '' + amountString + ' (QORT)' - } - - this._myOrdersGrid = this.shadowRoot.getElementById('myOrdersGrid') - - const getQortBtcPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/BITCOIN?inverse=true` }).then((res) => { - setTimeout(() => { this.qortbtc = (Number(res) / 1e8).toFixed(8) }, 1) - }) - setTimeout(getQortBtcPrice, 300000) - } - - const getQortLtcPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/LITECOIN?inverse=true` }).then((res) => { - setTimeout(() => { this.qortltc = (Number(res) / 1e8).toFixed(8) }, 1) - }) - setTimeout(getQortLtcPrice, 300000) - } - - const getQortDogePrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/DOGECOIN?inverse=true` }).then((res) => { - setTimeout(() => { this.qortdoge = (Number(res) / 1e8).toFixed(8) }, 1) - }) - setTimeout(getQortDogePrice, 300000) - } - - const getQortDgbPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/DIGIBYTE?inverse=true` }).then((res) => { - setTimeout(() => { this.qortdgb = (Number(res) / 1e8).toFixed(8) }, 1) - }) - setTimeout(getQortDgbPrice, 300000) - } - - const getQortRvnPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/RAVENCOIN?inverse=true` }).then((res) => { - setTimeout(() => { this.qortrvn = (Number(res) / 1e8).toFixed(8) }, 1) - }) - setTimeout(getQortRvnPrice, 300000) - } - - const getQortArrrPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/PIRATECHAIN?inverse=true` }).then((res) => { - setTimeout(() => { this.qortarrr = (Number(res) / 1e8).toFixed(8) }, 1) - }) - setTimeout(getQortArrrPrice, 300000) - } - - window.addEventListener('storage', () => { - this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") - this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") - this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") - this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") - const checkLanguage = localStorage.getItem('qortalLanguage') - const checkTheme = localStorage.getItem('qortalTheme') - - use(checkLanguage) - - this.theme = (checkTheme === 'dark') ? 'dark' : 'light' - document.querySelector('html').setAttribute('theme', this.theme) - }) - - if (!isElectron()) { - } else { - window.addEventListener('contextmenu', (event) => { - event.preventDefault() - window.parent.electronAPI.showMyMenu() - }) - } - - this.btcWallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address - this.ltcWallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address - this.dogeWallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address - this.dgbWallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address - this.rvnWallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address - this.arrrWallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address - - let configLoaded = false - - parentEpml.ready().then(() => { - parentEpml.subscribe('selected_address', async (selectedAddress) => { - this.selectedAddress = {} - selectedAddress = JSON.parse(selectedAddress) - if (!selectedAddress || Object.entries(selectedAddress).length === 0) return - this.selectedAddress = selectedAddress - - this.btcWallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address - this.ltcWwallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address - this.dogeWallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address - this.dgbWallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address - this.rvnWallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address - this.arrrWallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address - - this.updateAccountBalance() - }) - - parentEpml.subscribe('config', (c) => { - if (!configLoaded) { - setTimeout(getQortBtcPrice, 1) - setTimeout(getQortLtcPrice, 1) - setTimeout(getQortDogePrice, 1) - setTimeout(getQortDgbPrice, 1) - setTimeout(getQortRvnPrice, 1) - setTimeout(getQortArrrPrice, 1) - configLoaded = true - } - this.config = JSON.parse(c) - }) - - let coinSelectionMenu = this.shadowRoot.getElementById("coinSelectionMenu") - - coinSelectionMenu.addEventListener('change', function () { - _this.setForeignCoin(coinSelectionMenu.value,false) - }) - - _this.setForeignCoin(coinSelectionMenu.value,true) - }) - parentEpml.imReady() - this.btcTradebook() - this.ltcTradebook() - this.dogeTradebook() - this.dgbTradebook() - this.rvnTradebook() - this.arrrTradebook() - this.clearConsole() - setInterval(() => { - this.clearConsole() - }, 60000) - setInterval(() => { - this.getNewBlockedTrades() - }, 300000) - } - - clearConsole() { - if (!isElectron()) { - } else { - console.clear() - window.parent.electronAPI.clearCache() - } - } - - renderAutoLockButton() { - if (this.myAutoLockScreenPass === false && this.myAutoLockScreenSet === false) { - return html` -
    - this.openAutoSetScreenLockPass()} title="${translate("login.lp11")}"> -
    - ` - } else if (this.myAutoLockScreenSet === false) { - return html` -
    - this.setAutoLockQortal()} title="${translate("login.lp11")}"> -
    - ` - } else if (this.myAutoLockScreenSet === true) { - return html` -
    - -
    - ` - } - } - - openAutoSetScreenLockPass() { - this.shadowRoot.getElementById('autoLockPassword').value = '' - this.shadowRoot.getElementById('autoLockPasswordConfirm').value = '' - this.shadowRoot.getElementById('setAutoLockScreenPass').open() - } - - closewAutoSetScreenLockPass() { - this.shadowRoot.getElementById('setAutoLockScreenPass').close() - } - - autoCheckPass() { - const autoPassword = this.shadowRoot.getElementById('autoLockPassword').value - const autoRePassword = this.shadowRoot.getElementById('autoLockPasswordConfirm').value - - if (autoPassword === '') { - let snackbar1string = get("login.pleaseenter") - parentEpml.request('showSnackBar', `${snackbar1string}`) - return - } - - if (autoPassword != autoRePassword) { - let snackbar2string = get("login.notmatch") - parentEpml.request('showSnackBar', `${snackbar2string}`) - return - } - - if (autoPassword.length < 8) { - let snackbar3string = get("login.lessthen8") - parentEpml.request('showSnackBar', `${snackbar3string}`) - this.autoExtraConfirm() - } - - if (autoPassword.length >= 8) { - this.setAutoNewScreenPass() - let snackbar4string = get("login.lp6") - parentEpml.request('showSnackBar', `${snackbar4string}`) - } - } - - autoExtraConfirm() { - this.shadowRoot.getElementById('setAutoLockScreenPass').close() - this.shadowRoot.getElementById('autoExtraConfirmPass').open() - } - - closAutoExtraConfirmPass() { - this.shadowRoot.getElementById('autoExtraConfirmPass').close() - this.shadowRoot.getElementById('autoLockPassword').value = '' - this.shadowRoot.getElementById('autoLockPasswordConfirm').value = '' - } - - setAutoNewScreenPass() { - const autoRawPassword = this.shadowRoot.getElementById('autoLockPassword').value - const autoCryptPassword = encryptData(autoRawPassword, this.autoSalt) - localStorage.setItem(this.autoLockScreenPass, autoCryptPassword) - this.myAutoLockScreenPass = '' - this.myAutoLockScreenPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt) - this.shadowRoot.getElementById('setAutoLockScreenPass').close() - this.shadowRoot.getElementById('autoExtraConfirmPass').close() - this.shadowRoot.getElementById('autoLockPassword').value = '' - this.shadowRoot.getElementById('autoLockPasswordConfirm').value = '' - } - - setAutoLockQortal() { - this.autoHelperMessage = this.renderAutoHelperPass() - this.autoLockSet = '' - this.autoLockSet = encryptData(true, this.autoSalt) - localStorage.setItem(this.autoLockScreenSet, this.autoLockSet) - this.myAutoLockScreenSet = '' - this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt) - this.shadowRoot.getElementById('autoLockScreenActive').open() - } - - autoPassKeyListener(e) { - if (e.key === 'Enter') { - this.closeAutoLockScreenActive() - } - } - - async closeAutoLockScreenActive() { - const myAutoPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt) - const autoCheckPass = this.shadowRoot.getElementById('autoUnlockPassword').value - const errDelay = ms => new Promise(res => setTimeout(res, ms)) - - if (autoCheckPass === myAutoPass) { - this.autoLockSet = '' - this.autoLockSet = encryptData(false, this.autoSalt) - localStorage.setItem(this.autoLockScreenSet, this.autoLockSet) - this.myAutoLockScreenSet = '' - this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt) - this.shadowRoot.getElementById('autoLockScreenActive').close() - this.shadowRoot.getElementById('autoUnlockPassword').value = '' - this.autoHelperMessage = this.renderAutoHelperPass() - } else { - this.shadowRoot.getElementById('autoUnlockPassword').value = '' - this.autoHelperMessage = this.renderAutoHelperErr() - await errDelay(3000) - this.autoHelperMessage = this.renderAutoHelperPass() - - } - } - - renderAutoHelperPass() { - return html`${translate("login.pleaseenter")}` - } - - renderAutoHelperErr() { - return html`${translate("login.lp8")}` - } - - changeTheme() { - const checkTheme = localStorage.getItem('qortalTheme') - this.theme = (checkTheme === 'dark') ? 'dark' : 'light' - document.querySelector('html').setAttribute('theme', this.theme); - } - - changeLanguage() { - const checkLanguage = localStorage.getItem('qortalLanguage') - - if (checkLanguage === null || checkLanguage.length === 0) { - localStorage.setItem('qortalLanguage', 'us') - use('us') - } else { - use(checkLanguage) - } - } - - renderFetchText() { - return html`${translate("walletpage.wchange1")}` - } - - renderWarning() { - return html`${translate("tradepage.tchange48")} ${this.listedCoins.get(this.selectedCoin).coinCode}` - } - - renderBotWarning() { - return html`${translate("walletpage.wchange1")}` - } - - showAutoBuyGrid() { - switch(this.listedCoins.get(this.selectedCoin).coinCode) { - case "BTC": - return html`${this.tradeBotBTCTemplate()}` - break - case "LTC": - return html`${this.tradeBotLTCTemplate()}` - break - case "DOGE": - return html`${this.tradeBotDOGETemplate()}` - break - case "DGB": - return html`${this.tradeBotDGBTemplate()}` - break - case "RVN": - return html`${this.tradeBotRVNTemplate()}` - break - case "ARRR": - return html`${this.tradeBotARRRTemplate()}` - break - default: - break - } - } - - exchangeRateQort() { - switch(this.listedCoins.get(this.selectedCoin).coinCode) { - case "BTC": - this.qortRatio = this.qortbtc - break - case "LTC": - this.qortRatio = this.qortltc - break - case "DOGE": - this.qortRatio = this.qortdoge - break - case "DGB": - this.qortRatio = this.qortdgb - break - case "RVN": - this.qortRatio = this.qortrvn - break - case "ARRR": - this.qortRatio = this.qortarrr - break - default: - break - } - return html`${this.qortRatio}` - } - - exchangeRateForeign() { - if (this.listedCoins.get(this.selectedCoin).coinCode === "BTC") { - parentEpml.request('apiCall', { - url: `/crosschain/price/BITCOIN?inverse=false` - }).then((res) => { - this.btcqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.btcqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "LTC") { - parentEpml.request('apiCall', { - url: `/crosschain/price/LITECOIN?inverse=false` - }).then((res) => { - this.ltcqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.ltcqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "DOGE") { - parentEpml.request('apiCall', { - url: `/crosschain/price/DOGECOIN?inverse=false` - }).then((res) => { - this.dogeqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.dogeqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "DGB") { - parentEpml.request('apiCall', { - url: `/crosschain/price/DIGIBYTE?inverse=false` - }).then((res) => { - this.dgbqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.dgbqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "RVN") { - parentEpml.request('apiCall', { - url: `/crosschain/price/RAVENCOIN?inverse=false` - }).then((res) => { - this.rvnqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.rvnqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "ARRR") { - parentEpml.request('apiCall', { - url: `/crosschain/price/PIRATECHAIN?inverse=false` - }).then((res) => { - this.arrrqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.arrrqort}` - } - } - - async updateWalletBalance() { - let _url = `` - let _body = null - - switch (this.selectedCoin) { - case 'BITCOIN': - _url = `/crosschain/btc/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.derivedMasterPublicKey - break - case 'LITECOIN': - _url = `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey - break - case 'DOGECOIN': - _url = `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey - break - case 'DIGIBYTE': - _url = `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey - break - case 'RAVENCOIN': - _url = `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey - break - case 'PIRATECHAIN': - _url = `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58 - break - default: - break - } - - this.showGetWalletBance = true - this.showAddAutoBuy = false - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.listedCoins.get(this.selectedCoin).balance = (Number(res) / 1e8).toFixed(8) - } - }) - - this.showGetWalletBance = false - this.showAddAutoBuy = true - } - - async fetchWalletAddress(coin) { - switch (coin) { - case 'PIRATECHAIN': - let res = await parentEpml.request('apiCall', { - url: `/crosschain/arrr/walletaddress?apiKey=${this.getApiKey()}`, - method: 'POST', - body: `${window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58}`, - }) - if (res != null && res.error != 1201) { - this.arrrWalletAddress = res - } - break - - default: - // Not used for other coins yet - break - } - } - - async getDoneTrades() { - let tradesUrl = `` - clearTimeout(this.updateDoneTradesTimeout) - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const myAddress = window.parent.reduxStore.getState().app.selectedAddress.address - - switch (this.selectedCoin) { - case 'BITCOIN': - tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=BITCOIN&minimumTimestamp=1597310000000&limit=0&reverse=true` - break - case 'LITECOIN': - tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=LITECOIN&minimumTimestamp=1597310000000&limit=0&reverse=true` - break - case 'DOGECOIN': - tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=DOGECOIN&minimumTimestamp=1597310000000&limit=0&reverse=true` - break - case 'DIGIBYTE': - tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=DIGIBYTE&minimumTimestamp=1597310000000&limit=0&reverse=true` - break - case 'RAVENCOIN': - tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=RAVENCOIN&minimumTimestamp=1597310000000&limit=0&reverse=true` - break - case 'PIRATECHAIN': - tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=PIRATECHAIN&minimumTimestamp=1597310000000&limit=0&reverse=true` - break - default: - break - } - - this.isLoadingDoneTrades = true - - const doneTradesAll = await fetch(tradesUrl).then(response => { - return response.json() - }) - - this.listedCoins.get(this.selectedCoin).myGridBoughtItems = doneTradesAll.map(item => { - const searchAddress = item.buyerReceivingAddress - if (searchAddress == myAddress) { - return { - timestamp: item.tradeTimestamp, - foreignAmount: item.foreignAmount, - qortAmount: item.qortAmount - } - } - }).filter(item => !!item) - - this.isLoadingDoneTrades = false - this.updateDoneTradesTimeout = setTimeout(() => this.getDoneTrades(), 300000) - } - - btcTradebook() { - if (localStorage.getItem(this.btcWallet) === null) { - localStorage.setItem(this.btcWallet, "") - } else { - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") - } - } - - addToBTCTradebook() { - const addBotBtcQortAmount = this.shadowRoot.getElementById('autoBuyBTCQortAmountInput').value - const addBotBtcPrice = this.shadowRoot.getElementById('autoBuyBTCPriceInput').value - const addBtcQortAmount = this.round(parseFloat(addBotBtcQortAmount)) - const addBtcPrice = this.round(parseFloat(addBotBtcPrice)) - - var oldBtcTradebook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") - - const newBtcTradebookItem = { - botBtcQortAmount: addBtcQortAmount, - botBtcPrice: addBtcPrice - } - - oldBtcTradebook.push(newBtcTradebookItem) - - localStorage.setItem(this.btcWallet, JSON.stringify(oldBtcTradebook)) - - let btctradebookstring = get("tradepage.tchange44") - parentEpml.request('showSnackBar', `${btctradebookstring}`) - - this.closeBTCTradebookDialog() - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") - } - - closeBTCTradebookDialog() { - this.shadowRoot.querySelector('#tradeBotBTCAddDialog').close() - this.clearTradeBotForm() - } - - removeBTCTradebook() { - localStorage.removeItem(this.btcWallet) - localStorage.setItem(this.btcWallet, "") - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") - - this.autoBuyBotDisable = false - - let btcstring = get("tradepage.tchange41") - parentEpml.request('showSnackBar', `${btcstring}`) - } - - ltcTradebook() { - if (localStorage.getItem(this.ltcWallet) === null) { - localStorage.setItem(this.ltcWallet, "") - } else { - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") - } - } - - addToLTCTradebook() { - const addBotLtcQortAmount = this.shadowRoot.getElementById('autoBuyLTCQortAmountInput').value - const addBotLtcPrice = this.shadowRoot.getElementById('autoBuyLTCPriceInput').value - const addLtcQortAmount = this.round(parseFloat(addBotLtcQortAmount)) - const addLtcPrice = this.round(parseFloat(addBotLtcPrice)) - - var oldLtcTradebook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") - - const newLtcTradebookItem = { - botLtcQortAmount: addLtcQortAmount, - botLtcPrice: addLtcPrice - } - - oldLtcTradebook.push(newLtcTradebookItem) - - localStorage.setItem(this.ltcWallet, JSON.stringify(oldLtcTradebook)) - - let ltctradebookstring = get("tradepage.tchange44") - parentEpml.request('showSnackBar', `${ltctradebookstring}`) - - this.closeLTCTradebookDialog() - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") - } - - closeLTCTradebookDialog() { - this.shadowRoot.querySelector('#tradeBotLTCAddDialog').close() - this.clearTradeBotForm() - } - - removeLTCTradebook() { - localStorage.removeItem(this.ltcWallet) - localStorage.setItem(this.ltcWallet, "") - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") - - this.autoBuyBotDisable = false + ` + } + + tradeBotARRRTemplate() { + return html` +
    +
    +
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    +
    + + { + render(html`${data.item.botArrrQortAmount}`, root) + }} + > + + { + render(html`${data.item.botArrrPrice}`, root) + }} + > + + { + const totalCoins = this.round(parseFloat(data.item.botArrrQortAmount) * parseFloat(data.item.botArrrPrice)) + const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myBotFunds) > Number(totalCoins)) { + this.autoBuyBotDisable = false + render(html`${totalCoins}`, root) + } else { + this.autoBuyBotDisable = true + render(html`${totalCoins}`, root) + } + }} + > + + { + render(html` + this.removeARRRTradebook()}> + delete  ${translate("nodepage.nchange12")} + + `, root) + }} + > + + + ${this.isEmptyArray(this.tradeBotArrrBook) ? html` + + ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} + + `: ''} +
    + ${this.autoBuyBotDisable ? html` +
    ${this.renderBotWarning()}
    + `: ''} +
    +
    + ` + } + + clearConsole() { + if (!isElectron()) { + } else { + console.clear() + window.parent.electronAPI.clearCache() + } + } + + renderAutoLockButton() { + if (this.myAutoLockScreenPass === false && this.myAutoLockScreenSet === false) { + return html` +
    + this.openAutoSetScreenLockPass()} title="${translate("login.lp11")}"> +
    + ` + } else if (this.myAutoLockScreenSet === false) { + return html` +
    + this.setAutoLockQortal()} title="${translate("login.lp11")}"> +
    + ` + } else if (this.myAutoLockScreenSet === true) { + return html` +
    + +
    + ` + } + } + + openAutoSetScreenLockPass() { + this.shadowRoot.getElementById('autoLockPassword').value = '' + this.shadowRoot.getElementById('autoLockPasswordConfirm').value = '' + this.shadowRoot.getElementById('setAutoLockScreenPass').open() + } + + closewAutoSetScreenLockPass() { + this.shadowRoot.getElementById('setAutoLockScreenPass').close() + } + + autoCheckPass() { + const autoPassword = this.shadowRoot.getElementById('autoLockPassword').value + const autoRePassword = this.shadowRoot.getElementById('autoLockPasswordConfirm').value + + if (autoPassword === '') { + let snackbar1string = get("login.pleaseenter") + parentEpml.request('showSnackBar', `${snackbar1string}`) + return + } + + if (autoPassword != autoRePassword) { + let snackbar2string = get("login.notmatch") + parentEpml.request('showSnackBar', `${snackbar2string}`) + return + } + + if (autoPassword.length < 8) { + let snackbar3string = get("login.lessthen8") + parentEpml.request('showSnackBar', `${snackbar3string}`) + this.autoExtraConfirm() + } + + if (autoPassword.length >= 8) { + this.setAutoNewScreenPass() + let snackbar4string = get("login.lp6") + parentEpml.request('showSnackBar', `${snackbar4string}`) + } + } + + autoExtraConfirm() { + this.shadowRoot.getElementById('setAutoLockScreenPass').close() + this.shadowRoot.getElementById('autoExtraConfirmPass').open() + } + + closAutoExtraConfirmPass() { + this.shadowRoot.getElementById('autoExtraConfirmPass').close() + this.shadowRoot.getElementById('autoLockPassword').value = '' + this.shadowRoot.getElementById('autoLockPasswordConfirm').value = '' + } + + setAutoNewScreenPass() { + const autoRawPassword = this.shadowRoot.getElementById('autoLockPassword').value + const autoCryptPassword = encryptData(autoRawPassword, this.autoSalt) + localStorage.setItem(this.autoLockScreenPass, autoCryptPassword) + this.myAutoLockScreenPass = '' + this.myAutoLockScreenPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt) + this.shadowRoot.getElementById('setAutoLockScreenPass').close() + this.shadowRoot.getElementById('autoExtraConfirmPass').close() + this.shadowRoot.getElementById('autoLockPassword').value = '' + this.shadowRoot.getElementById('autoLockPasswordConfirm').value = '' + } + + setAutoLockQortal() { + this.autoHelperMessage = this.renderAutoHelperPass() + this.autoLockSet = '' + this.autoLockSet = encryptData(true, this.autoSalt) + localStorage.setItem(this.autoLockScreenSet, this.autoLockSet) + this.myAutoLockScreenSet = '' + this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt) + this.shadowRoot.getElementById('autoLockScreenActive').open() + } + + autoPassKeyListener(e) { + if (e.key === 'Enter') { + this.closeAutoLockScreenActive() + } + } + + async closeAutoLockScreenActive() { + const myAutoPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt) + const autoCheckPass = this.shadowRoot.getElementById('autoUnlockPassword').value + const errDelay = ms => new Promise(res => setTimeout(res, ms)) + + if (autoCheckPass === myAutoPass) { + this.autoLockSet = '' + this.autoLockSet = encryptData(false, this.autoSalt) + localStorage.setItem(this.autoLockScreenSet, this.autoLockSet) + this.myAutoLockScreenSet = '' + this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt) + this.shadowRoot.getElementById('autoLockScreenActive').close() + this.shadowRoot.getElementById('autoUnlockPassword').value = '' + this.autoHelperMessage = this.renderAutoHelperPass() + } else { + this.shadowRoot.getElementById('autoUnlockPassword').value = '' + this.autoHelperMessage = this.renderAutoHelperErr() + await errDelay(3000) + this.autoHelperMessage = this.renderAutoHelperPass() + + } + } + + renderAutoHelperPass() { + return html`${translate("login.pleaseenter")}` + } + + renderAutoHelperErr() { + return html`${translate("login.lp8")}` + } + + changeTheme() { + const checkTheme = localStorage.getItem('qortalTheme') + this.theme = (checkTheme === 'dark') ? 'dark' : 'light' + document.querySelector('html').setAttribute('theme', this.theme); + } + + changeLanguage() { + const checkLanguage = localStorage.getItem('qortalLanguage') + if (checkLanguage === null || checkLanguage.length === 0) { + localStorage.setItem('qortalLanguage', 'us') + use('us') + } else { + use(checkLanguage) + } + } + + renderFetchText() { + return html`${translate("walletpage.wchange1")}` + } + + renderWarning() { + return html`${translate("tradepage.tchange48")} ${this.listedCoins.get(this.selectedCoin).coinCode}` + } + + renderBotWarning() { + return html`${translate("walletpage.wchange1")}` + } + + showAutoBuyGrid() { + switch (this.listedCoins.get(this.selectedCoin).coinCode) { + case "BTC": + return html`${this.tradeBotBTCTemplate()}` + break + case "LTC": + return html`${this.tradeBotLTCTemplate()}` + break + case "DOGE": + return html`${this.tradeBotDOGETemplate()}` + break + case "DGB": + return html`${this.tradeBotDGBTemplate()}` + break + case "RVN": + return html`${this.tradeBotRVNTemplate()}` + break + case "ARRR": + return html`${this.tradeBotARRRTemplate()}` + break + default: + break + } + } + + exchangeRateQort() { + switch (this.listedCoins.get(this.selectedCoin).coinCode) { + case "BTC": + this.qortRatio = this.qortbtc + break + case "LTC": + this.qortRatio = this.qortltc + break + case "DOGE": + this.qortRatio = this.qortdoge + break + case "DGB": + this.qortRatio = this.qortdgb + break + case "RVN": + this.qortRatio = this.qortrvn + break + case "ARRR": + this.qortRatio = this.qortarrr + break + default: + break + } + return html`${this.qortRatio}` + } + + exchangeRateForeign() { + if (this.listedCoins.get(this.selectedCoin).coinCode === "BTC") { + parentEpml.request('apiCall', { + url: `/crosschain/price/BITCOIN?inverse=false` + }).then((res) => { + this.btcqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.btcqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "LTC") { + parentEpml.request('apiCall', { + url: `/crosschain/price/LITECOIN?inverse=false` + }).then((res) => { + this.ltcqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.ltcqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "DOGE") { + parentEpml.request('apiCall', { + url: `/crosschain/price/DOGECOIN?inverse=false` + }).then((res) => { + this.dogeqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.dogeqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "DGB") { + parentEpml.request('apiCall', { + url: `/crosschain/price/DIGIBYTE?inverse=false` + }).then((res) => { + this.dgbqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.dgbqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "RVN") { + parentEpml.request('apiCall', { + url: `/crosschain/price/RAVENCOIN?inverse=false` + }).then((res) => { + this.rvnqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.rvnqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "ARRR") { + parentEpml.request('apiCall', { + url: `/crosschain/price/PIRATECHAIN?inverse=false` + }).then((res) => { + this.arrrqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.arrrqort}` + } + } + + async updateWalletBalance() { + let _url = `` + let _body = null + + switch (this.selectedCoin) { + case 'BITCOIN': + _url = `/crosschain/btc/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.derivedMasterPublicKey + break + case 'LITECOIN': + _url = `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey + break + case 'DOGECOIN': + _url = `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey + break + case 'DIGIBYTE': + _url = `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey + break + case 'RAVENCOIN': + _url = `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey + break + case 'PIRATECHAIN': + _url = `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58 + break + default: + break + } + + this.showGetWalletBance = true + this.showAddAutoBuy = false + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.listedCoins.get(this.selectedCoin).balance = (Number(res) / 1e8).toFixed(8) + } + }) + + this.showGetWalletBance = false + this.showAddAutoBuy = true + } + + async fetchWalletAddress(coin) { + switch (coin) { + case 'PIRATECHAIN': + let res = await parentEpml.request('apiCall', { + url: `/crosschain/arrr/walletaddress?apiKey=${this.getApiKey()}`, + method: 'POST', + body: `${window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58}` + }) + if (res != null && res.error != 1201) { + this.arrrWalletAddress = res + } + break + + default: + // Not used for other coins yet + break + } + } + + async getDoneTrades() { + let tradesUrl = `` + clearTimeout(this.updateDoneTradesTimeout) + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const myAddress = window.parent.reduxStore.getState().app.selectedAddress.address + + switch (this.selectedCoin) { + case 'BITCOIN': + tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=BITCOIN&minimumTimestamp=1597310000000&limit=0&reverse=true` + break + case 'LITECOIN': + tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=LITECOIN&minimumTimestamp=1597310000000&limit=0&reverse=true` + break + case 'DOGECOIN': + tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=DOGECOIN&minimumTimestamp=1597310000000&limit=0&reverse=true` + break + case 'DIGIBYTE': + tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=DIGIBYTE&minimumTimestamp=1597310000000&limit=0&reverse=true` + break + case 'RAVENCOIN': + tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=RAVENCOIN&minimumTimestamp=1597310000000&limit=0&reverse=true` + break + case 'PIRATECHAIN': + tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=PIRATECHAIN&minimumTimestamp=1597310000000&limit=0&reverse=true` + break + default: + break + } + + this.isLoadingDoneTrades = true + + const doneTradesAll = await fetch(tradesUrl).then(response => { + return response.json() + }) + + this.listedCoins.get(this.selectedCoin).myGridBoughtItems = doneTradesAll.map(item => { + const searchAddress = item.buyerReceivingAddress + if (searchAddress == myAddress) { + return { + timestamp: item.tradeTimestamp, + foreignAmount: item.foreignAmount, + qortAmount: item.qortAmount + } + } + }).filter(item => !!item) + + this.isLoadingDoneTrades = false + this.updateDoneTradesTimeout = setTimeout(() => this.getDoneTrades(), 300000) + } + + btcTradebook() { + if (localStorage.getItem(this.btcWallet) === null) { + localStorage.setItem(this.btcWallet, "") + } else { + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") + } + } + + addToBTCTradebook() { + const addBotBtcQortAmount = this.shadowRoot.getElementById('autoBuyBTCQortAmountInput').value + const addBotBtcPrice = this.shadowRoot.getElementById('autoBuyBTCPriceInput').value + const addBtcQortAmount = this.round(parseFloat(addBotBtcQortAmount)) + const addBtcPrice = this.round(parseFloat(addBotBtcPrice)) + + var oldBtcTradebook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") + + const newBtcTradebookItem = { + botBtcQortAmount: addBtcQortAmount, + botBtcPrice: addBtcPrice + } + + oldBtcTradebook.push(newBtcTradebookItem) + + localStorage.setItem(this.btcWallet, JSON.stringify(oldBtcTradebook)) + + let btctradebookstring = get("tradepage.tchange44") + parentEpml.request('showSnackBar', `${btctradebookstring}`) + + this.closeBTCTradebookDialog() + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") + } + + closeBTCTradebookDialog() { + this.shadowRoot.querySelector('#tradeBotBTCAddDialog').close() + this.clearTradeBotForm() + } + + removeBTCTradebook() { + localStorage.removeItem(this.btcWallet) + localStorage.setItem(this.btcWallet, "") + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") + + this.autoBuyBotDisable = false + + let btcstring = get("tradepage.tchange41") + parentEpml.request('showSnackBar', `${btcstring}`) + } + + ltcTradebook() { + if (localStorage.getItem(this.ltcWallet) === null) { + localStorage.setItem(this.ltcWallet, "") + } else { + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") + } + } + + addToLTCTradebook() { + const addBotLtcQortAmount = this.shadowRoot.getElementById('autoBuyLTCQortAmountInput').value + const addBotLtcPrice = this.shadowRoot.getElementById('autoBuyLTCPriceInput').value + const addLtcQortAmount = this.round(parseFloat(addBotLtcQortAmount)) + const addLtcPrice = this.round(parseFloat(addBotLtcPrice)) + + var oldLtcTradebook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") + + const newLtcTradebookItem = { + botLtcQortAmount: addLtcQortAmount, + botLtcPrice: addLtcPrice + } + + oldLtcTradebook.push(newLtcTradebookItem) + + localStorage.setItem(this.ltcWallet, JSON.stringify(oldLtcTradebook)) + + let ltctradebookstring = get("tradepage.tchange44") + parentEpml.request('showSnackBar', `${ltctradebookstring}`) + + this.closeLTCTradebookDialog() + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") + } + + closeLTCTradebookDialog() { + this.shadowRoot.querySelector('#tradeBotLTCAddDialog').close() + this.clearTradeBotForm() + } + + removeLTCTradebook() { + localStorage.removeItem(this.ltcWallet) + localStorage.setItem(this.ltcWallet, "") + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") + + this.autoBuyBotDisable = false - let ltcstring = get("tradepage.tchange41") - parentEpml.request('showSnackBar', `${ltcstring}`) - } + let ltcstring = get("tradepage.tchange41") + parentEpml.request('showSnackBar', `${ltcstring}`) + } - dogeTradebook() { - if (localStorage.getItem(this.dogeWallet) === null) { - localStorage.setItem(this.dogeWallet, "") - } else { - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") - } - } - - addToDOGETradebook() { - const addBotDogeQortAmount = this.shadowRoot.getElementById('autoBuyDOGEQortAmountInput').value - const addBotDogePrice = this.shadowRoot.getElementById('autoBuyDOGEPriceInput').value - const addDogeQortAmount = this.round(parseFloat(addBotDogeQortAmount)) - const addDogePrice = this.round(parseFloat(addBotDogePrice)) + dogeTradebook() { + if (localStorage.getItem(this.dogeWallet) === null) { + localStorage.setItem(this.dogeWallet, "") + } else { + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") + } + } + + addToDOGETradebook() { + const addBotDogeQortAmount = this.shadowRoot.getElementById('autoBuyDOGEQortAmountInput').value + const addBotDogePrice = this.shadowRoot.getElementById('autoBuyDOGEPriceInput').value + const addDogeQortAmount = this.round(parseFloat(addBotDogeQortAmount)) + const addDogePrice = this.round(parseFloat(addBotDogePrice)) - var oldDogeTradebook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") + var oldDogeTradebook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") - const newDogeTradebookItem = { - botDogeQortAmount: addDogeQortAmount, - botDogePrice: addDogePrice - } + const newDogeTradebookItem = { + botDogeQortAmount: addDogeQortAmount, + botDogePrice: addDogePrice + } - oldDogeTradebook.push(newDogeTradebookItem) + oldDogeTradebook.push(newDogeTradebookItem) - localStorage.setItem(this.dogeWallet, JSON.stringify(oldDogeTradebook)) + localStorage.setItem(this.dogeWallet, JSON.stringify(oldDogeTradebook)) - let dogetradebookstring = get("tradepage.tchange44") - parentEpml.request('showSnackBar', `${dogetradebookstring}`) + let dogetradebookstring = get("tradepage.tchange44") + parentEpml.request('showSnackBar', `${dogetradebookstring}`) - this.closeDOGETradebookDialog() - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") - } + this.closeDOGETradebookDialog() + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") + } - closeDOGETradebookDialog() { - this.shadowRoot.querySelector('#tradeBotDOGEAddDialog').close() - this.clearTradeBotForm() - } - - removeDOGETradebook() { - localStorage.removeItem(this.dogeWallet) - localStorage.setItem(this.dogeWallet, "") - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") + closeDOGETradebookDialog() { + this.shadowRoot.querySelector('#tradeBotDOGEAddDialog').close() + this.clearTradeBotForm() + } + + removeDOGETradebook() { + localStorage.removeItem(this.dogeWallet) + localStorage.setItem(this.dogeWallet, "") + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") - this.autoBuyBotDisable = false + this.autoBuyBotDisable = false - let dogestring = get("tradepage.tchange41") - parentEpml.request('showSnackBar', `${dogestring}`) - } + let dogestring = get("tradepage.tchange41") + parentEpml.request('showSnackBar', `${dogestring}`) + } - dgbTradebook() { - if (localStorage.getItem(this.dgbWallet) === null) { - localStorage.setItem(this.dgbWallet, "") - } else { - this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") - } - } - - addToDGBTradebook() { - const addBotDgbQortAmount = this.shadowRoot.getElementById('autoBuyDGBQortAmountInput').value - const addBotDgbPrice = this.shadowRoot.getElementById('autoBuyDGBPriceInput').value - const addDgbQortAmount = this.round(parseFloat(addBotDgbQortAmount)) - const addDgbPrice = this.round(parseFloat(addBotDgbPrice)) + dgbTradebook() { + if (localStorage.getItem(this.dgbWallet) === null) { + localStorage.setItem(this.dgbWallet, "") + } else { + this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") + } + } + + addToDGBTradebook() { + const addBotDgbQortAmount = this.shadowRoot.getElementById('autoBuyDGBQortAmountInput').value + const addBotDgbPrice = this.shadowRoot.getElementById('autoBuyDGBPriceInput').value + const addDgbQortAmount = this.round(parseFloat(addBotDgbQortAmount)) + const addDgbPrice = this.round(parseFloat(addBotDgbPrice)) - var oldDgbTradebook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") + var oldDgbTradebook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") - const newDgbTradebookItem = { - botDgbQortAmount: addDgbQortAmount, - botDgbPrice: addDgbPrice - } + const newDgbTradebookItem = { + botDgbQortAmount: addDgbQortAmount, + botDgbPrice: addDgbPrice + } - oldDgbTradebook.push(newDgbTradebookItem) + oldDgbTradebook.push(newDgbTradebookItem) - localStorage.setItem(this.dgbWallet, JSON.stringify(oldDgbTradebook)) + localStorage.setItem(this.dgbWallet, JSON.stringify(oldDgbTradebook)) - let dgbtradebookstring = get("tradepage.tchange44") - parentEpml.request('showSnackBar', `${dgbtradebookstring}`) + let dgbtradebookstring = get("tradepage.tchange44") + parentEpml.request('showSnackBar', `${dgbtradebookstring}`) - this.closeDGBTradebookDialog() - this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") - } + this.closeDGBTradebookDialog() + this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") + } - closeDGBTradebookDialog() { - this.shadowRoot.querySelector('#tradeBotDGBAddDialog').close() - this.clearTradeBotForm() - } - - removeDGBTradebook() { - localStorage.removeItem(this.dgbWallet) - localStorage.setItem(this.dgbWallet, "") - this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") + closeDGBTradebookDialog() { + this.shadowRoot.querySelector('#tradeBotDGBAddDialog').close() + this.clearTradeBotForm() + } + + removeDGBTradebook() { + localStorage.removeItem(this.dgbWallet) + localStorage.setItem(this.dgbWallet, "") + this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") - this.autoBuyBotDisable = false + this.autoBuyBotDisable = false - let dgbstring = get("tradepage.tchange41") - parentEpml.request('showSnackBar', `${dgbstring}`) - } + let dgbstring = get("tradepage.tchange41") + parentEpml.request('showSnackBar', `${dgbstring}`) + } - rvnTradebook() { - if (localStorage.getItem(this.rvnWallet) === null) { - localStorage.setItem(this.rvnWallet, "") - } else { - this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") - } - } + rvnTradebook() { + if (localStorage.getItem(this.rvnWallet) === null) { + localStorage.setItem(this.rvnWallet, "") + } else { + this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") + } + } - addToRVNTradebook() { - const addBotRvnQortAmount = this.shadowRoot.getElementById('autoBuyRVNQortAmountInput').value - const addBotRvnPrice = this.shadowRoot.getElementById('autoBuyRVNPriceInput').value - const addRvnQortAmount = this.round(parseFloat(addBotRvnQortAmount)) - const addRvnPrice = this.round(parseFloat(addBotRvnPrice)) - - var oldRvnTradebook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") + addToRVNTradebook() { + const addBotRvnQortAmount = this.shadowRoot.getElementById('autoBuyRVNQortAmountInput').value + const addBotRvnPrice = this.shadowRoot.getElementById('autoBuyRVNPriceInput').value + const addRvnQortAmount = this.round(parseFloat(addBotRvnQortAmount)) + const addRvnPrice = this.round(parseFloat(addBotRvnPrice)) + + var oldRvnTradebook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") - const newRvnTradebookItem = { - botRvnQortAmount: addRvnQortAmount, - botRvnPrice: addRvnPrice - } - - oldRvnTradebook.push(newRvnTradebookItem) - - localStorage.setItem(this.rvnWallet, JSON.stringify(oldRvnTradebook)) - - let rvntradebookstring = get("tradepage.tchange44") - parentEpml.request('showSnackBar', `${rvntradebookstring}`) - - this.closeRVNTradebookDialog() - this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") - } - - closeRVNTradebookDialog() { - this.shadowRoot.querySelector('#tradeBotRVNAddDialog').close() - this.clearTradeBotForm() - } - - removeRVNTradebook() { - localStorage.removeItem(this.rvnWallet) - localStorage.setItem(this.rvnWallet, "") - this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") - - this.autoBuyBotDisable = false - - let rvnstring = get("tradepage.tchange41") - parentEpml.request('showSnackBar', `${rvnstring}`) - } - - arrrTradebook() { - if (localStorage.getItem(this.arrrWallet) === null) { - localStorage.setItem(this.arrrWallet, "") - } else { - this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") - } - } - - addToARRRTradebook() { - const addBotArrrQortAmount = this.shadowRoot.getElementById('autoBuyARRRQortAmountInput').value - const addBotArrrPrice = this.shadowRoot.getElementById('autoBuyARRRPriceInput').value - const addArrrQortAmount = this.round(parseFloat(addBotArrrQortAmount)) - const addArrrPrice = this.round(parseFloat(addBotArrrPrice)) - - var oldArrrTradebook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") - - const newArrrTradebookItem = { - botArrrQortAmount: addArrrQortAmount, - botArrrPrice: addArrrPrice - } - - oldArrrTradebook.push(newArrrTradebookItem) - - localStorage.setItem(this.arrrWallet, JSON.stringify(oldArrrTradebook)) - - let arrrtradebookstring = get("tradepage.tchange44") - parentEpml.request('showSnackBar', `${arrrtradebookstring}`) - - this.closeARRRTradebookDialog() - this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") - } - - closeARRRTradebookDialog() { - this.shadowRoot.querySelector('#tradeBotARRRAddDialog').close() - this.clearTradeBotForm() - } - - removeARRRTradebook() { - localStorage.removeItem(this.arrrWallet) - localStorage.setItem(this.arrrWallet, "") - this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") - - this.autoBuyBotDisable = false - - let arrrstring = get("tradepage.tchange41") - parentEpml.request('showSnackBar', `${arrrstring}`) - } - - async setForeignCoin(coin,beingInitialized) { - let _this = this - this.selectedCoin = coin - - let coinSelectionMenu=this.shadowRoot.getElementById("coinSelectionMenu") - - if(beingInitialized){ - coinSelectionMenu.shadowRoot.querySelector('.mdc-select--outlined .mdc-select__anchor').setAttribute('style', 'padding-left: 60px;') - let pairIconContainer = document.createElement("span") - let pairicon = (_this.listedCoins.get(_this.selectedCoin).coinCode).toLowerCase() - pairIconContainer.setAttribute("class","pairIconContainer") - pairIconContainer.setAttribute('style', 'left: 10px;top: 50%;transform: translate(0, -50%);height: 26px;width: 45px;position: absolute;background-repeat: no-repeat;background-size: cover;background-image: url(/img/qort'+pairicon+'.png);') - coinSelectionMenu.shadowRoot.querySelector('.mdc-select--outlined .mdc-select__anchor').appendChild(pairIconContainer) - }else{ - let pairIconContainer = coinSelectionMenu.shadowRoot.querySelector(".mdc-select--outlined .mdc-select__anchor span.pairIconContainer") - let pairicon = (_this.listedCoins.get(_this.selectedCoin).coinCode).toLowerCase() - pairIconContainer.style.backgroundImage='url(/img/qort'+pairicon+'.png)' - } - - this.isLoadingOpenTrades = true - this.createConnection() - this._openOrdersGrid.querySelector('#priceColumn').headerRenderer = function (root) { - const priceString2 = get("tradepage.tchange9") - root.innerHTML = '' + priceString2 + ' (' + _this.listedCoins.get(_this.selectedCoin).coinCode + ')' - } - this.clearTradeBotForm() - clearTimeout(this.updateDoneTradesTimeout) - await this.getDoneTrades() - this.updateDoneTradesTimeout = setTimeout(() => this.getDoneTrades(), 180000) - await this.updateWalletBalance() - await this.fetchWalletAddress(coin) - - } - - async reRenderOpenFilteredOrders() { - this.requestUpdate() - await this.updateComplete - this.isLoadingOpenTrades = false - } - - async reRenderMyOpenOrders() { - this.requestUpdate() - await this.updateComplete - this.isLoadingMyOpenOrders = false - } - - addAutoBuyAction() { - this.autoBuyWarning = false - this.clearTradeBotForm() - this.shadowRoot.querySelector('#tradeBot' + this.listedCoins.get(this.selectedCoin).coinCode + 'AddDialog').show() - } - - checkTradeBotValues() { - const checkTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value - const checkTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value - const checkTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value - const checkAmount = this.round(parseFloat(checkTradeBotAmountInput)) - const checkPrice = this.round(parseFloat(checkTradeBotPriceInput)) - const checkTotal = this.round(parseFloat(checkTradeBotTotalInput)) - - if (Number(checkAmount) === 0) { - let amountString = get("tradepage.tchange34") - parentEpml.request('showSnackBar', `${amountString}`) - } else if (Number(checkPrice) === 0) { - let priceString = get("tradepage.tchange35") - parentEpml.request('showSnackBar', `${priceString}`) - } else if (Number(checkTotal) === 0) { - let totalString = get("tradepage.tchange35") - parentEpml.request('showSnackBar', `${totalString}`) - } else { - this.showAddToAutoBuyStore() - } - } - - showAddToAutoBuyStore() { - switch(this.listedCoins.get(this.selectedCoin).coinCode) { - case "BTC": - this.addToBTCTradebook() - break - case "LTC": - this.addToLTCTradebook() - break - case "DOGE": - this.addToDOGETradebook() - break - case "DGB": - this.addToDGBTradebook() - break - case "RVN": - this.addToRVNTradebook() - break - case "ARRR": - this.addToARRRTradebook() - break - default: - break - } - } - - processOfferingTrade(offer) { - try { - if(this.listedCoins.get(offer.foreignBlockchain).name!='') { - const offerItem = { - ...offer, - qortAmount: parseFloat(offer.qortAmount), - price: parseFloat(offer.foreignAmount) / parseFloat(offer.qortAmount), - } - const addOffer = () => { - this.listedCoins.get(offer.foreignBlockchain).openOrders.unshift(offerItem) - } - const initOffer = () => { - this.listedCoins.get(offer.foreignBlockchain).openOrders.push(offerItem) - } - this.listedCoins.get(offer.foreignBlockchain).openOrders.length === 0 ? initOffer() : addOffer() - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null - } - } catch(e) { - console.log("Error adding offer from "+offer.foreignBlockchain) - } - } - - processRedeemedTrade(offer) { - try { - if (this.listedCoins.get(offer.foreignBlockchain).name!='') { - - if (offer.qortalCreator === this.selectedAddress.address) { - if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - const offerItem = { - ...offer, - mode: 'SOLD', - } - this._myHistoricTradesGrid.items.unshift(offerItem) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null - } else if (offer.partnerQortalReceivingAddress === this.selectedAddress.address) { - if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - const offerItem = { - ...offer, - mode: 'BOUGHT', - } - this._myHistoricTradesGrid.items.unshift(offerItem) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null - } - const addNewHistoricTrade = () => { - this._historicTradesGrid.items.unshift(offer) - this._historicTradesGrid.clearCache() - } - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? addNewHistoricTrade() : null - - } - } catch(e) { - console.log("Error processing redeemed trade offer from "+offer.foreignBlockchain) - } - } - - processTradingTrade(offer) { - try { - if (this.listedCoins.get(offer.foreignBlockchain).name!='') { - - if (offer.qortalCreator === this.selectedAddress.address && this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - this._openOrdersGrid.items.forEach((item, index) => { - if (item.qortalAtAddress === offer.qortalAtAddress) { - this._openOrdersGrid.items.splice(index, 1) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null - } - }) - this.listedCoins.get(offer.foreignBlockchain).openOrders = this.listedCoins.get(offer.foreignBlockchain).openOrders.filter((order) => order.qortalAtAddress !== offer.qortalAtAddress) - } - } catch(e) { - console.log("Error processing trading trade offer from "+offer.foreignBlockchain) - } - } - - processRefundedTrade(offer) { - try { - if (this.listedCoins.get(offer.foreignBlockchain).name!='') { - - if (offer.qortalCreator === this.selectedAddress.address) { - if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - this._myHistoricTradesGrid.items.unshift(offer) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null - } - - } - } catch(e) { - console.log("Error processing refunded trade offer from "+offer.foreignBlockchain) - } - } - - processCancelledTrade(offer) { - try { - if (this.listedCoins.get(offer.foreignBlockchain).name!='') { - - if (offer.qortalCreator === this.selectedAddress.address) { - if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - this._myHistoricTradesGrid.items.unshift(offer) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null - } - this._openOrdersGrid.items.forEach((item, index) => { - if (item.qortalAtAddress === offer.qortalAtAddress) { - this._openOrdersGrid.items.splice(index, 1) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null - } - }) - this.listedCoins.get(offer.foreignBlockchain).openOrders = this.listedCoins.get(offer.foreignBlockchain).openOrders.filter((order) => order.qortalAtAddress !== offer.qortalAtAddress) - this._stuckOrdersGrid.items.forEach((item, index) => { - if (item.qortalAtAddress === offer.qortalAtAddress) { - this._stuckOrdersGrid.items.splice(index, 1) - this._stuckOrdersGrid.clearCache() - } - }) - } - } catch(e) { - console.log("Error processing cancelled trade offer from "+offer.foreignBlockchain) - } - } - - processTradeOffers(offers) { - offers.forEach((offer) => { - if (offer.mode === 'OFFERING') { - this.processOfferingTrade(offer) - } - }) - } - - processTradeBotStates(tradeStates) { - - const BitcoinACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - const LitecoinACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - const DogecoinACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - const DigibyteACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - const RavencoinACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - const PirateChainACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - switch (this.selectedCoin) { - case 'BITCOIN': - BitcoinACCTv1(tradeStates) - break - case 'LITECOIN': - LitecoinACCTv1(tradeStates) - break - case 'DOGECOIN': - DogecoinACCTv1(tradeStates) - break - case 'DIGIBYTE': - DigibyteACCTv1(tradeStates) - break - case 'RAVENCOIN': - RavencoinACCTv1(tradeStates) - break - case 'PIRATECHAIN': - PirateChainACCTv1(tradeStates) - break - default: - break - } - } - - changeTradeBotState(state, tradeState) { - this.isLoadingMyOpenOrders = true - const stateItem = { - ...state, - _tradeState: tradeState, - } - const item = this._myOrdersGrid.querySelector(`#${state.atAddress}`) - const addStateItem = () => { - this.reRenderMyOpenOrders() - this._myOrdersGrid.items.unshift(stateItem) - this._myOrdersGrid.clearCache() - } - const updateStateItem = () => { - this._myOrdersGrid.items.forEach((item, index) => { - if (item.atAddress === state.atAddress) { - this.reRenderMyOpenOrders() - this._myOrdersGrid.items.splice(index, 1) - this._myOrdersGrid.items.unshift(stateItem) - this._myOrdersGrid.clearCache() - } - }) - } - item ? updateStateItem() : addStateItem() - } - - handleCompletedState(state) { - this._myOrdersGrid.items.forEach((item, index) => { - if (item.atAddress === state.atAddress) { - this.reRenderMyOpenOrders() - this._myOrdersGrid.items.splice(index, 1) - this._myOrdersGrid.clearCache() - } - }) - } - - initSocket() { - let _relatedCoin = "" - let tradePresenceTxns = null - let offeringTrades = null - - self.addEventListener('message', function (event) { - switch (event.data.type) { - case 'open_orders': - offeringTrades = event.data.content - processOffersWithPresence() - break - case 'set_coin': - _relatedCoin = event.data.content - break - default: - break - } - }) - - const lessThanThirtyMinsAgo = (timestamp) => { - const THIRTYMINS = 1000 * 60 * 30 - const thirtyMinsAgo = Date.now() - THIRTYMINS - return timestamp > thirtyMinsAgo - } - - const filterOffersUsingTradePresence = (offeringTrade) => { - return offeringTrade.tradePresenceExpiry > Date.now(); - } - - const processOffersWithPresence = () => { - if (offeringTrades === null) return - - async function asyncForEach(array, callback) { - for (let index = 0; index < array.length; index++) { - await callback(array[index], index, array) - } - } - - const startOfferPresenceMapping = async () => { - - if (tradePresenceTxns !== null) { - await asyncForEach(tradePresenceTxns, async (tradePresence) => { - let offerIndex = offeringTrades.findIndex((offeringTrade) => offeringTrade.qortalCreatorTradeAddress === tradePresence.tradeAddress) - offerIndex !== -1 ? (offeringTrades[offerIndex].tradePresenceExpiry = tradePresence.timestamp) : null - }) - } - - let filteredOffers = offeringTrades.filter((offeringTrade) => filterOffersUsingTradePresence(offeringTrade)) - self.postMessage({ type: 'PRESENCE', data: { offers: offeringTrades, filteredOffers: filteredOffers, relatedCoin: _relatedCoin } }) - } - - startOfferPresenceMapping() - } - - const initTradeOffersWebSocket = (restarted = false) => { - let tradeOffersSocketCounter = 0 - let socketTimeout - let socketLink = `ws://NODEURL/websockets/crosschain/tradeoffers?foreignBlockchain=FOREIGN_BLOCKCHAIN&includeHistoric=true` - const socket = new WebSocket(socketLink) - socket.onopen = () => { - setTimeout(pingSocket, 50) - tradeOffersSocketCounter += 1 - } - socket.onmessage = (e) => { - e.relatedCoin = _relatedCoin - self.postMessage({ - type: 'TRADE_OFFERS', - data: e.data, - counter: tradeOffersSocketCounter, - isRestarted: restarted, - }) - tradeOffersSocketCounter += 1 - restarted = false - } - socket.onclose = () => { - clearTimeout(socketTimeout) - restartTradeOffersWebSocket() - } - socket.onerror = (e) => { - clearTimeout(socketTimeout) - } - const pingSocket = () => { - socket.send('ping') - socketTimeout = setTimeout(pingSocket, 295000) - } - } - - const initTradeBotWebSocket = (restarted = false) => { - let socketTimeout - let socketLink = `ws://NODEURL/websockets/crosschain/tradebot?foreignBlockchain=FOREIGN_BLOCKCHAIN` - const socket = new WebSocket(socketLink) - socket.onopen = () => { - setTimeout(pingSocket, 50) - } - socket.onmessage = (e) => { - e.relatedCoin = _relatedCoin - self.postMessage({ - type: 'TRADE_BOT', - data: e.data, - isRestarted: restarted, - }) - restarted = false - } - socket.onclose = () => { - clearTimeout(socketTimeout) - restartTradeBotWebSocket() - } - socket.onerror = (e) => { - clearTimeout(socketTimeout) - } - const pingSocket = () => { - socket.send('ping') - socketTimeout = setTimeout(pingSocket, 295000) - } - } - - const initTradePresenceWebSocket = (restarted = false) => { - let socketTimeout - let socketLink = `ws://NODEURL/websockets/crosschain/tradepresence` - const socket = new WebSocket(socketLink) - socket.onopen = () => { - setTimeout(pingSocket, 50) - } - socket.onmessage = (e) => { - tradePresenceTxns = JSON.parse(e.data) - processOffersWithPresence() - restarted = false - } - socket.onclose = () => { - clearTimeout(socketTimeout) - restartTradePresenceWebSocket() - } - socket.onerror = (e) => { - clearTimeout(socketTimeout) - } - const pingSocket = () => { - socket.send('ping') - socketTimeout = setTimeout(pingSocket, 295000) - } - } - - const restartTradePresenceWebSocket = () => { - setTimeout(() => initTradePresenceWebSocket(true), 50) - } - - const restartTradeOffersWebSocket = () => { - setTimeout(() => initTradeOffersWebSocket(true), 50) - } - - const restartTradeBotWebSocket = () => { - setTimeout(() => initTradeBotWebSocket(true), 50) - } - - initTradeOffersWebSocket() - initTradePresenceWebSocket() - initTradeBotWebSocket() - } - - updateAccountBalance() { - clearTimeout(this.updateAccountBalanceTimeout) - parentEpml.request('apiCall', { - url: `/addresses/balance/${this.selectedAddress.address}?apiKey=${this.getApiKey()}`, - }) - .then((res) => { - this.listedCoins.get("QORTAL").balance = res - this.updateAccountBalanceTimeout = setTimeout(() => this.updateAccountBalance(), 10000) - }) - } - - _checkBuyAmount(e) { - const targetAmount = e.target.value - const target = e.target - - if (targetAmount.length === 0) { - this.isValidAmount = false - this.sellBtnDisable = true - e.target.blur() - e.target.focus() - e.target.invalid = true - } else { - this.buyBtnDisable = false - } - - e.target.blur() - e.target.focus() - - e.target.validityTransform = (newValue, nativeValidity) => { - if (newValue.includes('-') === true) { - this.buyBtnDisable = true - return { - valid: false, - } - } else if (!nativeValidity.valid) { - if (newValue.includes('.') === true) { - let myAmount = newValue.split('.') - if (myAmount[1].length > 8) { - this.buyBtnDisable = true - } else { - this.buyBtnDisable = false - return { - valid: true, - } - } - } - } else { - this.buyBtnDisable = false - } - } - } - - checkTradeBotAmount(e) { - const targetAmount = e.target.value - const target = e.target - this.autoBuyWarning = false - - if (targetAmount.length === 0) { - this.isValidAmount = false - this.autoBuyBtnDisable = true - this.autoBuyWarning = false - e.target.blur() - e.target.focus() - e.target.invalid = true - } else { - const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value - const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value - const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value - const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myFunds) > Number(checkFunds)) { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = false - this.autoBuyWarning = false - } else { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = true - this.autoBuyWarning = true - } - } - - e.target.blur() - e.target.focus() - - e.target.validityTransform = (newValue, nativeValidity) => { - if (newValue.includes('-') === true) { - this.autoBuyBtnDisable = true - this.autoBuyWarning = false - return { - valid: false, - } - } else if (!nativeValidity.valid) { - if (newValue.includes('.') === true) { - let myAmount = newValue.split('.') - if (myAmount[1].length > 8) { - this.autoBuyBtnDisable = true - this.autoBuyWarning = false - } else { - const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value - const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value - const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value - const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myFunds) > Number(checkFunds)) { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = false - this.autoBuyWarning = false - } else { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = true - this.autoBuyWarning = true - } - return { - valid: true, - } - } - } - } else { - const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value - const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value - const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value - const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myFunds) > Number(checkFunds)) { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = false - this.autoBuyWarning = false - } else { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = true - this.autoBuyWarning = true - } - } - } - } - - checkTradeBotTotalAmount(e) { - const targetAmount = e.target.value - const target = e.target - this.autoBuyWarning = false - - if (targetAmount.length === 0) { - this.isValidAmount = false - this.autoBuyBtnDisable = true - this.autoBuyWarning = false - e.target.blur() - e.target.focus() - e.target.invalid = true - } else { - const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value - const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value - const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value - const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myFunds) > Number(checkFunds)) { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = false - this.autoBuyWarning = false - } else { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = true - this.autoBuyWarning = true - } - } - - e.target.blur() - e.target.focus() - - e.target.validityTransform = (newValue, nativeValidity) => { - if (newValue.includes('-') === true) { - this.autoBuyBtnDisable = true - this.autoBuyWarning = false - return { - valid: false, - } - } else if (!nativeValidity.valid) { - if (newValue.includes('.') === true) { - let myAmount = newValue.split('.') - if (myAmount[1].length > 8) { - this.autoBuyBtnDisable = true - this.autoBuyWarning = false - } else { - const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value - const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value - const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value - const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myFunds) > Number(checkFunds)) { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = false - this.autoBuyWarning = false - } else { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = true - this.autoBuyWarning = true - } - return { - valid: true, - } - } - } - } else { - const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value - const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value - const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value - const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myFunds) > Number(checkFunds)) { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = false - this.autoBuyWarning = false - } else { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = true - this.autoBuyWarning = true - } - } - } - } - - async tradeFee() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/transactions/unitfee?txType=DEPLOY_AT` - await fetch(url).then((response) => { - if (response.ok) { - return response.json() - } - return Promise.reject(response) - }).then((json) => { - this.listedCoins.get("QORTAL").tradeFee = (Number(json) + 100000) / 1e8 - }) - } - - getApiKey() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const newRvnTradebookItem = { + botRvnQortAmount: addRvnQortAmount, + botRvnPrice: addRvnPrice + } + + oldRvnTradebook.push(newRvnTradebookItem) + + localStorage.setItem(this.rvnWallet, JSON.stringify(oldRvnTradebook)) + + let rvntradebookstring = get("tradepage.tchange44") + parentEpml.request('showSnackBar', `${rvntradebookstring}`) + + this.closeRVNTradebookDialog() + this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") + } + + closeRVNTradebookDialog() { + this.shadowRoot.querySelector('#tradeBotRVNAddDialog').close() + this.clearTradeBotForm() + } + + removeRVNTradebook() { + localStorage.removeItem(this.rvnWallet) + localStorage.setItem(this.rvnWallet, "") + this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") + + this.autoBuyBotDisable = false + + let rvnstring = get("tradepage.tchange41") + parentEpml.request('showSnackBar', `${rvnstring}`) + } + + arrrTradebook() { + if (localStorage.getItem(this.arrrWallet) === null) { + localStorage.setItem(this.arrrWallet, "") + } else { + this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") + } + } + + addToARRRTradebook() { + const addBotArrrQortAmount = this.shadowRoot.getElementById('autoBuyARRRQortAmountInput').value + const addBotArrrPrice = this.shadowRoot.getElementById('autoBuyARRRPriceInput').value + const addArrrQortAmount = this.round(parseFloat(addBotArrrQortAmount)) + const addArrrPrice = this.round(parseFloat(addBotArrrPrice)) + + var oldArrrTradebook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") + + const newArrrTradebookItem = { + botArrrQortAmount: addArrrQortAmount, + botArrrPrice: addArrrPrice + } + + oldArrrTradebook.push(newArrrTradebookItem) + + localStorage.setItem(this.arrrWallet, JSON.stringify(oldArrrTradebook)) + + let arrrtradebookstring = get("tradepage.tchange44") + parentEpml.request('showSnackBar', `${arrrtradebookstring}`) + + this.closeARRRTradebookDialog() + this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") + } + + closeARRRTradebookDialog() { + this.shadowRoot.querySelector('#tradeBotARRRAddDialog').close() + this.clearTradeBotForm() + } + + removeARRRTradebook() { + localStorage.removeItem(this.arrrWallet) + localStorage.setItem(this.arrrWallet, "") + this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") + + this.autoBuyBotDisable = false + + let arrrstring = get("tradepage.tchange41") + parentEpml.request('showSnackBar', `${arrrstring}`) + } + + async setForeignCoin(coin, beingInitialized) { + let _this = this + this.selectedCoin = coin + + let coinSelectionMenu = this.shadowRoot.getElementById("coinSelectionMenu") + + if (beingInitialized) { + coinSelectionMenu.shadowRoot.querySelector('.mdc-select--outlined .mdc-select__anchor').setAttribute('style', 'padding-left: 60px;') + let pairIconContainer = document.createElement("span") + let pairicon = (_this.listedCoins.get(_this.selectedCoin).coinCode).toLowerCase() + pairIconContainer.setAttribute("class", "pairIconContainer") + pairIconContainer.setAttribute('style', 'left: 10px;top: 50%;transform: translate(0, -50%);height: 26px;width: 45px;position: absolute;background-repeat: no-repeat;background-size: cover;background-image: url(/img/qort' + pairicon + '.png);') + coinSelectionMenu.shadowRoot.querySelector('.mdc-select--outlined .mdc-select__anchor').appendChild(pairIconContainer) + } else { + let pairIconContainer = coinSelectionMenu.shadowRoot.querySelector(".mdc-select--outlined .mdc-select__anchor span.pairIconContainer") + let pairicon = (_this.listedCoins.get(_this.selectedCoin).coinCode).toLowerCase() + pairIconContainer.style.backgroundImage = 'url(/img/qort' + pairicon + '.png)' + } + + this.isLoadingOpenTrades = true + this.createConnection() + this._openOrdersGrid.querySelector('#priceColumn').headerRenderer = function (root) { + const priceString2 = get("tradepage.tchange9") + root.innerHTML = '' + priceString2 + ' (' + _this.listedCoins.get(_this.selectedCoin).coinCode + ')' + } + this.clearTradeBotForm() + clearTimeout(this.updateDoneTradesTimeout) + await this.getDoneTrades() + this.updateDoneTradesTimeout = setTimeout(() => this.getDoneTrades(), 180000) + await this.updateWalletBalance() + await this.fetchWalletAddress(coin) + + } + + async reRenderOpenFilteredOrders() { + this.requestUpdate() + await this.updateComplete + this.isLoadingOpenTrades = false + } + + async reRenderMyOpenOrders() { + this.requestUpdate() + await this.updateComplete + this.isLoadingMyOpenOrders = false + } + + addAutoBuyAction() { + this.autoBuyWarning = false + this.clearTradeBotForm() + this.shadowRoot.querySelector('#tradeBot' + this.listedCoins.get(this.selectedCoin).coinCode + 'AddDialog').show() + } + + checkTradeBotValues() { + const checkTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value + const checkTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value + const checkTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value + const checkAmount = this.round(parseFloat(checkTradeBotAmountInput)) + const checkPrice = this.round(parseFloat(checkTradeBotPriceInput)) + const checkTotal = this.round(parseFloat(checkTradeBotTotalInput)) + + if (Number(checkAmount) === 0) { + let amountString = get("tradepage.tchange34") + parentEpml.request('showSnackBar', `${amountString}`) + } else if (Number(checkPrice) === 0) { + let priceString = get("tradepage.tchange35") + parentEpml.request('showSnackBar', `${priceString}`) + } else if (Number(checkTotal) === 0) { + let totalString = get("tradepage.tchange35") + parentEpml.request('showSnackBar', `${totalString}`) + } else { + this.showAddToAutoBuyStore() + } + } + + showAddToAutoBuyStore() { + switch (this.listedCoins.get(this.selectedCoin).coinCode) { + case "BTC": + this.addToBTCTradebook() + break + case "LTC": + this.addToLTCTradebook() + break + case "DOGE": + this.addToDOGETradebook() + break + case "DGB": + this.addToDGBTradebook() + break + case "RVN": + this.addToRVNTradebook() + break + case "ARRR": + this.addToARRRTradebook() + break + default: + break + } + } + + processOfferingTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + const offerItem = { + ...offer, + qortAmount: parseFloat(offer.qortAmount), + price: parseFloat(offer.foreignAmount) / parseFloat(offer.qortAmount), + } + const addOffer = () => { + this.listedCoins.get(offer.foreignBlockchain).openOrders.unshift(offerItem) + } + const initOffer = () => { + this.listedCoins.get(offer.foreignBlockchain).openOrders.push(offerItem) + } + this.listedCoins.get(offer.foreignBlockchain).openOrders.length === 0 ? initOffer() : addOffer() + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null + } + } catch (e) { + console.log("Error adding offer from " + offer.foreignBlockchain) + } + } + + processRedeemedTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + + if (offer.qortalCreator === this.selectedAddress.address) { + if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + const offerItem = { + ...offer, + mode: 'SOLD', + } + this._myHistoricTradesGrid.items.unshift(offerItem) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null + } else if (offer.partnerQortalReceivingAddress === this.selectedAddress.address) { + if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + const offerItem = { + ...offer, + mode: 'BOUGHT', + } + this._myHistoricTradesGrid.items.unshift(offerItem) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null + } + const addNewHistoricTrade = () => { + this._historicTradesGrid.items.unshift(offer) + this._historicTradesGrid.clearCache() + } + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? addNewHistoricTrade() : null + + } + } catch (e) { + console.log("Error processing redeemed trade offer from " + offer.foreignBlockchain) + } + } + + processTradingTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + + if (offer.qortalCreator === this.selectedAddress.address && this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + this._openOrdersGrid.items.forEach((item, index) => { + if (item.qortalAtAddress === offer.qortalAtAddress) { + this._openOrdersGrid.items.splice(index, 1) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null + } + }) + this.listedCoins.get(offer.foreignBlockchain).openOrders = this.listedCoins.get(offer.foreignBlockchain).openOrders.filter((order) => order.qortalAtAddress !== offer.qortalAtAddress) + } + } catch (e) { + console.log("Error processing trading trade offer from " + offer.foreignBlockchain) + } + } + + processRefundedTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + + if (offer.qortalCreator === this.selectedAddress.address) { + if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + this._myHistoricTradesGrid.items.unshift(offer) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null + } + + } + } catch (e) { + console.log("Error processing refunded trade offer from " + offer.foreignBlockchain) + } + } + + processCancelledTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + + if (offer.qortalCreator === this.selectedAddress.address) { + if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + this._myHistoricTradesGrid.items.unshift(offer) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null + } + this._openOrdersGrid.items.forEach((item, index) => { + if (item.qortalAtAddress === offer.qortalAtAddress) { + this._openOrdersGrid.items.splice(index, 1) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null + } + }) + this.listedCoins.get(offer.foreignBlockchain).openOrders = this.listedCoins.get(offer.foreignBlockchain).openOrders.filter((order) => order.qortalAtAddress !== offer.qortalAtAddress) + this._stuckOrdersGrid.items.forEach((item, index) => { + if (item.qortalAtAddress === offer.qortalAtAddress) { + this._stuckOrdersGrid.items.splice(index, 1) + this._stuckOrdersGrid.clearCache() + } + }) + } + } catch (e) { + console.log("Error processing cancelled trade offer from " + offer.foreignBlockchain) + } + } + + processTradeOffers(offers) { + offers.forEach((offer) => { + if (offer.mode === 'OFFERING') { + this.processOfferingTrade(offer) + } + }) + } + + processTradeBotStates(tradeStates) { + + const BitcoinACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + const LitecoinACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + const DogecoinACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + const DigibyteACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + const RavencoinACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + const PirateChainACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + switch (this.selectedCoin) { + case 'BITCOIN': + BitcoinACCTv1(tradeStates) + break + case 'LITECOIN': + LitecoinACCTv1(tradeStates) + break + case 'DOGECOIN': + DogecoinACCTv1(tradeStates) + break + case 'DIGIBYTE': + DigibyteACCTv1(tradeStates) + break + case 'RAVENCOIN': + RavencoinACCTv1(tradeStates) + break + case 'PIRATECHAIN': + PirateChainACCTv1(tradeStates) + break + default: + break + } + } + + changeTradeBotState(state, tradeState) { + this.isLoadingMyOpenOrders = true + const stateItem = { + ...state, + _tradeState: tradeState, + } + const item = this._myOrdersGrid.querySelector(`#${state.atAddress}`) + const addStateItem = () => { + this.reRenderMyOpenOrders() + this._myOrdersGrid.items.unshift(stateItem) + this._myOrdersGrid.clearCache() + } + const updateStateItem = () => { + this._myOrdersGrid.items.forEach((item, index) => { + if (item.atAddress === state.atAddress) { + this.reRenderMyOpenOrders() + this._myOrdersGrid.items.splice(index, 1) + this._myOrdersGrid.items.unshift(stateItem) + this._myOrdersGrid.clearCache() + } + }) + } + item ? updateStateItem() : addStateItem() + } + + handleCompletedState(state) { + this._myOrdersGrid.items.forEach((item, index) => { + if (item.atAddress === state.atAddress) { + this.reRenderMyOpenOrders() + this._myOrdersGrid.items.splice(index, 1) + this._myOrdersGrid.clearCache() + } + }) + } + + initSocket() { + let _relatedCoin = "" + let tradePresenceTxns = null + let offeringTrades = null + + self.addEventListener('message', function (event) { + switch (event.data.type) { + case 'open_orders': + offeringTrades = event.data.content + processOffersWithPresence() + break + case 'set_coin': + _relatedCoin = event.data.content + break + default: + break + } + }) + + const lessThanThirtyMinsAgo = (timestamp) => { + const THIRTYMINS = 1000 * 60 * 30 + const thirtyMinsAgo = Date.now() - THIRTYMINS + return timestamp > thirtyMinsAgo + } + + const filterOffersUsingTradePresence = (offeringTrade) => { + return offeringTrade.tradePresenceExpiry > Date.now(); + } + + const processOffersWithPresence = () => { + if (offeringTrades === null) return + + async function asyncForEach(array, callback) { + for (let index = 0; index < array.length; index++) { + await callback(array[index], index, array) + } + } + + const startOfferPresenceMapping = async () => { + + if (tradePresenceTxns !== null) { + await asyncForEach(tradePresenceTxns, async (tradePresence) => { + let offerIndex = offeringTrades.findIndex((offeringTrade) => offeringTrade.qortalCreatorTradeAddress === tradePresence.tradeAddress) + offerIndex !== -1 ? (offeringTrades[offerIndex].tradePresenceExpiry = tradePresence.timestamp) : null + }) + } + + let filteredOffers = offeringTrades.filter((offeringTrade) => filterOffersUsingTradePresence(offeringTrade)) + self.postMessage({ type: 'PRESENCE', data: { offers: offeringTrades, filteredOffers: filteredOffers, relatedCoin: _relatedCoin } }) + } + + startOfferPresenceMapping() + } + + const initTradeOffersWebSocket = (restarted = false) => { + let tradeOffersSocketCounter = 0 + let socketTimeout + let socketLink = `ws://NODEURL/websockets/crosschain/tradeoffers?foreignBlockchain=FOREIGN_BLOCKCHAIN&includeHistoric=true` + const socket = new WebSocket(socketLink) + socket.onopen = () => { + setTimeout(pingSocket, 50) + tradeOffersSocketCounter += 1 + } + socket.onmessage = (e) => { + e.relatedCoin = _relatedCoin + self.postMessage({ + type: 'TRADE_OFFERS', + data: e.data, + counter: tradeOffersSocketCounter, + isRestarted: restarted, + }) + tradeOffersSocketCounter += 1 + restarted = false + } + socket.onclose = () => { + clearTimeout(socketTimeout) + restartTradeOffersWebSocket() + } + socket.onerror = (e) => { + clearTimeout(socketTimeout) + } + const pingSocket = () => { + socket.send('ping') + socketTimeout = setTimeout(pingSocket, 295000) + } + } + + const initTradeBotWebSocket = (restarted = false) => { + let socketTimeout + let socketLink = `ws://NODEURL/websockets/crosschain/tradebot?foreignBlockchain=FOREIGN_BLOCKCHAIN` + const socket = new WebSocket(socketLink) + socket.onopen = () => { + setTimeout(pingSocket, 50) + } + socket.onmessage = (e) => { + e.relatedCoin = _relatedCoin + self.postMessage({ + type: 'TRADE_BOT', + data: e.data, + isRestarted: restarted, + }) + restarted = false + } + socket.onclose = () => { + clearTimeout(socketTimeout) + restartTradeBotWebSocket() + } + socket.onerror = (e) => { + clearTimeout(socketTimeout) + } + const pingSocket = () => { + socket.send('ping') + socketTimeout = setTimeout(pingSocket, 295000) + } + } + + const initTradePresenceWebSocket = (restarted = false) => { + let socketTimeout + let socketLink = `ws://NODEURL/websockets/crosschain/tradepresence` + const socket = new WebSocket(socketLink) + socket.onopen = () => { + setTimeout(pingSocket, 50) + } + socket.onmessage = (e) => { + tradePresenceTxns = JSON.parse(e.data) + processOffersWithPresence() + restarted = false + } + socket.onclose = () => { + clearTimeout(socketTimeout) + restartTradePresenceWebSocket() + } + socket.onerror = (e) => { + clearTimeout(socketTimeout) + } + const pingSocket = () => { + socket.send('ping') + socketTimeout = setTimeout(pingSocket, 295000) + } + } + + const restartTradePresenceWebSocket = () => { + setTimeout(() => initTradePresenceWebSocket(true), 50) + } + + const restartTradeOffersWebSocket = () => { + setTimeout(() => initTradeOffersWebSocket(true), 50) + } + + const restartTradeBotWebSocket = () => { + setTimeout(() => initTradeBotWebSocket(true), 50) + } + + initTradeOffersWebSocket() + initTradePresenceWebSocket() + initTradeBotWebSocket() + } + + updateAccountBalance() { + clearTimeout(this.updateAccountBalanceTimeout) + parentEpml.request('apiCall', { + url: `/addresses/balance/${this.selectedAddress.address}?apiKey=${this.getApiKey()}`, + }) + .then((res) => { + this.listedCoins.get("QORTAL").balance = res + this.updateAccountBalanceTimeout = setTimeout(() => this.updateAccountBalance(), 10000) + }) + } + + _checkBuyAmount(e) { + const targetAmount = e.target.value + const target = e.target + + if (targetAmount.length === 0) { + this.isValidAmount = false + this.sellBtnDisable = true + e.target.blur() + e.target.focus() + e.target.invalid = true + } else { + this.buyBtnDisable = false + } + + e.target.blur() + e.target.focus() + + e.target.validityTransform = (newValue, nativeValidity) => { + if (newValue.includes('-') === true) { + this.buyBtnDisable = true + return { + valid: false, + } + } else if (!nativeValidity.valid) { + if (newValue.includes('.') === true) { + let myAmount = newValue.split('.') + if (myAmount[1].length > 8) { + this.buyBtnDisable = true + } else { + this.buyBtnDisable = false + return { + valid: true, + } + } + } + } else { + this.buyBtnDisable = false + } + } + } + + checkTradeBotAmount(e) { + const targetAmount = e.target.value + const target = e.target + this.autoBuyWarning = false + + if (targetAmount.length === 0) { + this.isValidAmount = false + this.autoBuyBtnDisable = true + this.autoBuyWarning = false + e.target.blur() + e.target.focus() + e.target.invalid = true + } else { + const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value + const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value + const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value + const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myFunds) > Number(checkFunds)) { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = false + this.autoBuyWarning = false + } else { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = true + this.autoBuyWarning = true + } + } + + e.target.blur() + e.target.focus() + + e.target.validityTransform = (newValue, nativeValidity) => { + if (newValue.includes('-') === true) { + this.autoBuyBtnDisable = true + this.autoBuyWarning = false + return { + valid: false, + } + } else if (!nativeValidity.valid) { + if (newValue.includes('.') === true) { + let myAmount = newValue.split('.') + if (myAmount[1].length > 8) { + this.autoBuyBtnDisable = true + this.autoBuyWarning = false + } else { + const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value + const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value + const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value + const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myFunds) > Number(checkFunds)) { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = false + this.autoBuyWarning = false + } else { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = true + this.autoBuyWarning = true + } + return { + valid: true, + } + } + } + } else { + const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value + const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value + const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value + const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myFunds) > Number(checkFunds)) { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = false + this.autoBuyWarning = false + } else { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = true + this.autoBuyWarning = true + } + } + } + } + + checkTradeBotTotalAmount(e) { + const targetAmount = e.target.value + const target = e.target + this.autoBuyWarning = false + + if (targetAmount.length === 0) { + this.isValidAmount = false + this.autoBuyBtnDisable = true + this.autoBuyWarning = false + e.target.blur() + e.target.focus() + e.target.invalid = true + } else { + const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value + const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value + const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value + const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myFunds) > Number(checkFunds)) { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = false + this.autoBuyWarning = false + } else { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = true + this.autoBuyWarning = true + } + } + + e.target.blur() + e.target.focus() + + e.target.validityTransform = (newValue, nativeValidity) => { + if (newValue.includes('-') === true) { + this.autoBuyBtnDisable = true + this.autoBuyWarning = false + return { + valid: false, + } + } else if (!nativeValidity.valid) { + if (newValue.includes('.') === true) { + let myAmount = newValue.split('.') + if (myAmount[1].length > 8) { + this.autoBuyBtnDisable = true + this.autoBuyWarning = false + } else { + const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value + const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value + const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value + const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myFunds) > Number(checkFunds)) { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = false + this.autoBuyWarning = false + } else { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = true + this.autoBuyWarning = true + } + return { + valid: true, + } + } + } + } else { + const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value + const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value + const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value + const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myFunds) > Number(checkFunds)) { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = false + this.autoBuyWarning = false + } else { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = true + this.autoBuyWarning = true + } + } + } + } + + async tradeFee() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/transactions/unitfee?txType=DEPLOY_AT` + await fetch(url).then((response) => { + if (response.ok) { + return response.json() + } + return Promise.reject(response) + }).then((json) => { + this.listedCoins.get("QORTAL").tradeFee = (Number(json) + 100000) / 1e8 + }) + } + + clearTradeBotForm() { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.initialAmount + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value = this.initialAmount + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.initialAmount + this.autoBuyBtnDisable = true + } + + inlineWorker(passedFunction, modifiers) { + let parsedFunction = `` + + modifiers.forEach((modifier) => { + let regex = new RegExp(modifier.searchValue, 'g') + parsedFunction = parsedFunction.length === 0 ? `(function ${passedFunction.toString().trim().replace(regex, modifier.replaceValue)})()` : parsedFunction.toString().trim().replace(regex, modifier.replaceValue) + }) + + const workerUrl = URL.createObjectURL(new Blob([parsedFunction], { type: 'text/javascript' })) + const worker = new Worker(workerUrl) + URL.revokeObjectURL(workerUrl) + return worker + } + + clearPaneCache() { + this._openOrdersGrid.clearCache() + this._myOrdersGrid.clearCache() + } + + createConnection() { + if (workers.get(this.selectedCoin).tradesConnectedWorker !== null) { + this.isLoadingHistoricTrades = false + this.isLoadingOpenTrades = false + return + } + + const handleMessage = (message) => { + switch (message.type) { + case 'TRADE_OFFERS': + if (!message.isRestarted) { + this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter = message.counter + this.processTradeOffers(JSON.parse(message.data)) + this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter === 1 ? this.clearPaneCache() : null + workers.get(this.selectedCoin).tradesConnectedWorker.postMessage(this.listedCoins.get(this.selectedCoin).openOrders) + workers.get(this.selectedCoin).tradesConnectedWorker.postMessage({ type: "open_orders", content: this.listedCoins.get(this.selectedCoin).openOrders }) + } + return null + case 'TRADE_BOT': + if (!message.isRestarted) this.processTradeBotStates(JSON.parse(message.data)) + return null + case 'PRESENCE': + this.tradesPresenceCleaned = [] + this.listedCoins.get(message.data.relatedCoin).openOrders = message.data.offers + this.tradesPresenceCleaned = message.data.filteredOffers + + const filterPresenceList = () => { + this.blockedTradesList.forEach(item => { + const toDelete = item.recipient + this.tradesPresenceCleaned = this.tradesPresenceCleaned.filter(el => { + return el.qortalCreatorTradeAddress !== toDelete + }) + }) + } + + filterPresenceList() + this.listedCoins.get(message.data.relatedCoin).openFilteredOrders = this.tradesPresenceCleaned + this.reRenderOpenFilteredOrders() + return null + default: + break + } + } + + let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + let nodeUrl = myNode.domain + ':' + myNode.port + + const modifiers = [ + { searchValue: 'NODEURL', replaceValue: nodeUrl }, + { searchValue: 'FOREIGN_BLOCKCHAIN', replaceValue: this.selectedCoin }, + ] + + workers.get(this.selectedCoin).tradesConnectedWorker = this.inlineWorker(this.initSocket, modifiers) + + workers.get(this.selectedCoin).tradesConnectedWorker.addEventListener('message', function (event) { handleMessage(event.data) }, { passive: true }) + + workers.get(this.selectedCoin).tradesConnectedWorker.postMessage({ type: "set_coin", content: this.selectedCoin }) + } + + async getNewBlockedTrades() { + const unconfirmedTransactionsList = async () => { + const myNodeInf = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const myNodeUrl = myNodeInf.protocol + '://' + myNodeInf.domain + ':' + myNodeInf.port + const unconfirmedTransactionslUrl = `${myNodeUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` + + var addBlockedTrades = JSON.parse(localStorage.getItem('failedTrades') || '[]') + + await fetch(unconfirmedTransactionslUrl).then(response => { + return response.json() + }).then(data => { + data.map(item => { + const unconfirmedNessageTimeDiff = Date.now() - item.timestamp + const timeOneHour = 60 * 60 * 1000 + if (Number(unconfirmedNessageTimeDiff) > Number(timeOneHour)) { + const addBlocked = { + timestamp: item.timestamp, + recipient: item.recipient + } + addBlockedTrades.push(addBlocked) + } + }) + localStorage.setItem("failedTrades", JSON.stringify(addBlockedTrades)) + this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + }) + } + + await unconfirmedTransactionsList() + + const filterUnconfirmedTransactionsList = async () => { + let cleanBlockedTrades = this.blockedTradesList.reduce((newArray, cut) => { + if (!newArray.some(obj => obj.recipient === cut.recipient)) { + newArray.push(cut) + } + return newArray + }, []) + localStorage.setItem("failedTrades", JSON.stringify(cleanBlockedTrades)) + this.blockedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") + } + + await filterUnconfirmedTransactionsList() + } + + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] return myNode.apiKey - } + } - clearTradeBotForm() { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.initialAmount - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value = this.initialAmount - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.initialAmount - this.autoBuyBtnDisable = true - } + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } - isEmptyArray(arr) { - if (!arr) { - return true - } - return arr.length === 0 - } - - round(number) { + round(number) { return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) - } - - inlineWorker(passedFunction, modifiers) { - let parsedFunction = `` - - modifiers.forEach((modifier) => { - let regex = new RegExp(modifier.searchValue, 'g') - parsedFunction = parsedFunction.length === 0 ? `(function ${passedFunction.toString().trim().replace(regex, modifier.replaceValue)})()` : parsedFunction.toString().trim().replace(regex, modifier.replaceValue) - }) - - const workerUrl = URL.createObjectURL(new Blob([parsedFunction], { type: 'text/javascript' })) - const worker = new Worker(workerUrl) - URL.revokeObjectURL(workerUrl) - return worker - } - - clearPaneCache() { - this._openOrdersGrid.clearCache() - this._myOrdersGrid.clearCache() - } - - createConnection() { - if (workers.get(this.selectedCoin).tradesConnectedWorker !== null) { - this.isLoadingHistoricTrades = false - this.isLoadingOpenTrades = false - return - } - - const handleMessage = (message) => { - switch (message.type) { - case 'TRADE_OFFERS': - if (!message.isRestarted) { - this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter = message.counter - this.processTradeOffers(JSON.parse(message.data)) - this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter === 1 ? this.clearPaneCache() : null - workers.get(this.selectedCoin).tradesConnectedWorker.postMessage(this.listedCoins.get(this.selectedCoin).openOrders) - workers.get(this.selectedCoin).tradesConnectedWorker.postMessage({ type: "open_orders", content: this.listedCoins.get(this.selectedCoin).openOrders }) - } - return null - case 'TRADE_BOT': - if (!message.isRestarted) this.processTradeBotStates(JSON.parse(message.data)) - return null - case 'PRESENCE': - this.tradesPresenceCleaned = [] - this.listedCoins.get(message.data.relatedCoin).openOrders = message.data.offers - this.tradesPresenceCleaned = message.data.filteredOffers - - const filterPresenceList = () => { - this.blockedTradesList.forEach(item => { - const toDelete = item.recipient - this.tradesPresenceCleaned = this.tradesPresenceCleaned.filter(el => { - return el.qortalCreatorTradeAddress !== toDelete - }) - }) - } - - filterPresenceList() - this.listedCoins.get(message.data.relatedCoin).openFilteredOrders = this.tradesPresenceCleaned - this.reRenderOpenFilteredOrders() - return null - default: - break - } - } - - let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - let nodeUrl = myNode.domain + ':' + myNode.port - - const modifiers = [ - { searchValue: 'NODEURL', replaceValue: nodeUrl }, - { searchValue: 'FOREIGN_BLOCKCHAIN', replaceValue: this.selectedCoin }, - ] - - workers.get(this.selectedCoin).tradesConnectedWorker = this.inlineWorker(this.initSocket, modifiers) - - workers.get(this.selectedCoin).tradesConnectedWorker.addEventListener('message', function (event) { handleMessage(event.data) }, { passive: true }) - - workers.get(this.selectedCoin).tradesConnectedWorker.postMessage({ type: "set_coin", content: this.selectedCoin }) - } - - async getNewBlockedTrades() { - const unconfirmedTransactionsList = async () => { - const myNodeInf = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const myNodeUrl = myNodeInf.protocol + '://' + myNodeInf.domain + ':' + myNodeInf.port - const unconfirmedTransactionslUrl = `${myNodeUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` - - var addBlockedTrades = JSON.parse(localStorage.getItem('failedTrades') || '[]') - - await fetch(unconfirmedTransactionslUrl).then(response => { - return response.json() - }).then(data => { - data.map(item => { - const unconfirmedNessageTimeDiff = Date.now() - item.timestamp - const timeOneHour = 60 * 60 * 1000 - if (Number(unconfirmedNessageTimeDiff) > Number(timeOneHour)) { - const addBlocked = { - timestamp: item.timestamp, - recipient: item.recipient - } - addBlockedTrades.push(addBlocked) - } - }) - localStorage.setItem("failedTrades", JSON.stringify(addBlockedTrades)) - this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') - }) - } - - await unconfirmedTransactionsList() - - const filterUnconfirmedTransactionsList = async () => { - let cleanBlockedTrades = this.blockedTradesList.reduce((newArray, cut) => { - if(!newArray.some(obj => obj.recipient === cut.recipient)) { - newArray.push(cut) - } - return newArray - },[]) - localStorage.setItem("failedTrades", JSON.stringify(cleanBlockedTrades)) - this.blockedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } - - await filterUnconfirmedTransactionsList() - } + } } -window.customElements.define('trade-bot-portal', TradeBotPortal) +window.customElements.define('trade-bot-portal', TradeBotPortal) \ No newline at end of file diff --git a/plugins/plugins/core/trade-portal/charts/arrr-charts.js b/plugins/plugins/core/trade-portal/charts/arrr-charts.js index 68c0e618..20f16fed 100644 --- a/plugins/plugins/core/trade-portal/charts/arrr-charts.js +++ b/plugins/plugins/core/trade-portal/charts/arrr-charts.js @@ -1,7 +1,6 @@ -import {css, html, LitElement} from 'lit' -import {Epml} from '../../../../epml.js' -import {get, registerTranslateConfig, translate, use} from '../../../../../core/translate' -import '@polymer/paper-dialog/paper-dialog.js' +import { html, LitElement } from 'lit' +import { Epml } from '../../../../epml' +import { highChartStyles } from '../../components/plugins-css' import * as Highcharts from 'highcharts' import Exporting from 'highcharts/modules/exporting' import StockChart from 'highcharts/modules/stock' @@ -11,18 +10,21 @@ import 'highcharts/modules/boost.js' import 'highcharts/modules/data.js' import 'highcharts/modules/export-data.js' import 'highcharts/modules/offline-exporting.js' +import '@polymer/paper-dialog/paper-dialog.js' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + Exporting(Highcharts) StockChart(Highcharts) let arrrChartDialog -const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) - class ArrrCharts extends LitElement { static get properties() { return { @@ -33,43 +35,7 @@ class ArrrCharts extends LitElement { } static get styles() { - return css` - .loadingContainer { - height: 100%; - width: 100%; - } - - .trades-chart { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 25px; - padding: 15px; - } - - .chart-container { - margin: auto; - color: var(--black); - text-align: center; - padding: 15px; - height: 30vh; - width: 80vw; - } - - .chart-info-wrapper { - background: transparent; - height: 38vh; - width: 83vw; - overflow: auto; - } - - .chart-loading-wrapper { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - } - ` + return [highChartStyles] } constructor() { @@ -199,6 +165,17 @@ class ArrrCharts extends LitElement { } } + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + round(number) { return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } @@ -208,5 +185,4 @@ window.customElements.define('arrr-charts', ArrrCharts) const chartsarrr = document.createElement('arrr-charts') arrrChartDialog = document.body.appendChild(chartsarrr) - -export default arrrChartDialog +export default arrrChartDialog \ No newline at end of file diff --git a/plugins/plugins/core/trade-portal/charts/btc-charts.js b/plugins/plugins/core/trade-portal/charts/btc-charts.js index 1ec4136c..19f2a121 100644 --- a/plugins/plugins/core/trade-portal/charts/btc-charts.js +++ b/plugins/plugins/core/trade-portal/charts/btc-charts.js @@ -1,7 +1,6 @@ -import {css, html, LitElement} from 'lit' -import {Epml} from '../../../../epml.js' -import {get, registerTranslateConfig, translate, use} from '../../../../../core/translate' -import '@polymer/paper-dialog/paper-dialog.js' +import { html, LitElement } from 'lit' +import { Epml } from '../../../../epml' +import { highChartStyles } from '../../components/plugins-css' import * as Highcharts from 'highcharts' import Exporting from 'highcharts/modules/exporting' import StockChart from 'highcharts/modules/stock' @@ -11,18 +10,21 @@ import 'highcharts/modules/boost.js' import 'highcharts/modules/data.js' import 'highcharts/modules/export-data.js' import 'highcharts/modules/offline-exporting.js' +import '@polymer/paper-dialog/paper-dialog.js' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + Exporting(Highcharts) StockChart(Highcharts) let btcChartDialog -const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) - class BtcCharts extends LitElement { static get properties() { return { @@ -33,43 +35,7 @@ class BtcCharts extends LitElement { } static get styles() { - return css` - .loadingContainer { - height: 100%; - width: 100%; - } - - .trades-chart { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 25px; - padding: 15px; - } - - .chart-container { - margin: auto; - color: var(--black); - text-align: center; - padding: 15px; - height: 30vh; - width: 80vw; - } - - .chart-info-wrapper { - background: transparent; - height: 38vh; - width: 83vw; - overflow: auto; - } - - .chart-loading-wrapper { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - } - ` + return [highChartStyles] } constructor() { @@ -200,6 +166,17 @@ class BtcCharts extends LitElement { } } + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + round(number) { return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } @@ -209,5 +186,4 @@ window.customElements.define('btc-charts', BtcCharts) const chartsbtc = document.createElement('btc-charts') btcChartDialog = document.body.appendChild(chartsbtc) - -export default btcChartDialog +export default btcChartDialog \ No newline at end of file diff --git a/plugins/plugins/core/trade-portal/charts/dgb-charts.js b/plugins/plugins/core/trade-portal/charts/dgb-charts.js index a78b51fe..eac814de 100644 --- a/plugins/plugins/core/trade-portal/charts/dgb-charts.js +++ b/plugins/plugins/core/trade-portal/charts/dgb-charts.js @@ -1,7 +1,6 @@ -import {css, html, LitElement} from 'lit' -import {Epml} from '../../../../epml.js' -import {get, registerTranslateConfig, translate, use} from '../../../../../core/translate' -import '@polymer/paper-dialog/paper-dialog.js' +import { html, LitElement } from 'lit' +import { Epml } from '../../../../epml' +import { highChartStyles } from '../../components/plugins-css' import * as Highcharts from 'highcharts' import Exporting from 'highcharts/modules/exporting' import StockChart from 'highcharts/modules/stock' @@ -11,18 +10,21 @@ import 'highcharts/modules/boost.js' import 'highcharts/modules/data.js' import 'highcharts/modules/export-data.js' import 'highcharts/modules/offline-exporting.js' +import '@polymer/paper-dialog/paper-dialog.js' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + Exporting(Highcharts) StockChart(Highcharts) let dgbChartDialog -const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) - class DgbCharts extends LitElement { static get properties() { return { @@ -33,43 +35,7 @@ class DgbCharts extends LitElement { } static get styles() { - return css` - .loadingContainer { - height: 100%; - width: 100%; - } - - .trades-chart { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 25px; - padding: 15px; - } - - .chart-container { - margin: auto; - color: var(--black); - text-align: center; - padding: 15px; - height: 30vh; - width: 80vw; - } - - .chart-info-wrapper { - background: transparent; - height: 38vh; - width: 83vw; - overflow: auto; - } - - .chart-loading-wrapper { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - } - ` + return [highChartStyles] } constructor() { @@ -199,6 +165,17 @@ class DgbCharts extends LitElement { } } + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + round(number) { return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } @@ -208,5 +185,4 @@ window.customElements.define('dgb-charts', DgbCharts) const chartsdgb = document.createElement('dgb-charts') dgbChartDialog = document.body.appendChild(chartsdgb) - -export default dgbChartDialog +export default dgbChartDialog \ No newline at end of file diff --git a/plugins/plugins/core/trade-portal/charts/doge-charts.js b/plugins/plugins/core/trade-portal/charts/doge-charts.js index 01f1eecb..da008dcd 100644 --- a/plugins/plugins/core/trade-portal/charts/doge-charts.js +++ b/plugins/plugins/core/trade-portal/charts/doge-charts.js @@ -1,7 +1,6 @@ -import {css, html, LitElement} from 'lit' -import {Epml} from '../../../../epml.js' -import {get, registerTranslateConfig, translate, use} from '../../../../../core/translate' -import '@polymer/paper-dialog/paper-dialog.js' +import { html, LitElement } from 'lit' +import { Epml } from '../../../../epml' +import { highChartStyles } from '../../components/plugins-css' import * as Highcharts from 'highcharts' import Exporting from 'highcharts/modules/exporting' import StockChart from 'highcharts/modules/stock' @@ -11,18 +10,21 @@ import 'highcharts/modules/boost.js' import 'highcharts/modules/data.js' import 'highcharts/modules/export-data.js' import 'highcharts/modules/offline-exporting.js' +import '@polymer/paper-dialog/paper-dialog.js' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + Exporting(Highcharts) StockChart(Highcharts) let dogeChartDialog -const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) - class DogeCharts extends LitElement { static get properties() { return { @@ -33,43 +35,7 @@ class DogeCharts extends LitElement { } static get styles() { - return css` - .loadingContainer { - height: 100%; - width: 100%; - } - - .trades-chart { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 25px; - padding: 15px; - } - - .chart-container { - margin: auto; - color: var(--black); - text-align: center; - padding: 15px; - height: 30vh; - width: 80vw; - } - - .chart-info-wrapper { - background: transparent; - height: 38vh; - width: 83vw; - overflow: auto; - } - - .chart-loading-wrapper { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - } - ` + return [highChartStyles] } constructor() { @@ -199,6 +165,17 @@ class DogeCharts extends LitElement { } } + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + round(number) { return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } @@ -208,5 +185,4 @@ window.customElements.define('doge-charts', DogeCharts) const chartsdoge = document.createElement('doge-charts') dogeChartDialog = document.body.appendChild(chartsdoge) - -export default dogeChartDialog +export default dogeChartDialog \ No newline at end of file diff --git a/plugins/plugins/core/trade-portal/charts/ltc-charts.js b/plugins/plugins/core/trade-portal/charts/ltc-charts.js index 6c880abc..23186b62 100644 --- a/plugins/plugins/core/trade-portal/charts/ltc-charts.js +++ b/plugins/plugins/core/trade-portal/charts/ltc-charts.js @@ -1,7 +1,6 @@ -import {css, html, LitElement} from 'lit' -import {Epml} from '../../../../epml.js' -import {get, registerTranslateConfig, translate, use} from '../../../../../core/translate' -import '@polymer/paper-dialog/paper-dialog.js' +import { html, LitElement } from 'lit' +import { Epml } from '../../../../epml' +import { highChartStyles } from '../../components/plugins-css' import * as Highcharts from 'highcharts' import Exporting from 'highcharts/modules/exporting' import StockChart from 'highcharts/modules/stock' @@ -11,18 +10,21 @@ import 'highcharts/modules/boost.js' import 'highcharts/modules/data.js' import 'highcharts/modules/export-data.js' import 'highcharts/modules/offline-exporting.js' +import '@polymer/paper-dialog/paper-dialog.js' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + Exporting(Highcharts) StockChart(Highcharts) let ltcChartDialog -const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) - class LtcCharts extends LitElement { static get properties() { return { @@ -33,43 +35,7 @@ class LtcCharts extends LitElement { } static get styles() { - return css` - .loadingContainer { - height: 100%; - width: 100%; - } - - .trades-chart { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 25px; - padding: 15px; - } - - .chart-container { - margin: auto; - color: var(--black); - text-align: center; - padding: 15px; - height: 30vh; - width: 80vw; - } - - .chart-info-wrapper { - background: transparent; - height: 38vh; - width: 83vw; - overflow: auto; - } - - .chart-loading-wrapper { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - } - ` + return [highChartStyles] } constructor() { @@ -199,6 +165,17 @@ class LtcCharts extends LitElement { } } + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + round(number) { return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } @@ -208,5 +185,4 @@ window.customElements.define('ltc-charts', LtcCharts) const chartsltc = document.createElement('ltc-charts') ltcChartDialog = document.body.appendChild(chartsltc) - -export default ltcChartDialog +export default ltcChartDialog \ No newline at end of file diff --git a/plugins/plugins/core/trade-portal/charts/rvn-charts.js b/plugins/plugins/core/trade-portal/charts/rvn-charts.js index c878aece..d8dd4144 100644 --- a/plugins/plugins/core/trade-portal/charts/rvn-charts.js +++ b/plugins/plugins/core/trade-portal/charts/rvn-charts.js @@ -1,7 +1,6 @@ -import {css, html, LitElement} from 'lit' -import {Epml} from '../../../../epml.js' -import {get, registerTranslateConfig, translate, use} from '../../../../../core/translate' -import '@polymer/paper-dialog/paper-dialog.js' +import { html, LitElement } from 'lit' +import { Epml } from '../../../../epml' +import { highChartStyles } from '../../components/plugins-css' import * as Highcharts from 'highcharts' import Exporting from 'highcharts/modules/exporting' import StockChart from 'highcharts/modules/stock' @@ -11,18 +10,21 @@ import 'highcharts/modules/boost.js' import 'highcharts/modules/data.js' import 'highcharts/modules/export-data.js' import 'highcharts/modules/offline-exporting.js' +import '@polymer/paper-dialog/paper-dialog.js' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + Exporting(Highcharts) StockChart(Highcharts) let rvnChartDialog -const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) - class RvnCharts extends LitElement { static get properties() { return { @@ -33,43 +35,7 @@ class RvnCharts extends LitElement { } static get styles() { - return css` - .loadingContainer { - height: 100%; - width: 100%; - } - - .trades-chart { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 25px; - padding: 15px; - } - - .chart-container { - margin: auto; - color: var(--black); - text-align: center; - padding: 15px; - height: 30vh; - width: 80vw; - } - - .chart-info-wrapper { - background: transparent; - height: 38vh; - width: 83vw; - overflow: auto; - } - - .chart-loading-wrapper { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - } - ` + return [highChartStyles] } constructor() { @@ -199,6 +165,17 @@ class RvnCharts extends LitElement { } } + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + round(number) { return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } @@ -208,5 +185,4 @@ window.customElements.define('rvn-charts', RvnCharts) const chartsrvn = document.createElement('rvn-charts') rvnChartDialog = document.body.appendChild(chartsrvn) - -export default rvnChartDialog +export default rvnChartDialog \ No newline at end of file diff --git a/plugins/plugins/core/trade-portal/trade-portal-css.js b/plugins/plugins/core/trade-portal/trade-portal-css.js deleted file mode 100644 index 31a4f6f8..00000000 --- a/plugins/plugins/core/trade-portal/trade-portal-css.js +++ /dev/null @@ -1,687 +0,0 @@ -import {css} from 'lit' - -export const tradeStyles = css` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --mdc-theme-error: rgb(255, 89, 89); - --mdc-text-field-outlined-idle-border-color: var(--txtfieldborder); - --mdc-text-field-outlined-hover-border-color: var(--txtfieldhoverborder); - --mdc-text-field-label-ink-color: var(--black); - --mdc-text-field-ink-color: var(--black); - --mdc-select-outlined-idle-border-color: var(--txtfieldborder); - --mdc-select-outlined-hover-border-color: var(--txtfieldhoverborder); - --mdc-select-label-ink-color: var(--black); - --mdc-select-ink-color: var(--black); - --mdc-theme-surface: var(--white); - --mdc-dialog-content-ink-color: var(--black); - --mdc-dialog-shape-radius: 25px; - --paper-input-container-focus-color: var(--mdc-theme-primary); - --lumo-primary-text-color: rgb(0, 167, 245); - --lumo-primary-color-50pct: rgba(0, 167, 245, 0.5); - --lumo-primary-color-10pct: rgba(0, 167, 245, 0.1); - --lumo-primary-color: hsl(199, 100%, 48%); - --lumo-base-color: var(--white); - --lumo-body-text-color: var(--black); - --lumo-secondary-text-color: var(--sectxt); - --lumo-contrast-60pct: var(--vdicon); - --_lumo-grid-border-color: var(--border); - --_lumo-grid-secondary-border-color: var(--border2); - } - - .myhover vaadin-grid-cell-content { - cursor: pointer; - } - - .myhover vaadin-grid::part(selected-row) { - color: green; - cursor: pointer; - } - - .myhover vaadin-grid::part(focused-selected-row) { - color: green; - cursor: pointer; - } - - .myhover vaadin-grid::part(cell):hover { - cursor: pointer; - } - - .myhover vaadin-grid::part(row):hover { - color: green; - cursor: pointer; - } - - .myhover vaadin-grid::part(selected-row-cell) { - color: green; - cursor: pointer; - } - - paper-spinner-lite { - height: 30px; - width: 30px; - --paper-spinner-color: var(--mdc-theme-primary); - --paper-spinner-stroke-width: 3px; - } - - mwc-tab-bar { - --mdc-text-transform: none; - --mdc-tab-color-default: var(--black); - --mdc-tab-text-label-color-default: var(--black); - } - - #tabs-1 { - --mdc-tab-height: 42px; - border-left: 1px solid var(--tradeborder); - border-top: 1px solid var(--tradeborder); - border-right: 1px solid var(--tradeborder); - color: var(--black); - } - - #tab-buy[active] { - --mdc-theme-primary: rgba(55, 160, 51, 0.9); - } - - #tabs-1-content { - height: 100%; - padding-bottom: 10px; - } - - #tabs-1-content>div { - height: 100%; - border: 1px solid var(--tradeborder); - } - - #tabs-1-content .card { - border: none; - } - - #tabs-1-content .btn-clear { - --mdc-icon-button-size: 32px; - color: var(--black); - } - - .btn-clear-bot { - --mdc-icon-button-size: 32px; - color: var(--black); - float: right; - } - - .btn-info { - color: #03a9f4; - --mdc-icon-size: 16px; - padding-top: 3px; - } - - #tab-sell[active] { - --mdc-theme-primary: rgb(255, 89, 89); - } - - #trade-portal-page { - background: var(--white); - padding: 12px 24px; - } - - .divCard { - border: 1px solid var(--black); - padding: 1em; - box-shadow: 0 0.3px 1px 0 rgba(0, 0, 0, 0.14), 0 1px 1px -1px rgba(0, 0, 0, 0.12), 0 1px 2px 0 rgba(0, 0, 0, 0.2); - } - - h2 { - margin: 10px 0; - } - - h4 { - margin: 5px 0; - } - - p { - font-size: 14px; - line-height: 21px; - } - - .card-body { - background-color: var(--white); - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; - min-height: 100vh; - margin: 0; - } - - .card-container { - background-color: var(--white); - border-radius: 5px; - color: var(--black); - padding-top: 30px; - position: relative; - width: 350px; - max-width: 100%; - text-align: center; - } - - .card-container .level { - color: #ffffff; - background-color: #03a9f4; - border-radius: 3px; - font-size: 14px; - font-weight: bold; - padding: 3px 7px; - position: absolute; - top: 30px; - left: 30px; - } - - .card-container .founder { - color: #ffffff; - background-color: #03a9f4; - border-radius: 3px; - font-size: 14px; - font-weight: bold; - padding: 3px 7px; - position: absolute; - top: 30px; - right: 30px; - } - - .card-container .round { - width: 96px; - height: 96px; - border: 1px solid #03a9f4; - border-radius: 50%; - padding: 2px; - } - - .card-container .badge { - width: 200px; - height: 135px; - border: 1px solid transparent; - border-radius: 10%; - padding: 2px; - } - - .userdata { - background-color: #1F1A36; - text-align: left; - padding: 15px; - margin-top: 30px; - } - - .userdata ul { - list-style-type: none; - margin: 0; - padding: 0; - } - - .userdata ul li { - border: 1px solid #2D2747; - border-radius: 2px; - display: inline-block; - font-size: 12px; - margin: 0 7px 7px 0; - padding: 7px; - } - - h2, - h3, - h4, - h5 { - color: var(--black); - font-weight: 400; - } - - header { - display: flex; - flex: 0 1 auto; - align-items: center; - justify-content: center; - padding: 0px 10px; - font-size: 16px; - color: var(--white); - background-color: var(--tradehead); - border-left: 1px solid var(--tradeborder); - border-top: 1px solid var(--tradeborder); - border-right: 1px solid var(--tradeborder); - min-height: 40px; - } - - p { - margin-bottom: 12px; - } - - #trade-portal { - max-width: 100vw; - margin-left: auto; - margin-right: auto; - } - - .box { - margin: 0; - padding: 0; - display: flex; - flex-flow: column; - height: 100%; - } - - .box-bot { - margin: 0; - padding: 0; - display: flex; - flex-flow: column; - height: 150px; - } - - #first-trade-section { - margin-bottom: 10px; - } - - #first-trade-section>div {} - - #second-trade-section { - margin-bottom: 10px; - } - - #second-trade-section>div {} - - #third-trade-section { - margin-bottom: 10px; - } - - #third-trade-section>div {} - - .trade-chart { - background-color: var(--white); - border: 2px #ddd solid; - text-align: center; - } - - .open-trades { - text-align: center; - } - - .open-market-container { - text-align: center; - } - - .trade-bot-container { - text-align: center; - } - - .no-last-seen { - background: rgb(255, 89, 89); - padding: 9px 1.3px; - border-radius: 50%; - width: 1rem; - margin: 0 auto; - } - - .card { - padding: 1em; - border: 1px var(--tradeborder) solid; - flex: 1 1 auto; - display: flex; - flex-flow: column; - justify-content: space-evenly; - min-height: inherit; - } - - .card-bot { - padding: 1em; - flex: 1 1 auto; - display: flex; - flex-flow: column; - justify-content: space-evenly; - width: 350px; - min-height: inherit; - } - - .cancel { - --mdc-theme-primary: rgb(255, 89, 89); - } - - .border-wrapper { - border: 1px var(--tradeborder) solid; - overflow: hidden; - } - - .amt-text { - color: var(--tradehave); - font-size: 15px; - margin-top: 5px; - margin-bottom: 12px; - } - - .exchange { - color: var(--black); - font-size: 18px; - font-weight: bold; - margin-top: 5px; - margin-bottom: 10px; - } - - .clear-button { - display: inline; - float: right; - margin-bottom: 5px; - } - - .exhcnage-text { - display: inline; - float: left; - margin-bottom: 5px; - } - - .balance-text { - display: inline; - float: right; - margin-bottom: 5px; - } - - .fee-text { - display: inline; - float: left; - margin-bottom: 5px; - } - - .tab-text { - color: var(--tradehave); - font-size: 12px; - text-align: left; - margin-top: 2px; - margin-bottom: -12px; - } - - .historic-trades { - text-align: center; - } - - .my-open-orders { - text-align: center; - } - - .my-historic-trades { - text-align: center; - } - - .buttons { - width: auto !important; - } - - .buy-button { - --mdc-theme-primary: rgba(55, 160, 51, 0.9); - } - - .sell-button { - --mdc-theme-primary: rgb(255, 89, 89); - } - - .trade-bot-button { - margin-top: 20px; - margin-bottom: 20px; - --mdc-theme-primary: rgba(55, 160, 51, 0.9); - } - - .full-width { - background-color: var(--white); - border: 2px var(--black); - height: 200px; - text-align: center; - } - - vaading-grid { - font-size: .8em; - } - - vaadin-grid-column { - flex-grow: 1; - } - - .loadingContainer { - height: 100%; - width: 100%; - } - - .loading, - .loading:after { - border-radius: 50%; - width: 5em; - height: 5em; - } - - .loading { - margin: 10px auto; - border-width: .6em; - border-style: solid; - border-color: rgba(3, 169, 244, 0.2) rgba(3, 169, 244, 0.2) rgba(3, 169, 244, 0.2) rgb(3, 169, 244); - font-size: 10px; - position: relative; - text-indent: -9999em; - transform: translateZ(0px); - animation: 1.1s linear 0s infinite normal none running loadingAnimation; - } - - mwc-select#coinSelectionMenu { - font-size: 24px; - width: 220px; - } - - mwc-select#coinSelectionMenu mwc-list-item { - line-height: 30px; - } - - .coinName::before { - content: ""; - display: inline-block; - height: 26px; - width: 45px; - position: absolute; - background-repeat: no-repeat; - background-size: cover; - left: 10px; - top: 10px; - } - - .btc.coinName:before { - background-image: url('/img/qortbtc.png'); - } - - .ltc.coinName:before { - background-image: url('/img/qortltc.png'); - } - - .doge.coinName:before { - background-image: url('/img/qortdoge.png'); - } - - .dgb.coinName:before { - background-image: url('/img/qortdgb.png'); - } - - .rvn.coinName:before { - background-image: url('/img/qortrvn.png'); - } - - .arrr.coinName:before { - background-image: url('/img/qortarrr.png'); - } - - .coinName { - display: inline-block; - height: 26px; - padding-left: 45px; - } - - .warning-text { - animation: blinker 1.5s linear infinite; - display: inline; - float: left; - margin-bottom: 5px; - color: rgb(255, 89, 89); - } - - .warning-bot-text { - animation: blinker 1.5s linear infinite; - display: inline; - text-align: center; - color: rgb(255, 89, 89); - } - - .red { - --mdc-theme-primary: #F44336; - } - - @-webkit-keyframes loadingAnimation { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } - } - - @keyframes loadingAnimation { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } - } - - @keyframes blinker { - 50% { - opacity: 0; - } - } - - paper-dialog.info { - width: 100%; - max-width: 75vw; - height: 100%; - max-height: 50vh; - background-color: var(--white); - color: var(--black); - border: 1px solid var(--black); - border-radius: 15px; - line-height: 1.6; - overflow-y: auto; - } - - .actions { - display: flex; - justify-content: space-between; - padding: 0 1em; - margin: 12px 0 -6px 0; - } - - .close-icon { - font-size: 36px; - } - - .close-icon:hover { - cursor: pointer; - opacity: .6; - } - - .setpass-wrapper { - width: 100%; - min-width: 400px; - max-width: 450px; - text-align: center; - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - padding: 10px 10px 0px; - box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1); - } - - .lock-wrapper { - width: 100%; - height: 100%; - min-width: 600px; - max-width: 600px; - min-height: 400px; - max-height: 400px; - text-align: center; - background: url("/img/qortal-lock.jpg"); - border: 1px solid var(--black); - border-radius: 25px; - padding: 10px 10px 0px; - } - - .text-wrapper { - width: 100%; - height: 100%; - min-width: 280px; - max-width: 280px; - min-height: 64px; - max-height: 64px; - text-align: center; - margin-left: 35px; - margin-top: 125px; - overflow: hidden; - } - - .lock-title-white { - font-family: 'magistralbold'; - font-weight: 700; - font-size: 26px; - line-height: 32px; - color: #ffffff; - } - - .lock-title-red { - font-family: 'magistralbold'; - font-weight: 700; - font-size: 26px; - line-height: 32px; - color: #df3636; - } - - @media (min-width: 701px) { - * {} - - #trade-portal {} - - #first-trade-section { - display: grid; - grid-template-columns: 1fr 1fr 2fr; - grid-auto-rows: max(450px); - column-gap: 0.5em; - row-gap: 0.4em; - justify-items: stretch; - align-items: stretch; - margin-bottom: 10px; - } - - #second-trade-section { - display: grid; - grid-template-columns: 2fr 1fr; - grid-auto-rows: max(450px); - column-gap: 0.5em; - row-gap: 0.4em; - justify-items: stretch; - align-items: stretch; - margin-bottom: 10px; - } - - #third-trade-section { - display: grid; - grid-template-columns: 1fr 2fr 1fr; - grid-auto-rows: max(200px); - column-gap: 0.5em; - row-gap: 0.4em; - justify-items: stretch; - align-items: stretch; - margin-bottom: 10px; - } - } -` \ No newline at end of file diff --git a/plugins/plugins/core/trade-portal/trade-portal.src.js b/plugins/plugins/core/trade-portal/trade-portal.src.js index a8405c55..d122b0df 100644 --- a/plugins/plugins/core/trade-portal/trade-portal.src.js +++ b/plugins/plugins/core/trade-portal/trade-portal.src.js @@ -1,11 +1,18 @@ -import {html, LitElement} from 'lit' -import {render} from 'lit/html.js' -import {Epml} from '../../../epml.js' +import { html, LitElement } from 'lit' +import { render } from 'lit/html.js' +import { Epml } from '../../../epml' +import { decryptData, encryptData } from '../../../../core/src/lockScreen' +import { tradePortalStyles } from '../components/plugins-css' import isElectron from 'is-electron' -import {get, registerTranslateConfig, translate, use} from '../../../../core/translate' -import Base58 from '../../../../crypto/api/deps/Base58.js' -import {decryptData, encryptData} from '../../../../core/src/lockScreen.js' -import {tradeStyles} from './trade-portal-css.js' +import chartsbtc from './charts/btc-charts' +import chartsltc from './charts/ltc-charts' +import chartsdoge from './charts/doge-charts' +import chartsdgb from './charts/dgb-charts' +import chartsrvn from './charts/rvn-charts' +import chartsarrr from './charts/arrr-charts' +import Base58 from '../../../../crypto/api/deps/Base58' +import '../components/TradeInfoView' +import '../components/TraderInfoView' import '@material/mwc-button' import '@material/mwc-textfield' import '@material/mwc-icon' @@ -23,17 +30,11 @@ import '@polymer/paper-spinner/paper-spinner-lite.js' import '@vaadin/grid' import '@vaadin/grid/vaadin-grid-sorter' import '@vaadin/password-field' -import chartsbtc from './charts/btc-charts.js' -import chartsltc from './charts/ltc-charts.js' -import chartsdoge from './charts/doge-charts.js' -import chartsdgb from './charts/dgb-charts.js' -import chartsrvn from './charts/rvn-charts.js' -import chartsarrr from './charts/arrr-charts.js' -import '../components/TraderInfoView.js' -import '../components/TradeInfoView.js' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) @@ -41,2205 +42,2221 @@ const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) let workers = new Map() class TradePortal extends LitElement { - static get properties() { - return { - selectedAddress: { type: Object }, - config: { type: Object }, - listedCoins: { type: Map }, - nodeInfo: { type: Array }, - blockedTradesList: { type: Array }, - tradesPresenceCleaned: { type: Array }, - sellBtnDisable: { type: Boolean }, - isSellLoading: { type: Boolean }, - isBuyLoading: { type: Boolean }, - buyBtnDisable: { type: Boolean }, - autoBuyWarning: { type: Boolean }, - autoBuyBtnDisable: { type: Boolean }, - autoBuyBotDisable: { type: Boolean }, - initialAmount: { type: Number }, - cancelBtnDisable: { type: Boolean }, - cancelStuckOfferBtnDisable: { type: Boolean }, - selectedCoin: { type: String }, - isLoadingHistoricTrades: { type: Boolean }, - isLoadingOpenTrades: { type: Boolean }, - isLoadingMyOpenOrders: { type: Boolean }, - showGetWalletBance: { type: Boolean }, - theme: { type: String, reflect: true }, - btcWallet: { type: String }, - ltcWallet: { type: String }, - dogeWallet: { type: String }, - dgbWallet: { type: String }, - rvnWallet: { type: String }, - arrrWallet: { type: String }, - arrrWalletAddress: { type: String }, - qortbtc: { type: Number }, - qortltc: { type: Number }, - qortdoge: { type: Number }, - qortdgb: { type: Number }, - qortrvn: { type: Number }, - qortarrr: { type: Number }, - btcqort: { type: Number }, - ltcqort: { type: Number }, - dogeqort: { type: Number }, - dgbqort: { type: Number }, - rvnqort: { type: Number }, - arrrqort: { type: Number }, - qortRatio: {type: Number}, - tradeSalt: { type: String }, - tradeStorageData: { type: String }, - tradeLockScreenPass: { type: String }, - tradeLockScreenSet: { type: String }, - tradeLockPass: { type: String }, - tradeLockSet: { type: String }, - myTradeLockScreenPass: { type: String }, - myTradeLockScreenSet: { type: String }, - tradeHelperMessage: { type: String } - } - } + static get properties() { + return { + selectedAddress: { type: Object }, + config: { type: Object }, + listedCoins: { type: Map }, + nodeInfo: { type: Array }, + blockedTradesList: { type: Array }, + tradesPresenceCleaned: { type: Array }, + sellBtnDisable: { type: Boolean }, + isSellLoading: { type: Boolean }, + isBuyLoading: { type: Boolean }, + buyBtnDisable: { type: Boolean }, + autoBuyWarning: { type: Boolean }, + autoBuyBtnDisable: { type: Boolean }, + autoBuyBotDisable: { type: Boolean }, + initialAmount: { type: Number }, + cancelBtnDisable: { type: Boolean }, + cancelStuckOfferBtnDisable: { type: Boolean }, + selectedCoin: { type: String }, + isLoadingHistoricTrades: { type: Boolean }, + isLoadingOpenTrades: { type: Boolean }, + isLoadingMyOpenOrders: { type: Boolean }, + showGetWalletBance: { type: Boolean }, + theme: { type: String, reflect: true }, + btcWallet: { type: String }, + ltcWallet: { type: String }, + dogeWallet: { type: String }, + dgbWallet: { type: String }, + rvnWallet: { type: String }, + arrrWallet: { type: String }, + arrrWalletAddress: { type: String }, + qortbtc: { type: Number }, + qortltc: { type: Number }, + qortdoge: { type: Number }, + qortdgb: { type: Number }, + qortrvn: { type: Number }, + qortarrr: { type: Number }, + btcqort: { type: Number }, + ltcqort: { type: Number }, + dogeqort: { type: Number }, + dgbqort: { type: Number }, + rvnqort: { type: Number }, + arrrqort: { type: Number }, + qortRatio: { type: Number }, + tradeSalt: { type: String }, + tradeStorageData: { type: String }, + tradeLockScreenPass: { type: String }, + tradeLockScreenSet: { type: String }, + tradeLockPass: { type: String }, + tradeLockSet: { type: String }, + myTradeLockScreenPass: { type: String }, + myTradeLockScreenSet: { type: String }, + tradeHelperMessage: { type: String } + } + } - static get styles() { - return [tradeStyles] - } + static get styles() { + return [tradePortalStyles] + } - constructor() { - super() - let qortal = { - name: "QORTAL", - balance: "0", - coinCode: "QORT", - coinAmount: this.amountString, - tradeFee: "0.02" - } + constructor() { + super() + let qortal = { + name: "QORTAL", + balance: "0", + coinCode: "QORT", + coinAmount: this.amountString, + tradeFee: "0.02" + } - let bitcoin = { - name: "BITCOIN", - balance: "0", - coinCode: "BTC", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.0001" - } + let bitcoin = { + name: "BITCOIN", + balance: "0", + coinCode: "BTC", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.0001" + } - let litecoin = { - name: "LITECOIN", - balance: "0", - coinCode: "LTC", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.00005" - } + let litecoin = { + name: "LITECOIN", + balance: "0", + coinCode: "LTC", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.00005" + } - let dogecoin = { - name: "DOGECOIN", - balance: "0", - coinCode: "DOGE", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.005" - } + let dogecoin = { + name: "DOGECOIN", + balance: "0", + coinCode: "DOGE", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.005" + } - let digibyte = { - name: "DIGIBYTE", - balance: "0", - coinCode: "DGB", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.0005" - } + let digibyte = { + name: "DIGIBYTE", + balance: "0", + coinCode: "DGB", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.0005" + } - let ravencoin = { - name: "RAVENCOIN", - balance: "0", - coinCode: "RVN", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.006" - } + let ravencoin = { + name: "RAVENCOIN", + balance: "0", + coinCode: "RVN", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.006" + } - let piratechain = { - name: "PIRATECHAIN", - balance: "0", - coinCode: "ARRR", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.0002" - } + let piratechain = { + name: "PIRATECHAIN", + balance: "0", + coinCode: "ARRR", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.0002" + } - this.listedCoins = new Map() - this.listedCoins.set("QORTAL", qortal) - this.listedCoins.set("BITCOIN", bitcoin) - this.listedCoins.set("LITECOIN", litecoin) - this.listedCoins.set("DOGECOIN", dogecoin) - this.listedCoins.set("DIGIBYTE", digibyte) - this.listedCoins.set("RAVENCOIN", ravencoin) - this.listedCoins.set("PIRATECHAIN", piratechain) + this.listedCoins = new Map() + this.listedCoins.set("QORTAL", qortal) + this.listedCoins.set("BITCOIN", bitcoin) + this.listedCoins.set("LITECOIN", litecoin) + this.listedCoins.set("DOGECOIN", dogecoin) + this.listedCoins.set("DIGIBYTE", digibyte) + this.listedCoins.set("RAVENCOIN", ravencoin) + this.listedCoins.set("PIRATECHAIN", piratechain) - workers.set("QORTAL", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("QORTAL", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("BITCOIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("BITCOIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("LITECOIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("LITECOIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("DOGECOIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("DOGECOIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("DIGIBYTE", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("DIGIBYTE", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("RAVENCOIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("RAVENCOIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("PIRATECHAIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("PIRATECHAIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - this.selectedCoin = "LITECOIN" - this.selectedAddress = {} - this.nodeInfo = [] - this.blockedTradesList = [] - this.preparedPresence = [] - this.tradesPresenceCleaned = [] - this.config = {} - this.sellBtnDisable = false - this.isSellLoading = false - this.buyBtnDisable = true - this.autoBuyWarning = false - this.autoBuyBtnDisable = true - this.autoBuyBotDisable = false - this.isBuyLoading = false - this.initialAmount = 0 - this.cancelBtnDisable = false - this.cancelStuckOfferBtnDisable = false - this.isLoadingHistoricTrades = true - this.isLoadingOpenTrades = true - this.isLoadingMyOpenOrders = false - this.showGetWalletBance = true - this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' - this.btcWallet = '' - this.ltcWallet = '' - this.dogeWallet = '' - this.dgbWallet = '' - this.rvnWallet = '' - this.arrrWallet = '' - this.arrrWalletAddress = '' - this.qortbtc = 0 - this.qortltc = 0 - this.qortdoge = 0 - this.qortdgb = 0 - this.qortrvn = 0 - this.qortarrr = 0 - this.btcqort = 0 - this.ltcqort = 0 - this.dogeqort = 0 - this.dgbqort = 0 - this.rvnqort = 0 - this.arrrqort = 0 - this.tradeInfoAccountName = '' - this.tradeImageUrl = '' - this.tradeAddressResult = [] - this.displayTradeAddress = '' - this.displayTradeLevel = '' - this.displayTradeBalance = '' - this.tradeSalt = '' - this.tradeStorageData = '' - this.tradeLockScreenPass = '' - this.tradeLockScreenSet = '' - this.tradeLockPass = '' - this.tradeLockSet = '' - this.myTradeLockScreenPass = '' - this.myTradeLockScreenSet = '' - this.tradeHelperMessage = '' - this.pingCoinBalancesController = this.pingCoinBalancesController.bind(this) - } + this.selectedCoin = "LITECOIN" + this.selectedAddress = {} + this.nodeInfo = [] + this.blockedTradesList = [] + this.preparedPresence = [] + this.tradesPresenceCleaned = [] + this.config = {} + this.sellBtnDisable = false + this.isSellLoading = false + this.buyBtnDisable = true + this.autoBuyWarning = false + this.autoBuyBtnDisable = true + this.autoBuyBotDisable = false + this.isBuyLoading = false + this.initialAmount = 0 + this.cancelBtnDisable = false + this.cancelStuckOfferBtnDisable = false + this.isLoadingHistoricTrades = true + this.isLoadingOpenTrades = true + this.isLoadingMyOpenOrders = false + this.showGetWalletBance = true + this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' + this.btcWallet = '' + this.ltcWallet = '' + this.dogeWallet = '' + this.dgbWallet = '' + this.rvnWallet = '' + this.arrrWallet = '' + this.arrrWalletAddress = '' + this.qortbtc = 0 + this.qortltc = 0 + this.qortdoge = 0 + this.qortdgb = 0 + this.qortrvn = 0 + this.qortarrr = 0 + this.btcqort = 0 + this.ltcqort = 0 + this.dogeqort = 0 + this.dgbqort = 0 + this.rvnqort = 0 + this.arrrqort = 0 + this.tradeInfoAccountName = '' + this.tradeImageUrl = '' + this.tradeAddressResult = [] + this.displayTradeAddress = '' + this.displayTradeLevel = '' + this.displayTradeBalance = '' + this.tradeSalt = '' + this.tradeStorageData = '' + this.tradeLockScreenPass = '' + this.tradeLockScreenSet = '' + this.tradeLockPass = '' + this.tradeLockSet = '' + this.myTradeLockScreenPass = '' + this.myTradeLockScreenSet = '' + this.tradeHelperMessage = '' + this.pingCoinBalancesController = this.pingCoinBalancesController.bind(this) + } - historicTradesTemplate() { - return html` -
    -
    -
    ${translate("tradepage.tchange3")}
    -
    -
    ${translate("login.loading")}
    - - { - render(html`${data.item.qortAmount}`, root) - }} - > - - { - const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) - render(html`${price}`, root) - }} - > - - { - render(html`${data.item.foreignAmount}`, root) - }} - > - - + render() { + return html` +
    +
    +

    Qortal ${translate("tradepage.tchange1")} -  

    + + QORT / LTC + QORT / BTC + QORT / DOGE + QORT / DGB + QORT / RVN + QORT / ARRR + +
    + this.shadowRoot.getElementById('tradeInfoDialog').open()}> +
    +
    + ${this.chartShowCoin()} +
    +
    + ${this.renderTradeLockButton()} +
    +
    +
    +
    + ${this.historicTradesTemplate()} + ${this.myHistoricTradesTemplate()} + ${this.openTradesTemplate()} +
    +
    + ${this.myOpenOrdersTemplate()} + ${this.openMarketTemplate()} +
    +
    +
    +
    +

    ${translate("tradepage.tchange33")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange40")}

    +

    1 QORT = ${this.exchangeRateQort()} ${this.listedCoins.get(this.selectedCoin).coinCode}

    + this.setDefaultSellPrice()}> +
    +
    +
    -
    - ` - } - - openTradesTemplate() { - return html` -
    -
    -
    ${translate("tradepage.tchange5")}
    -
    -
    ${translate("login.loading")}
    - - { - render(html`${this.round(data.item.qortAmount)}`, root) - }} - > - - { - render(html`${this.round(data.item.price)}`, root) - }} - > - - { - render(html`${data.item.foreignAmount}`, root) - }} - > - - { - render(html`${data.item.qortalCreator}`, root) - }} - > - - { - render(html`info`, root) - }} - > - + + +
    +

    ${translate("tradepage.tchange7")}

    +
    +
    +
    + + + + + { render(html`${this.renderCancelStuckOfferButton(data.item)}`, root) }}>
    -
    -
    - ` - } + ${translate("general.close")} + + +
    +

    + this.shadowRoot.getElementById('tradeInfoDialog').close()} title="${translate("info.inf2")}">highlight_off +
    +
    +

    ${translate("info.inf1")}

    +

    ${translate("info.inf3")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("info.inf4")}

    +

    ${translate("info.inf5")} ${this.listedCoins.get(this.selectedCoin).coinCode}

    +

    ${translate("info.inf6")}

    +
    +
    + +
    +

    Qortal ${translate("tabmenu.tm4")} ${translate("login.lp1")}

    +
    +
    +
    +

    ${translate("login.lp2")}

    +

    ${translate("login.lp3")}

    +
    +
    + password + +
    +
    + password + +
    +
    + ${translate("login.lp4")} + ${translate("login.lp5")} +
    +
    + +
    +

    Qortal ${translate("tabmenu.tm4")} ${translate("login.lp1")}

    +
    +
    +
    +

    ${translate("login.lessthen8")}

    +
    +
    + ${translate("login.lp4")} + ${translate("login.lp5")} +
    +
    + +
    + ${translate("sidemenu.tradeportal")}
    + ${translate("login.lp9")} + ${translate("login.lp10")} +
    +
    + password + +
    + ${this.tradeHelperMessage} +
    +
    +
    +
    + +
    +
    + + + ` + } - openMarketTemplate() { - return html` -
    -
    - - - - - -
    -
    -
    - -
    - ${translate("tradepage.tchange8")} (QORT)* -

    - - -

    - ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - - -

    - - ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} - ${translate("walletpage.wchange12")}: ${this.listedCoins.get(this.selectedCoin).tradeFee} ${this.listedCoins.get(this.selectedCoin).coinCode} - -
    -
    - - ${this.isBuyLoading === false ? html`${translate("tradepage.tchange18")}` : html``} - + async firstUpdated() { + let _this = this + + this.changeTheme() + this.changeLanguage() + + this.tradeFee() + this.getNewBlockedTrades() + + this.tradeHelperMessage = this.renderTradeHelperPass() + + this.tradeSalt = '' + this.tradeSalt = Base58.encode(window.parent.reduxStore.getState().app.wallet._addresses[0].keyPair.privateKey) + + this.tradeStorageData = '' + this.tradeStorageData = window.parent.reduxStore.getState().app.selectedAddress.address + + this.tradeLockScreenPass = '' + this.tradeLockScreenPass = 'tradeLockScreenPass-' + this.tradeStorageData + + this.tradeLockScreenSet = '' + this.tradeLockScreenSet = 'tradeLockScreenSet-' + this.tradeStorageData + + this.tradeLockPass = '' + this.tradeLockPass = encryptData(false, this.tradeSalt) + + this.tradeLockSet = '' + this.tradeLockSet = encryptData(false, this.tradeSalt) + + if (localStorage.getItem(this.tradeLockScreenPass) === null && localStorage.getItem(this.tradeLockScreenSet) === null) { + localStorage.setItem(this.tradeLockScreenPass, this.tradeLockPass) + localStorage.setItem(this.tradeLockScreenSet, this.tradeLockSet) + this.myTradeLockScreenPass = '' + this.myTradeLockScreenPass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt) + this.myTradeLockScreenSet = '' + this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt) + } else { + this.myTradeLockScreenPass = '' + this.myTradeLockScreenPass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt) + this.myTradeLockScreenSet = '' + this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt) + } + + if (this.myTradeLockScreenSet === true) { + this.shadowRoot.getElementById('tradeLockScreenActive').open() + } + + this.updateWalletBalance() + this.fetchWalletAddress(this.selectedCoin) + this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + + setTimeout(() => { + this.displayTabContent('buy') + }, 0) + + this._openOrdersGrid = this.shadowRoot.getElementById('openOrdersGrid') + + this._openOrdersGrid.querySelector('#priceColumn').headerRenderer = function (root) { + const priceString = get("tradepage.tchange9") + root.innerHTML = '' + priceString + ' (' + _this.listedCoins.get(_this.selectedCoin).coinCode + ')' + } + + this._openOrdersGrid.querySelector('#qortAmountColumn').headerRenderer = function (root) { + const amountString = get("tradepage.tchange8") + root.innerHTML = '' + amountString + ' (QORT)' + } + + this._myOrdersGrid = this.shadowRoot.getElementById('myOrdersGrid') + this._historicTradesGrid = this.shadowRoot.getElementById('historicTradesGrid') + this._myHistoricTradesGrid = this.shadowRoot.getElementById('myHistoricTradesGrid') + this._stuckOrdersGrid = this.shadowRoot.getElementById('stuckOrdersGrid') + + const getNodeInfo = () => { + parentEpml.request("apiCall", { url: `/admin/status` }).then((res) => { + this.nodeInfo = res + getSellButtonStatus() + }) + setTimeout(getNodeInfo, 30000) + } + + const getSellButtonStatus = () => { + if (this.nodeInfo.isSynchronizing === true) { + this.sellBtnDisable = true + } else this.sellBtnDisable = this.nodeInfo.isSynchronizing !== false; + } + + const getQortBtcPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/BITCOIN?inverse=true` }).then((res) => { + this.qortbtc = (Number(res) / 1e8).toFixed(8) + }) + setTimeout(getQortBtcPrice, 300000) + } + + const getQortLtcPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/LITECOIN?inverse=true` }).then((res) => { + this.qortltc = (Number(res) / 1e8).toFixed(8) + }) + setTimeout(getQortLtcPrice, 300000) + } + + const getQortDogePrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/DOGECOIN?inverse=true` }).then((res) => { + this.qortdoge = (Number(res) / 1e8).toFixed(8) + }) + setTimeout(getQortDogePrice, 300000) + } + + const getQortDgbPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/DIGIBYTE?inverse=true` }).then((res) => { + this.qortdgb = (Number(res) / 1e8).toFixed(8) + }) + setTimeout(getQortDgbPrice, 300000) + } + + const getQortRvnPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/RAVENCOIN?inverse=true` }).then((res) => { + this.qortrvn = (Number(res) / 1e8).toFixed(8) + }) + setTimeout(getQortRvnPrice, 300000) + } + + const getQortArrrPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/PIRATECHAIN?inverse=true` }).then((res) => { + this.qortarrr = (Number(res) / 1e8).toFixed(8) + }) + setTimeout(getQortArrrPrice, 300000) + } + + window.addEventListener('storage', () => { + this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + const checkLanguage = localStorage.getItem('qortalLanguage') + const checkTheme = localStorage.getItem('qortalTheme') + + use(checkLanguage) + + this.theme = (checkTheme === 'dark') ? 'dark' : 'light' + document.querySelector('html').setAttribute('theme', this.theme) + }) + + if (!isElectron()) { + } else { + window.addEventListener('contextmenu', (event) => { + event.preventDefault() + window.parent.electronAPI.showMyMenu() + }) + } + + this.btcWallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address + this.ltcWallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address + this.dogeWallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address + this.dgbWallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address + this.rvnWallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address + this.arrrWallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address + + let configLoaded = false + + parentEpml.ready().then(() => { + parentEpml.subscribe('selected_address', async (selectedAddress) => { + this.selectedAddress = {} + selectedAddress = JSON.parse(selectedAddress) + if (!selectedAddress || Object.entries(selectedAddress).length === 0) return + this.selectedAddress = selectedAddress + + this.btcWallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address + this.ltcWallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address + this.dogeWallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address + this.dgbWallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address + this.rvnWallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address + this.arrrWallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address + this.updateAccountBalance() + }) + + parentEpml.subscribe('config', (c) => { + if (!configLoaded) { + setTimeout(getNodeInfo, 1) + setTimeout(getQortBtcPrice, 1) + setTimeout(getQortLtcPrice, 1) + setTimeout(getQortDogePrice, 1) + setTimeout(getQortDgbPrice, 1) + setTimeout(getQortRvnPrice, 1) + setTimeout(getQortArrrPrice, 1) + configLoaded = true + } + this.config = JSON.parse(c) + }) + + parentEpml.subscribe('coin_balances', async (payload) => { + const coinBalances = JSON.parse(payload) + let coin = '' + switch (this.selectedCoin) { + case 'BITCOIN': + coin = 'btc' + break + case 'LITECOIN': + coin = 'ltc' + break + case 'DOGECOIN': + coin = 'doge' + break + case 'DIGIBYTE': + coin = 'dgb' + break + case 'RAVENCOIN': + coin = 'rvn' + break + case 'PIRATECHAIN': + coin = 'arrr' + break + default: + break + } + if (coinBalances[coin]) { + const res = coinBalances[coin].fullValue + let value = (Number(res) / 1e8).toFixed(8) + if (coin !== 'qort') { + value = (Number(res) / 1e8).toFixed(8) + } + this.listedCoins.get(this.selectedCoin).balance = value + this.requestUpdate() + } + }) + + let coinSelectionMenu = this.shadowRoot.getElementById("coinSelectionMenu") + + coinSelectionMenu.addEventListener('change', function () { + _this.setForeignCoin(coinSelectionMenu.value, false) + }) + + _this.setForeignCoin(coinSelectionMenu.value, true) + }) + + parentEpml.imReady() + + setTimeout(() => this.shadowRoot.querySelector('[slot="vaadin-grid-cell-content-3"]').setAttribute('title', 'Last Seen'), 3000) + + this.clearConsole() + + setInterval(() => { + this.clearConsole() + }, 60000) + + setInterval(() => { + this.getNewBlockedTrades() + }, 150000) + } + + historicTradesTemplate() { + return html` +
    +
    +
    ${translate("tradepage.tchange3")}
    +
    +
    +
    + ${translate("login.loading")} +
    + + { + render(html`${data.item.qortAmount}`, root) + }} + > + + { + const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) + render(html`${price}`, root) + }} + > + + { + render(html`${data.item.foreignAmount}`, root) + }} + > + + +
    +
    +
    + ` + } + + openTradesTemplate() { + return html` +
    +
    +
    ${translate("tradepage.tchange5")}
    +
    +
    +
    + ${translate("login.loading")} +
    + + { + render(html`${this.round(data.item.qortAmount)}`, root) + }} + > + + { + render(html`${this.round(data.item.price)}`, root) + }} + > + + { + render(html`${data.item.foreignAmount}`, root) + }} + > + + { + render(html`${data.item.qortalCreator}`, root) + }} + > + + { + render(html` + + info + + `, root) + }} + > + + +
    +
    +
    + ` + } + + openMarketTemplate() { + return html` +
    +
    + + + + +
    +
    +
    +
    + +
    + ${translate("tradepage.tchange8")} (QORT)* +

    + + +

    + ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + + +

    + + ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} + ${translate("walletpage.wchange12")}: ${this.listedCoins.get(this.selectedCoin).tradeFee} ${this.listedCoins.get(this.selectedCoin).coinCode} + +
    +
    + + ${this.isBuyLoading === false ? html`${translate("tradepage.tchange18")}` : html` + + `} + +
    -
    -
    -
    -
    - -
    - ${translate("tradepage.tchange8")} (QORT)* -

    - - -

    - ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - - ${translate("tradepage.tchange16")}: ${this.listedCoins.get("QORTAL").balance} QORT - ${translate("walletpage.wchange12")}: ${this.listedCoins.get("QORTAL").tradeFee} QORT - -
    -
    - - ${this.isSellLoading === false ? html`${translate("tradepage.tchange19")}` : html``} - +
    +
    +
    + +
    + ${translate("tradepage.tchange8")} (QORT)* +

    + + +

    + ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + + ${translate("tradepage.tchange16")}: ${this.listedCoins.get("QORTAL").balance} QORT + ${translate("walletpage.wchange12")}: ${this.listedCoins.get("QORTAL").tradeFee} QORT + +
    +
    + + ${this.isSellLoading === false ? html`${translate("tradepage.tchange19")}` : html` + + `} + +
    -
    - ` - } + ` + } - myOpenOrdersTemplate() { - return html` -
    -
    -
    ${translate("tradepage.tchange6")} this.showStuckOrdersDialog()}>
    -
    -
    ${translate("login.loading")}
    - - { - const dateString = new Date(data.item.timestamp).toLocaleString() - render(html`${dateString}`, root) - }} - > - - { - render(html` ${data.item._tradeState} `, root) - }} - > - - { - const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) - render(html`${price}`, root) - }} - > - - - - - - { - render(html`${this.renderCancelButton(data.item)}`, root) - }} - > - - -
    -
    -
    - ` - } - - myHistoricTradesTemplate() { - return html` -
    -
    -
    ${translate("tradepage.tchange4")}
    -
    - - { - const dateString = new Date(data.item.timestamp).toLocaleString() - render(html`${dateString}`, root) - }} - > - - { - if (data.item.mode === 'SOLD') return render(html` ${translate("tradepage.tchange31")} `, root) - if (data.item.mode === 'BOUGHT') return render(html` ${translate("tradepage.tchange32")} `, root) - return render(html` ${data.item.mode} `, root) - }} - > - - { - const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) - render(html`${price}`, root) - }} - > - - - - { - render(html` ${data.item.foreignAmount} `, root) - }} - > - - -
    -
    -
    - ` - } - - render() { - return html` -
    -
    -

    Qortal ${translate("tradepage.tchange1")} -  

    - - QORT / LTC - QORT / BTC - QORT / DOGE - QORT / DGB - QORT / RVN - QORT / ARRR - -
    - this.shadowRoot.getElementById('tradeInfoDialog').open()}> -
    -
    - ${this.chartShowCoin()} -
    -
    - ${this.renderTradeLockButton()} -
    - -
    -
    -
    - ${this.historicTradesTemplate()} - ${this.myHistoricTradesTemplate()} - ${this.openTradesTemplate()} -
    -
    - ${this.myOpenOrdersTemplate()} - ${this.openMarketTemplate()} -
    -
    -
    -
    -

    ${translate("tradepage.tchange33")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange40")}

    -

    1 QORT = ${this.exchangeRateQort()} ${this.listedCoins.get(this.selectedCoin).coinCode}

    - this.setDefaultSellPrice()}> + myOpenOrdersTemplate() { + return html` +
    +
    +
    ${translate("tradepage.tchange6")} this.showStuckOrdersDialog()}>
    +
    +
    +
    + ${translate("login.loading")} +
    + + { + const dateString = new Date(data.item.timestamp).toLocaleString() + render(html`${dateString}`, root) + }} + > + + { + render(html` ${data.item._tradeState} `, root) + }} + > + + { + const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) + render(html`${price}`, root) + }} + > + + + + + + { + render(html`${this.renderCancelButton(data.item)}`, root) + }} + > + +
    -
    -
    - - -
    -

    ${translate("tradepage.tchange7")}

    -
    + ` + } + + myHistoricTradesTemplate() { + return html` +
    +
    +
    ${translate("tradepage.tchange4")}
    +
    + + { + const dateString = new Date(data.item.timestamp).toLocaleString() + render(html`${dateString}`, root) + }} + > + + { + if (data.item.mode === 'SOLD') return render(html` ${translate("tradepage.tchange31")} `, root) + if (data.item.mode === 'BOUGHT') return render(html` ${translate("tradepage.tchange32")} `, root) + return render(html` ${data.item.mode} `, root) + }} + > + + { + const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) + render(html`${price}`, root) + }} + > + + + + { + render(html` ${data.item.foreignAmount} `, root) + }} + > + + +
    +
    -
    - - - - - { render(html`${this.renderCancelStuckOfferButton(data.item)}`, root) }}> - -
    - ${translate("general.close")} - - - -
    -

    - this.shadowRoot.getElementById('tradeInfoDialog').close()} title="${translate("info.inf2")}">highlight_off -
    -
    -

    ${translate("info.inf1")}

    -

    ${translate("info.inf3")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("info.inf4")}

    -

    ${translate("info.inf5")} ${this.listedCoins.get(this.selectedCoin).coinCode}

    -

    ${translate("info.inf6")}

    -
    -
    - -
    -

    Qortal ${translate("tabmenu.tm4")} ${translate("login.lp1")}

    -
    -
    -
    -

    ${translate("login.lp2")}

    -

    ${translate("login.lp3")}

    -
    -
    - password - -
    -
    - password - -
    -
    - ${translate("login.lp4")} - ${translate("login.lp5")} -
    -
    - -
    -

    Qortal ${translate("tabmenu.tm4")} ${translate("login.lp1")}

    -
    -
    -
    -

    ${translate("login.lessthen8")}

    -
    -
    - ${translate("login.lp4")} - ${translate("login.lp5")} -
    -
    - -
    - ${translate("sidemenu.tradeportal")}
    - ${translate("login.lp9")} - ${translate("login.lp10")} -
    -
    - password - -
    - ${this.tradeHelperMessage} -
    -
    -
    -
    - -
    -
    - - - ` - } - - pingCoinBalancesController() { - if(!this.selectedCoin) return - let coin = '' - switch (this.selectedCoin) { - case 'BITCOIN': - coin ='btc' - break - case 'LITECOIN': - coin = 'ltc' - break - case 'DOGECOIN': - coin = 'doge' - break - case 'DIGIBYTE': - coin = 'dgb' - break - case 'RAVENCOIN': - coin = 'rvn' - break - case 'PIRATECHAIN': - coin = 'arrr' - break - default: - break - } - const customEvent = new CustomEvent('ping-coin-controller-with-coin', { - detail: coin - }) - window.parent.dispatchEvent(customEvent) - } - - connectedCallback() { - super.connectedCallback() - this.intervalID = setInterval(this.pingCoinBalancesController, 30000) - } - - disconnectedCallback() { - super.disconnectedCallback() - if (this.intervalID) { - clearInterval(this.intervalID) - } - } - - async firstUpdated() { - let _this = this - - this.changeTheme() - this.changeLanguage() - await this.tradeFee() - await this.getNewBlockedTrades() - - this.tradeHelperMessage = this.renderTradeHelperPass() - - this.tradeSalt = '' - this.tradeSalt = Base58.encode(window.parent.reduxStore.getState().app.wallet._addresses[0].keyPair.privateKey) - - this.tradeStorageData = '' - this.tradeStorageData = window.parent.reduxStore.getState().app.selectedAddress.address - - this.tradeLockScreenPass = '' - this.tradeLockScreenPass = 'tradeLockScreenPass-' + this.tradeStorageData - - this.tradeLockScreenSet = '' - this.tradeLockScreenSet = 'tradeLockScreenSet-' + this.tradeStorageData - - this.tradeLockPass = '' - this.tradeLockPass = encryptData(false, this.tradeSalt) - - this.tradeLockSet = '' - this.tradeLockSet = encryptData(false, this.tradeSalt) - - if (localStorage.getItem(this.tradeLockScreenPass) === null && localStorage.getItem(this.tradeLockScreenSet) === null) { - localStorage.setItem(this.tradeLockScreenPass, this.tradeLockPass) - localStorage.setItem(this.tradeLockScreenSet, this.tradeLockSet) - this.myTradeLockScreenPass = '' - this.myTradeLockScreenPass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt) - this.myTradeLockScreenSet = '' - this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt) - } else { - this.myTradeLockScreenPass = '' - this.myTradeLockScreenPass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt) - this.myTradeLockScreenSet = '' - this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt) - } - - if (this.myTradeLockScreenSet === true) { - this.shadowRoot.getElementById('tradeLockScreenActive').open() - } - - await this.updateWalletBalance() - await this.fetchWalletAddress(this.selectedCoin) - this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') - - setTimeout(() => { - this.displayTabContent('buy') - }, 0) - - this._openOrdersGrid = this.shadowRoot.getElementById('openOrdersGrid') - - this._openOrdersGrid.querySelector('#priceColumn').headerRenderer = function (root) { - const priceString = get("tradepage.tchange9") - root.innerHTML = '' + priceString + ' (' + _this.listedCoins.get(_this.selectedCoin).coinCode + ')' - } - - this._openOrdersGrid.querySelector('#qortAmountColumn').headerRenderer = function (root) { - const amountString = get("tradepage.tchange8") - root.innerHTML = '' + amountString + ' (QORT)' - } - - this._myOrdersGrid = this.shadowRoot.getElementById('myOrdersGrid') - this._historicTradesGrid = this.shadowRoot.getElementById('historicTradesGrid') - this._myHistoricTradesGrid = this.shadowRoot.getElementById('myHistoricTradesGrid') - this._stuckOrdersGrid = this.shadowRoot.getElementById('stuckOrdersGrid') - - const getNodeInfo = () => { - parentEpml.request("apiCall", { url: `/admin/status` }).then((res) => { - this.nodeInfo = res - getSellButtonStatus() - }) - setTimeout(getNodeInfo, 30000) - } - - const getSellButtonStatus = () => { - if (this.nodeInfo.isSynchronizing === true) { - this.sellBtnDisable = true - } else this.sellBtnDisable = this.nodeInfo.isSynchronizing !== false; - } - - const getQortBtcPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/BITCOIN?inverse=true` }).then((res) => { - this.qortbtc = (Number(res) / 1e8).toFixed(8) - }) - setTimeout(getQortBtcPrice, 300000) - } - - const getQortLtcPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/LITECOIN?inverse=true` }).then((res) => { - this.qortltc = (Number(res) / 1e8).toFixed(8) - }) - setTimeout(getQortLtcPrice, 300000) - } - - const getQortDogePrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/DOGECOIN?inverse=true` }).then((res) => { - this.qortdoge = (Number(res) / 1e8).toFixed(8) - }) - setTimeout(getQortDogePrice, 300000) - } - - const getQortDgbPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/DIGIBYTE?inverse=true` }).then((res) => { - this.qortdgb = (Number(res) / 1e8).toFixed(8) - }) - setTimeout(getQortDgbPrice, 300000) - } - - const getQortRvnPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/RAVENCOIN?inverse=true` }).then((res) => { - this.qortrvn = (Number(res) / 1e8).toFixed(8) - }) - setTimeout(getQortRvnPrice, 300000) - } - - const getQortArrrPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/PIRATECHAIN?inverse=true` }).then((res) => { - this.qortarrr = (Number(res) / 1e8).toFixed(8) - }) - setTimeout(getQortArrrPrice, 300000) - } - - window.addEventListener('storage', () => { - this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') - const checkLanguage = localStorage.getItem('qortalLanguage') - const checkTheme = localStorage.getItem('qortalTheme') - - use(checkLanguage) - - this.theme = (checkTheme === 'dark') ? 'dark' : 'light' - document.querySelector('html').setAttribute('theme', this.theme) - }) - - if (!isElectron()) { - } else { - window.addEventListener('contextmenu', (event) => { - event.preventDefault() - window.parent.electronAPI.showMyMenu() - }) - } - - this.btcWallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address - this.ltcWallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address - this.dogeWallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address - this.dgbWallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address - this.rvnWallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address - this.arrrWallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address - - let configLoaded = false - - parentEpml.ready().then(() => { - parentEpml.subscribe('selected_address', async (selectedAddress) => { - this.selectedAddress = {} - selectedAddress = JSON.parse(selectedAddress) - if (!selectedAddress || Object.entries(selectedAddress).length === 0) return - this.selectedAddress = selectedAddress - - this.btcWallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address - this.ltcWallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address - this.dogeWallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address - this.dgbWallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address - this.rvnWallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address - this.arrrWallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address - this.updateAccountBalance() - }) - - parentEpml.subscribe('config', (c) => { - if (!configLoaded) { - setTimeout(getNodeInfo, 1) - setTimeout(getQortBtcPrice, 1) - setTimeout(getQortLtcPrice, 1) - setTimeout(getQortDogePrice, 1) - setTimeout(getQortDgbPrice, 1) - setTimeout(getQortRvnPrice, 1) - setTimeout(getQortArrrPrice, 1) - configLoaded = true - } - this.config = JSON.parse(c) - }) - parentEpml.subscribe('coin_balances', async (payload) => { - const coinBalances = JSON.parse(payload) - let coin = '' - switch (this.selectedCoin) { - case 'BITCOIN': - coin ='btc' - break - case 'LITECOIN': - coin = 'ltc' - break - case 'DOGECOIN': - coin = 'doge' - break - case 'DIGIBYTE': - coin = 'dgb' - break - case 'RAVENCOIN': - coin = 'rvn' - break - case 'PIRATECHAIN': - coin = 'arrr' - break - default: - break - } - if(coinBalances[coin]){ - const res = coinBalances[coin].fullValue - let value = (Number(res) / 1e8).toFixed(8) - if(coin !== 'qort'){ - value = (Number(res) / 1e8).toFixed(8) - } - this.listedCoins.get(this.selectedCoin).balance = value - this.requestUpdate() - } - }) - - let coinSelectionMenu = this.shadowRoot.getElementById("coinSelectionMenu") - - coinSelectionMenu.addEventListener('change', function () { - _this.setForeignCoin(coinSelectionMenu.value,false) - }) - - _this.setForeignCoin(coinSelectionMenu.value,true) - }) - parentEpml.imReady() - - setTimeout(() => this.shadowRoot.querySelector('[slot="vaadin-grid-cell-content-3"]').setAttribute('title', 'Last Seen'), 3000) - - this.clearConsole() - setInterval(() => { - this.clearConsole() - }, 60000) - - setInterval(() => { - this.getNewBlockedTrades() - }, 150000) - } - - clearConsole() { - if (!isElectron()) { - } else { - console.clear() - window.parent.electronAPI.clearCache() - } - } - - renderTradeLockButton() { - if (this.myTradeLockScreenPass === false && this.myTradeLockScreenSet === false) { - return html` -
    - this.openTradeSetScreenLockPass()} title="${translate("login.lp11")}"> -
    - ` - } else if (this.myTradeLockScreenSet === false) { - return html` -
    - this.setTradeLockQortal()} title="${translate("login.lp11")}"> -
    - ` - } else if (this.myTradeLockScreenSet === true) { - return html` -
    - -
    - ` - } - } - - openTradeSetScreenLockPass() { - this.shadowRoot.getElementById('tradeLockPassword').value = '' - this.shadowRoot.getElementById('tradeLockPasswordConfirm').value = '' - this.shadowRoot.getElementById('setTradeLockScreenPass').open() - } - - closewTradeSetScreenLockPass() { - this.shadowRoot.getElementById('setTradeLockScreenPass').close() - } - - tradeCheckPass() { - const tradePassword = this.shadowRoot.getElementById('tradeLockPassword').value - const tradeRePassword = this.shadowRoot.getElementById('tradeLockPasswordConfirm').value - - if (tradePassword === '') { - let snackbar1string = get("login.pleaseenter") - parentEpml.request('showSnackBar', `${snackbar1string}`) - return - } - - if (tradePassword != tradeRePassword) { - let snackbar2string = get("login.notmatch") - parentEpml.request('showSnackBar', `${snackbar2string}`) - return - } - - if (tradePassword.length < 8) { - let snackbar3string = get("login.lessthen8") - parentEpml.request('showSnackBar', `${snackbar3string}`) - this.tradeExtraConfirm() - } - - if (tradePassword.length >= 8) { - this.setTradeNewScreenPass() - let snackbar4string = get("login.lp6") - parentEpml.request('showSnackBar', `${snackbar4string}`) - } - } - - tradeExtraConfirm() { - this.shadowRoot.getElementById('setTradeLockScreenPass').close() - this.shadowRoot.getElementById('tradeExtraConfirmPass').open() - } - - closTradeExtraConfirmPass() { - this.shadowRoot.getElementById('tradeExtraConfirmPass').close() - this.shadowRoot.getElementById('tradeLockPassword').value = '' - this.shadowRoot.getElementById('tradeLockPasswordConfirm').value = '' - } - - setTradeNewScreenPass() { - const tradeRawPassword = this.shadowRoot.getElementById('tradeLockPassword').value - const tradeCryptPassword = encryptData(tradeRawPassword, this.tradeSalt) - localStorage.setItem(this.tradeLockScreenPass, tradeCryptPassword) - this.myTradeLockScreenPass = '' - this.myTradeLockScreenPass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt) - this.shadowRoot.getElementById('setTradeLockScreenPass').close() - this.shadowRoot.getElementById('tradeExtraConfirmPass').close() - this.shadowRoot.getElementById('tradeLockPassword').value = '' - this.shadowRoot.getElementById('tradeLockPasswordConfirm').value = '' - } - - setTradeLockQortal() { - this.tradeHelperMessage = this.renderTradeHelperPass() - this.tradeLockSet = '' - this.tradeLockSet = encryptData(true, this.tradeSalt) - localStorage.setItem(this.tradeLockScreenSet, this.tradeLockSet) - this.myTradeLockScreenSet = '' - this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt) - this.shadowRoot.getElementById('tradeLockScreenActive').open() - } - - tradePassKeyListener(e) { - if (e.key === 'Enter') { - this.closeTradeLockScreenActive() - } - } - - async closeTradeLockScreenActive() { - const myTradePass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt) - const tradeCheckPass = this.shadowRoot.getElementById('tradeUnlockPassword').value - const errDelay = ms => new Promise(res => setTimeout(res, ms)) - - if (tradeCheckPass === myTradePass) { - this.tradeLockSet = '' - this.tradeLockSet = encryptData(false, this.tradeSalt) - localStorage.setItem(this.tradeLockScreenSet, this.tradeLockSet) - this.myTradeLockScreenSet = '' - this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt) - this.shadowRoot.getElementById('tradeLockScreenActive').close() - this.shadowRoot.getElementById('tradeUnlockPassword').value = '' - this.tradeHelperMessage = this.renderTradeHelperPass() - } else { - this.shadowRoot.getElementById('tradeUnlockPassword').value = '' - this.tradeHelperMessage = this.renderTradeHelperErr() - await errDelay(3000) - this.tradeHelperMessage = this.renderTradeHelperPass() - - } - } - - renderTradeHelperPass() { - return html`${translate("login.pleaseenter")}` - } - - renderTradeHelperErr() { - return html`${translate("login.lp8")}` - } - - requestTraderInfo(traderAddress) { - let getAddress = traderAddress - const theInfoView = this.shadowRoot.querySelector('trader-info-view') - theInfoView.openTraderInfo(getAddress) - } - - requestTradeInfo(tradeObj) { - let seller = '' - let buyer = '' - let qortAmount = 0 - let foreignAmount = 0 - let ata = '' - let time = 0 - let coin = '' - seller = tradeObj.item.sellerAddress - buyer = tradeObj.item.buyerReceivingAddress - qortAmount = tradeObj.item.qortAmount - foreignAmount = tradeObj.item.foreignAmount - ata = tradeObj.item.atAddress - time = tradeObj.item.tradeTimestamp - coin = this.listedCoins.get(this.selectedCoin).coinCode - const theTradeInfoView = this.shadowRoot.querySelector('trade-info-view') - theTradeInfoView.openTradeInfo(seller, buyer, qortAmount, foreignAmount, ata, time, coin) - } - - changeTheme() { - const checkTheme = localStorage.getItem('qortalTheme') - this.theme = (checkTheme === 'dark') ? 'dark' : 'light' - document.querySelector('html').setAttribute('theme', this.theme); - } - - changeLanguage() { - const checkLanguage = localStorage.getItem('qortalLanguage') - - if (checkLanguage === null || checkLanguage.length === 0) { - localStorage.setItem('qortalLanguage', 'us') - use('us') - } else { - use(checkLanguage) - } - } - - renderFetchText() { - return html`${translate("walletpage.wchange1")}` - } - - renderWarning() { - return html`NOT ENOUGH ${this.listedCoins.get(this.selectedCoin).coinCode}` - } - - chartShowCoin() { - switch(this.listedCoins.get(this.selectedCoin).coinCode) { - case "BTC": - return html` chartsbtc.open()}>` - break - case "LTC": - return html` chartsltc.open()}>` - break - case "DOGE": - return html` chartsdoge.open()}>` - break - case "DGB": - return html` chartsdgb.open()}>` - break - case "RVN": - return html` chartsrvn.open()}>` - break - case "ARRR": - return html` chartsarrr.open()}>` - break - default: - break - } - } - - exchangeRateQort() { - switch(this.listedCoins.get(this.selectedCoin).coinCode) { - case "BTC": - this.qortRatio = this.qortbtc - break - case "LTC": - this.qortRatio = this.qortltc - break - case "DOGE": - this.qortRatio = this.qortdoge - break - case "DGB": - this.qortRatio = this.qortdgb - break - case "RVN": - this.qortRatio = this.qortrvn - break - case "ARRR": - this.qortRatio = this.qortarrr - break - default: - break - } - return html`${this.qortRatio}` - } - - exchangeRateForeign() { - if (this.listedCoins.get(this.selectedCoin).coinCode === "BTC") { - parentEpml.request('apiCall', { - url: `/crosschain/price/BITCOIN?inverse=false` - }).then((res) => { - this.btcqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.btcqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "LTC") { - parentEpml.request('apiCall', { - url: `/crosschain/price/LITECOIN?inverse=false` - }).then((res) => { - this.ltcqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.ltcqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "DOGE") { - parentEpml.request('apiCall', { - url: `/crosschain/price/DOGECOIN?inverse=false` - }).then((res) => { - this.dogeqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.dogeqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "DGB") { - parentEpml.request('apiCall', { - url: `/crosschain/price/DIGIBYTE?inverse=false` - }).then((res) => { - this.dgbqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.dgbqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "RVN") { - parentEpml.request('apiCall', { - url: `/crosschain/price/RAVENCOIN?inverse=false` - }).then((res) => { - this.rvnqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.rvnqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "ARRR") { - parentEpml.request('apiCall', { - url: `/crosschain/price/PIRATECHAIN?inverse=false` - }).then((res) => { - this.arrrqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.arrrqort}` - } - } - - async updateWalletBalance() { - let _url = `` - let _body = null - - switch (this.selectedCoin) { - case 'BITCOIN': - _url = `/crosschain/btc/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.derivedMasterPublicKey - break - case 'LITECOIN': - _url = `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey - break - case 'DOGECOIN': - _url = `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey - break - case 'DIGIBYTE': - _url = `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey - break - case 'RAVENCOIN': - _url = `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey - break - case 'PIRATECHAIN': - _url = `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58 - break - default: - break - } - - this.showGetWalletBance = true - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.listedCoins.get(this.selectedCoin).balance = (Number(res) / 1e8).toFixed(8) - } - }) - - this.showGetWalletBance = false - } - - async fetchWalletAddress(coin) { - switch (coin) { - case 'PIRATECHAIN': - let res = await parentEpml.request('apiCall', { - url: `/crosschain/arrr/walletaddress?apiKey=${this.getApiKey()}`, - method: 'POST', - body: `${window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58}`, - }) - if (res != null && res.error != 1201) { - this.arrrWalletAddress = res - } - break - - default: - // Not used for other coins yet - break - } - } - - async setForeignCoin(coin,beingInitialized) { - let _this = this - this.selectedCoin = coin - - let coinSelectionMenu=this.shadowRoot.getElementById("coinSelectionMenu") - - if(beingInitialized){ - coinSelectionMenu.shadowRoot.querySelector('.mdc-select--outlined .mdc-select__anchor').setAttribute('style', 'padding-left: 60px;') - let pairIconContainer = document.createElement("span") - let pairicon = (_this.listedCoins.get(_this.selectedCoin).coinCode).toLowerCase() - pairIconContainer.setAttribute("class","pairIconContainer") - pairIconContainer.setAttribute('style', 'left: 10px;top: 50%;transform: translate(0, -50%);height: 26px;width: 45px;position: absolute;background-repeat: no-repeat;background-size: cover;background-image: url(/img/qort'+pairicon+'.png);') - coinSelectionMenu.shadowRoot.querySelector('.mdc-select--outlined .mdc-select__anchor').appendChild(pairIconContainer) - }else{ - let pairIconContainer = coinSelectionMenu.shadowRoot.querySelector(".mdc-select--outlined .mdc-select__anchor span.pairIconContainer") - let pairicon = (_this.listedCoins.get(_this.selectedCoin).coinCode).toLowerCase() - pairIconContainer.style.backgroundImage='url(/img/qort'+pairicon+'.png)' - } - - this.isLoadingHistoricTrades = true - this.isLoadingOpenTrades = true - this.createConnection() - this._openOrdersGrid.querySelector('#priceColumn').headerRenderer = function (root) { - const priceString2 = get("tradepage.tchange9") - root.innerHTML = '' + priceString2 + ' (' + _this.listedCoins.get(_this.selectedCoin).coinCode + ')' - } - this.clearSellForm() - this.clearBuyForm() - await this.updateWalletBalance() - await this.fetchWalletAddress(coin) - } - - displayTabContent(tab) { - const tabPane = this.shadowRoot.getElementById("tabs-1") - tabPane.setAttribute("activeIndex", (tab === 'buy') ? '0': '1') - - const tabBuyContent = this.shadowRoot.getElementById('tab-buy-content') - tabBuyContent.style.display = (tab === 'buy') ? 'block' : 'none' - - const tabSellContent = this.shadowRoot.getElementById('tab-sell-content') - tabSellContent.style.display = (tab === 'sell') ? 'block' : 'none' - } - - setDefaultSellPrice() { - this.displayTabContent('sell') - const tabSellPrice = this.shadowRoot.getElementById('sellPriceInput') - tabSellPrice.value = this.qortRatio.isNaN ? 0 : this.qortRatio - } - - async reRenderHistoricTrades() { - this.requestUpdate() - await this.updateComplete - this.isLoadingHistoricTrades = false - } - - async reRenderOpenFilteredOrders() { - this.requestUpdate() - await this.updateComplete - this.isLoadingOpenTrades = false - } - - async reRenderMyOpenOrders() { - this.requestUpdate() - await this.updateComplete - this.isLoadingMyOpenOrders = false - } - - fillBuyForm(sellerRequest) { - this.shadowRoot.getElementById('buyAmountInput').value = parseFloat(sellerRequest.item.qortAmount) - this.shadowRoot.getElementById('buyPriceInput').value = this.round(parseFloat(sellerRequest.item.foreignAmount) / parseFloat(sellerRequest.item.qortAmount)) - this.shadowRoot.getElementById('buyTotalInput').value = parseFloat(sellerRequest.item.foreignAmount) - this.shadowRoot.getElementById('qortalAtAddress').value = sellerRequest.item.qortalAtAddress - const buyFunds = this.round(parseFloat(sellerRequest.item.foreignAmount)) - const haveFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(haveFunds) > Number(buyFunds)) { - this.buyBtnDisable = false - this.autoBuyWarning = false - this.displayTabContent('buy') - } else { - this.buyBtnDisable = true - this.autoBuyWarning = true - this.displayTabContent('buy') - } - - } - - processOfferingTrade(offer) { - try { - if(this.listedCoins.get(offer.foreignBlockchain).name!='') { - const offerItem = { - ...offer, - qortAmount: parseFloat(offer.qortAmount), - price: parseFloat(offer.foreignAmount) / parseFloat(offer.qortAmount), - } - const addOffer = () => { - this.listedCoins.get(offer.foreignBlockchain).openOrders.unshift(offerItem) - } - const initOffer = () => { - this.listedCoins.get(offer.foreignBlockchain).openOrders.push(offerItem) - } - this.listedCoins.get(offer.foreignBlockchain).openOrders.length === 0 ? initOffer() : addOffer() - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null - } - } catch(e) { - console.log("Error adding offer from "+offer.foreignBlockchain) - } - } - - processRedeemedTrade(offer) { - try { - if (this.listedCoins.get(offer.foreignBlockchain).name!='') { - - if (offer.qortalCreator === this.selectedAddress.address) { - if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - const offerItem = { - ...offer, - mode: 'SOLD', - } - this._myHistoricTradesGrid.items.unshift(offerItem) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null - } else if (offer.partnerQortalReceivingAddress === this.selectedAddress.address) { - if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - const offerItem = { - ...offer, - mode: 'BOUGHT', - } - this._myHistoricTradesGrid.items.unshift(offerItem) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null - } - const addNewHistoricTrade = () => { - this._historicTradesGrid.items.unshift(offer) - this._historicTradesGrid.clearCache() - } - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? addNewHistoricTrade() : null - - } - } catch(e) { - console.log("Error processing redeemed trade offer from "+offer.foreignBlockchain) - } - } - - processTradingTrade(offer) { - try { - if (this.listedCoins.get(offer.foreignBlockchain).name!='') { - - if (offer.qortalCreator === this.selectedAddress.address && this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - this._openOrdersGrid.items.forEach((item, index) => { - if (item.qortalAtAddress === offer.qortalAtAddress) { - this._openOrdersGrid.items.splice(index, 1) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null - } - }) - this.listedCoins.get(offer.foreignBlockchain).openOrders = this.listedCoins.get(offer.foreignBlockchain).openOrders.filter((order) => order.qortalAtAddress !== offer.qortalAtAddress) - } - } catch(e) { - console.log("Error processing trading trade offer from "+offer.foreignBlockchain) - } - } - - processRefundedTrade(offer) { - try { - if (this.listedCoins.get(offer.foreignBlockchain).name!='') { - - if (offer.qortalCreator === this.selectedAddress.address) { - if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - this._myHistoricTradesGrid.items.unshift(offer) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null - } - - } - } catch(e) { - console.log("Error processing refunded trade offer from "+offer.foreignBlockchain) - } - } - - processCancelledTrade(offer) { - try { - if (this.listedCoins.get(offer.foreignBlockchain).name!='') { - - if (offer.qortalCreator === this.selectedAddress.address) { - if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - this._myHistoricTradesGrid.items.unshift(offer) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null - } - this._openOrdersGrid.items.forEach((item, index) => { - if (item.qortalAtAddress === offer.qortalAtAddress) { - this._openOrdersGrid.items.splice(index, 1) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null - } - }) - this.listedCoins.get(offer.foreignBlockchain).openOrders = this.listedCoins.get(offer.foreignBlockchain).openOrders.filter((order) => order.qortalAtAddress !== offer.qortalAtAddress) - this._stuckOrdersGrid.items.forEach((item, index) => { - if (item.qortalAtAddress === offer.qortalAtAddress) { - this._stuckOrdersGrid.items.splice(index, 1) - this._stuckOrdersGrid.clearCache() - } - }) - } - } catch(e) { - console.log("Error processing cancelled trade offer from "+offer.foreignBlockchain) - } - } - - /** - * TRADE OFFER STATES or MODE - * - OFFERING - * - REDEEMED - * - TRADING - * - REFUNDED - * - CANCELLED - */ - - processTradeOffers(offers) { - offers.forEach((offer) => { - if (offer.mode === 'OFFERING') { - this.processOfferingTrade(offer) - } else if (offer.mode === 'REDEEMED') { - this.processRedeemedTrade(offer) - } else if (offer.mode === 'TRADING') { - this.processTradingTrade(offer) - } else if (offer.mode === 'REFUNDED') { - this.processRefundedTrade(offer) - } else if (offer.mode === 'CANCELLED') { - this.processCancelledTrade(offer) - } - }) - } - - /** - * TradeBot Note by cat - * - * trade-bot entry states: - * - when you do /crosschain/tradebot/create, - * - it returns unsigned DEPLOY_AT for you to sign & broadcast - * - so initial trade-bot state is BOB_WAITING_FOR_AT_CONFIRM, because trade-bot is waiting for UI to sign & broadcast txn and for that txn to be confirmed into a block - * - once that happens & Bob's trade-bot notices that DEPLOY_AT has confirmed (and hence AT created and running), then it switches to BOB_WAITING_FOR_MESSAGE - * - which is Bob's trade-bot waiting for a message from Alice's trade-bot telling it (Bob's trade-bot) that Alice's trade-bot has funded P2SH-A and some other details - * - when that message is sent, Bob's trade-bot processes that message and sends its own message to the AT (which switches it to TRADING mode) - * - but the next state for Bob's trade-bot is to wait for Alice to spot AT is locked to her and for her to fund P2SH-B, hence BOB_WAITING_FOR_P2SH_B - * - at this point, Bob's trade-bot finds P2SH-B on the litecoin blockchain and can send secret-B to P2SH-B - * - when this happens, Alice uses secret-B and secret-A to redeem the QORT from the AT, so until Alice does this, Bob's trade-bot state is BOB_WAITING_FOR_AT_REDEEM - * - after Alice redeems QORT from AT, Bob can extract secret-A and capture the actual LTC funds from P2SH-A to his own litecoin account and hence his trade-bot moves to BOB_DONE - * - if anything goes wrong then refunds occur and Bob's trade-bot ends up at BOB_REFUNDED instead - * - I think you can probably guess the corresponding meaning of states for Alice's point of view, but if not I can go through those too? - * - Alice calls /crosschain/tradebot/respond which funds P2SH-A - * - so her trade-bot waits for that to appear in litecoin blockchain, so until then is ALICE_WAITING_FOR_P2SH_A - * - once the P2SH-A funding confirms, Alice's trade-bot can MESSAGE Bob's trade-bot with the details and changes to ALICE_WAITING_FOR_AT_LOCK - * - Bob's AT should then lock to trading with Alice (via those MESSAGEs above) and Alice's trade-bot notices this, (minimally) funds P2SH-B and waits until Bob 'spends' P2SH-B, hence ALICE_WATCH_P2SH_B - * - if Bob spends P2SH-B, then Alice can send secret-B and secret-A to the AT, claim the QORT and she's ALICE_DONE - * - if something goes wrong then her trade-bot needs to refund P2SH-B (if applicable) first (ALICE_REFUNDING_B) - * - and when that's done refund P2SH-A (ALICE_REFUNDING_A) - * - and when that's done her trade-bot ends up at ALICE_REFUNDED - * - * (PHEW) - */ - - processTradeBotStates(tradeStates) { - - /** - * BitcoinACCTv1 TRADEBOT STATES - * - BOB_WAITING_FOR_AT_CONFIRM - * - BOB_WAITING_FOR_MESSAGE - * - BOB_WAITING_FOR_AT_REDEEM - * - BOB_DONE - * - BOB_REFUNDED - * - ALICE_WAITING_FOR_AT_LOCK - * - ALICE_DONE - * - ALICE_REFUNDING_A - * - ALICE_REFUNDED - * - * @param {[{}]} states - */ - - const BitcoinACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { - this.changeTradeBotState(state, 'PENDING') - } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { - this.changeTradeBotState(state, 'LISTED') - } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { - this.changeTradeBotState(state, 'TRADING') - } else if (state.tradeState == 'BOB_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'BOB_REFUNDED') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - /** - * LitecoinACCTv1 TRADEBOT STATES - * - BOB_WAITING_FOR_AT_CONFIRM - * - BOB_WAITING_FOR_MESSAGE - * - BOB_WAITING_FOR_AT_REDEEM - * - BOB_DONE - * - BOB_REFUNDED - * - ALICE_WAITING_FOR_AT_LOCK - * - ALICE_DONE - * - ALICE_REFUNDING_A - * - ALICE_REFUNDED - * - * @param {[{}]} states - */ - - const LitecoinACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { - this.changeTradeBotState(state, 'PENDING') - } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { - this.changeTradeBotState(state, 'LISTED') - } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { - this.changeTradeBotState(state, 'TRADING') - } else if (state.tradeState == 'BOB_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'BOB_REFUNDED') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - /** - * DogecoinACCTv1 TRADEBOT STATES - * - BOB_WAITING_FOR_AT_CONFIRM - * - BOB_WAITING_FOR_MESSAGE - * - BOB_WAITING_FOR_AT_REDEEM - * - BOB_DONE - * - BOB_REFUNDED - * - ALICE_WAITING_FOR_AT_LOCK - * - ALICE_DONE - * - ALICE_REFUNDING_A - * - ALICE_REFUNDED - * - * @param {[{}]} states - */ - - const DogecoinACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { - this.changeTradeBotState(state, 'PENDING') - } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { - this.changeTradeBotState(state, 'LISTED') - } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { - this.changeTradeBotState(state, 'TRADING') - } else if (state.tradeState == 'BOB_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'BOB_REFUNDED') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - /** - * DigibyteACCTv1 TRADEBOT STATES - * - BOB_WAITING_FOR_AT_CONFIRM - * - BOB_WAITING_FOR_MESSAGE - * - BOB_WAITING_FOR_AT_REDEEM - * - BOB_DONE - * - BOB_REFUNDED - * - ALICE_WAITING_FOR_AT_LOCK - * - ALICE_DONE - * - ALICE_REFUNDING_A - * - ALICE_REFUNDED - * - * @param {[{}]} states - */ - - const DigibyteACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { - this.changeTradeBotState(state, 'PENDING') - } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { - this.changeTradeBotState(state, 'LISTED') - } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { - this.changeTradeBotState(state, 'TRADING') - } else if (state.tradeState == 'BOB_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'BOB_REFUNDED') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - /** - * RavencoinACCTv1 TRADEBOT STATES - * - BOB_WAITING_FOR_AT_CONFIRM - * - BOB_WAITING_FOR_MESSAGE - * - BOB_WAITING_FOR_AT_REDEEM - * - BOB_DONE - * - BOB_REFUNDED - * - ALICE_WAITING_FOR_AT_LOCK - * - ALICE_DONE - * - ALICE_REFUNDING_A - * - ALICE_REFUNDED - * - * @param {[{}]} states - */ - - const RavencoinACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { - this.changeTradeBotState(state, 'PENDING') - } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { - this.changeTradeBotState(state, 'LISTED') - } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { - this.changeTradeBotState(state, 'TRADING') - } else if (state.tradeState == 'BOB_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'BOB_REFUNDED') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - /** - * PirateChainACCTv1 TRADEBOT STATES - * - BOB_WAITING_FOR_AT_CONFIRM - * - BOB_WAITING_FOR_MESSAGE - * - BOB_WAITING_FOR_AT_REDEEM - * - BOB_DONE - * - BOB_REFUNDED - * - ALICE_WAITING_FOR_AT_LOCK - * - ALICE_DONE - * - ALICE_REFUNDING_A - * - ALICE_REFUNDED - * - * @param {[{}]} states - */ - - const PirateChainACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { - this.changeTradeBotState(state, 'PENDING') - } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { - this.changeTradeBotState(state, 'LISTED') - } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { - this.changeTradeBotState(state, 'TRADING') - } else if (state.tradeState == 'BOB_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'BOB_REFUNDED') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - switch (this.selectedCoin) { - case 'BITCOIN': - BitcoinACCTv1(tradeStates) - break - case 'LITECOIN': - LitecoinACCTv1(tradeStates) - break - case 'DOGECOIN': - DogecoinACCTv1(tradeStates) - break - case 'DIGIBYTE': - DigibyteACCTv1(tradeStates) - break - case 'RAVENCOIN': - RavencoinACCTv1(tradeStates) - break - case 'PIRATECHAIN': - PirateChainACCTv1(tradeStates) - break - default: - break - } - if (this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter === 1) { - setTimeout(() => this.filterStuckTrades(tradeStates), 250) - } - } - - changeTradeBotState(state, tradeState) { - this.isLoadingMyOpenOrders = true - const stateItem = { - ...state, - _tradeState: tradeState, - } - const item = this._myOrdersGrid.querySelector(`#${state.atAddress}`) - const addStateItem = () => { - this.reRenderMyOpenOrders() - this._myOrdersGrid.items.unshift(stateItem) - this._myOrdersGrid.clearCache() - } - const updateStateItem = () => { - this._myOrdersGrid.items.forEach((item, index) => { - if (item.atAddress === state.atAddress) { - this.reRenderMyOpenOrders() - this._myOrdersGrid.items.splice(index, 1) - this._myOrdersGrid.items.unshift(stateItem) - this._myOrdersGrid.clearCache() - } - }) - } - item ? updateStateItem() : addStateItem() - } - - handleCompletedState(state) { - this._myOrdersGrid.items.forEach((item, index) => { - if (item.atAddress === state.atAddress) { - this.reRenderMyOpenOrders() - this._myOrdersGrid.items.splice(index, 1) - this._myOrdersGrid.clearCache() - } - }) - } - - initSocket() { - let _relatedCoin = "" - let tradePresenceTxns = null - let offeringTrades = null - - self.addEventListener('message', function (event) { - switch (event.data.type) { - case 'open_orders': - offeringTrades = event.data.content - processOffersWithPresence() - break - case 'set_coin': - _relatedCoin = event.data.content - break - default: - break - } - }) - - const lessThanThirtyMinsAgo = (timestamp) => { - const THIRTYMINS = 1000 * 60 * 30 - const thirtyMinsAgo = Date.now() - THIRTYMINS - return timestamp > thirtyMinsAgo - } - - const filterOffersUsingTradePresence = (offeringTrade) => { - return offeringTrade.tradePresenceExpiry > Date.now(); - } - - const processOffersWithPresence = () => { - if (offeringTrades === null) return - - async function asyncForEach(array, callback) { - for (let index = 0; index < array.length; index++) { - await callback(array[index], index, array) - } - } - - const startOfferPresenceMapping = async () => { - - if (tradePresenceTxns !== null) { - await asyncForEach(tradePresenceTxns, async (tradePresence) => { - let offerIndex = offeringTrades.findIndex((offeringTrade) => offeringTrade.qortalCreatorTradeAddress === tradePresence.tradeAddress) - offerIndex !== -1 ? (offeringTrades[offerIndex].tradePresenceExpiry = tradePresence.timestamp) : null - }) - } - - let filteredOffers = offeringTrades.filter((offeringTrade) => filterOffersUsingTradePresence(offeringTrade)) - self.postMessage({ type: 'PRESENCE', data: { offers: offeringTrades, filteredOffers: filteredOffers, relatedCoin: _relatedCoin } }) - } - - startOfferPresenceMapping() - } - - const initTradeOffersWebSocket = (restarted = false) => { - let tradeOffersSocketCounter = 0 - let socketTimeout - let socketLink = `ws://NODEURL/websockets/crosschain/tradeoffers?foreignBlockchain=FOREIGN_BLOCKCHAIN&includeHistoric=true` - const socket = new WebSocket(socketLink) - socket.onopen = () => { - setTimeout(pingSocket, 50) - tradeOffersSocketCounter += 1 - } - socket.onmessage = (e) => { - e.relatedCoin = _relatedCoin - self.postMessage({ - type: 'TRADE_OFFERS', - data: e.data, - counter: tradeOffersSocketCounter, - isRestarted: restarted, - }) - tradeOffersSocketCounter += 1 - restarted = false - } - socket.onclose = () => { - clearTimeout(socketTimeout) - restartTradeOffersWebSocket() - } - socket.onerror = (e) => { - clearTimeout(socketTimeout) - } - const pingSocket = () => { - socket.send('ping') - socketTimeout = setTimeout(pingSocket, 295000) - } - } - - const initTradeBotWebSocket = (restarted = false) => { - let socketTimeout - let socketLink = `ws://NODEURL/websockets/crosschain/tradebot?foreignBlockchain=FOREIGN_BLOCKCHAIN` - const socket = new WebSocket(socketLink) - socket.onopen = () => { - setTimeout(pingSocket, 50) - } - socket.onmessage = (e) => { - e.relatedCoin = _relatedCoin - self.postMessage({ - type: 'TRADE_BOT', - data: e.data, - isRestarted: restarted, - }) - restarted = false - } - socket.onclose = () => { - clearTimeout(socketTimeout) - restartTradeBotWebSocket() - } - socket.onerror = (e) => { - clearTimeout(socketTimeout) - } - const pingSocket = () => { - socket.send('ping') - socketTimeout = setTimeout(pingSocket, 295000) - } - } - - const initTradePresenceWebSocket = (restarted = false) => { - let socketTimeout - let socketLink = `ws://NODEURL/websockets/crosschain/tradepresence` - const socket = new WebSocket(socketLink) - socket.onopen = () => { - setTimeout(pingSocket, 50) - } - socket.onmessage = (e) => { - tradePresenceTxns = JSON.parse(e.data) - processOffersWithPresence() - restarted = false - } - socket.onclose = () => { - clearTimeout(socketTimeout) - restartTradePresenceWebSocket() - } - socket.onerror = (e) => { - clearTimeout(socketTimeout) - } - const pingSocket = () => { - socket.send('ping') - socketTimeout = setTimeout(pingSocket, 295000) - } - } - - const restartTradePresenceWebSocket = () => { - setTimeout(() => initTradePresenceWebSocket(true), 50) - } - - const restartTradeOffersWebSocket = () => { - setTimeout(() => initTradeOffersWebSocket(true), 50) - } - - const restartTradeBotWebSocket = () => { - setTimeout(() => initTradeBotWebSocket(true), 50) - } - - initTradeOffersWebSocket() - initTradePresenceWebSocket() - initTradeBotWebSocket() - } - - async sellAction() { - this.isSellLoading = true - this.sellBtnDisable = true - await this.tradeFee() - const sellAmountInput = this.shadowRoot.getElementById('sellAmountInput').value - const sellTotalInput = this.shadowRoot.getElementById('sellTotalInput').value - const fundingQortAmount = this.round(parseFloat(sellAmountInput) + 0.001) - - const makeRequest = async () => { - let _receivingAddress = null - switch (this.selectedCoin) { - case 'BITCOIN': - _receivingAddress = this.selectedAddress.btcWallet.address - break - case 'LITECOIN': - _receivingAddress = this.selectedAddress.ltcWallet.address - break - case 'DOGECOIN': - _receivingAddress = this.selectedAddress.dogeWallet.address - break - case 'DIGIBYTE': - _receivingAddress = this.selectedAddress.dgbWallet.address - break - case 'RAVENCOIN': - _receivingAddress = this.selectedAddress.rvnWallet.address - break - case 'PIRATECHAIN': - _receivingAddress = this.arrrWalletAddress - break - default: - break - } + ` + } + + pingCoinBalancesController() { + if (!this.selectedCoin) return + let coin = '' + switch (this.selectedCoin) { + case 'BITCOIN': + coin = 'btc' + break + case 'LITECOIN': + coin = 'ltc' + break + case 'DOGECOIN': + coin = 'doge' + break + case 'DIGIBYTE': + coin = 'dgb' + break + case 'RAVENCOIN': + coin = 'rvn' + break + case 'PIRATECHAIN': + coin = 'arrr' + break + default: + break + } + const customEvent = new CustomEvent('ping-coin-controller-with-coin', { detail: coin }) + window.parent.dispatchEvent(customEvent) + } + + connectedCallback() { + super.connectedCallback() + this.intervalID = setInterval(this.pingCoinBalancesController, 30000) + } + + disconnectedCallback() { + super.disconnectedCallback() + if (this.intervalID) { + clearInterval(this.intervalID) + } + } + + clearConsole() { + if (!isElectron()) { + } else { + console.clear() + window.parent.electronAPI.clearCache() + } + } + + renderTradeLockButton() { + if (this.myTradeLockScreenPass === false && this.myTradeLockScreenSet === false) { + return html` +
    + this.openTradeSetScreenLockPass()} title="${translate("login.lp11")}"> +
    + ` + } else if (this.myTradeLockScreenSet === false) { + return html` +
    + this.setTradeLockQortal()} title="${translate("login.lp11")}"> +
    + ` + } else if (this.myTradeLockScreenSet === true) { + return html` +
    + +
    + ` + } + } + + openTradeSetScreenLockPass() { + this.shadowRoot.getElementById('tradeLockPassword').value = '' + this.shadowRoot.getElementById('tradeLockPasswordConfirm').value = '' + this.shadowRoot.getElementById('setTradeLockScreenPass').open() + } + + closewTradeSetScreenLockPass() { + this.shadowRoot.getElementById('setTradeLockScreenPass').close() + } + + tradeCheckPass() { + const tradePassword = this.shadowRoot.getElementById('tradeLockPassword').value + const tradeRePassword = this.shadowRoot.getElementById('tradeLockPasswordConfirm').value + + if (tradePassword === '') { + let snackbar1string = get("login.pleaseenter") + parentEpml.request('showSnackBar', `${snackbar1string}`) + return + } + + if (tradePassword != tradeRePassword) { + let snackbar2string = get("login.notmatch") + parentEpml.request('showSnackBar', `${snackbar2string}`) + return + } + + if (tradePassword.length < 8) { + let snackbar3string = get("login.lessthen8") + parentEpml.request('showSnackBar', `${snackbar3string}`) + this.tradeExtraConfirm() + } + + if (tradePassword.length >= 8) { + this.setTradeNewScreenPass() + let snackbar4string = get("login.lp6") + parentEpml.request('showSnackBar', `${snackbar4string}`) + } + } + + tradeExtraConfirm() { + this.shadowRoot.getElementById('setTradeLockScreenPass').close() + this.shadowRoot.getElementById('tradeExtraConfirmPass').open() + } + + closTradeExtraConfirmPass() { + this.shadowRoot.getElementById('tradeExtraConfirmPass').close() + this.shadowRoot.getElementById('tradeLockPassword').value = '' + this.shadowRoot.getElementById('tradeLockPasswordConfirm').value = '' + } + + setTradeNewScreenPass() { + const tradeRawPassword = this.shadowRoot.getElementById('tradeLockPassword').value + const tradeCryptPassword = encryptData(tradeRawPassword, this.tradeSalt) + localStorage.setItem(this.tradeLockScreenPass, tradeCryptPassword) + this.myTradeLockScreenPass = '' + this.myTradeLockScreenPass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt) + this.shadowRoot.getElementById('setTradeLockScreenPass').close() + this.shadowRoot.getElementById('tradeExtraConfirmPass').close() + this.shadowRoot.getElementById('tradeLockPassword').value = '' + this.shadowRoot.getElementById('tradeLockPasswordConfirm').value = '' + } + + setTradeLockQortal() { + this.tradeHelperMessage = this.renderTradeHelperPass() + this.tradeLockSet = '' + this.tradeLockSet = encryptData(true, this.tradeSalt) + localStorage.setItem(this.tradeLockScreenSet, this.tradeLockSet) + this.myTradeLockScreenSet = '' + this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt) + this.shadowRoot.getElementById('tradeLockScreenActive').open() + } + + tradePassKeyListener(e) { + if (e.key === 'Enter') { + this.closeTradeLockScreenActive() + } + } + + async closeTradeLockScreenActive() { + const myTradePass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt) + const tradeCheckPass = this.shadowRoot.getElementById('tradeUnlockPassword').value + const errDelay = ms => new Promise(res => setTimeout(res, ms)) + + if (tradeCheckPass === myTradePass) { + this.tradeLockSet = '' + this.tradeLockSet = encryptData(false, this.tradeSalt) + localStorage.setItem(this.tradeLockScreenSet, this.tradeLockSet) + this.myTradeLockScreenSet = '' + this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt) + this.shadowRoot.getElementById('tradeLockScreenActive').close() + this.shadowRoot.getElementById('tradeUnlockPassword').value = '' + this.tradeHelperMessage = this.renderTradeHelperPass() + } else { + this.shadowRoot.getElementById('tradeUnlockPassword').value = '' + this.tradeHelperMessage = this.renderTradeHelperErr() + await errDelay(3000) + this.tradeHelperMessage = this.renderTradeHelperPass() + + } + } + + renderTradeHelperPass() { + return html`${translate("login.pleaseenter")}` + } + + renderTradeHelperErr() { + return html`${translate("login.lp8")}` + } + + requestTraderInfo(traderAddress) { + let getAddress = traderAddress + const theInfoView = this.shadowRoot.querySelector('trader-info-view') + theInfoView.openTraderInfo(getAddress) + } + + requestTradeInfo(tradeObj) { + let seller = '' + let buyer = '' + let qortAmount = 0 + let foreignAmount = 0 + let ata = '' + let time = 0 + let coin = '' + seller = tradeObj.item.sellerAddress + buyer = tradeObj.item.buyerReceivingAddress + qortAmount = tradeObj.item.qortAmount + foreignAmount = tradeObj.item.foreignAmount + ata = tradeObj.item.atAddress + time = tradeObj.item.tradeTimestamp + coin = this.listedCoins.get(this.selectedCoin).coinCode + const theTradeInfoView = this.shadowRoot.querySelector('trade-info-view') + theTradeInfoView.openTradeInfo(seller, buyer, qortAmount, foreignAmount, ata, time, coin) + } + + changeTheme() { + const checkTheme = localStorage.getItem('qortalTheme') + this.theme = (checkTheme === 'dark') ? 'dark' : 'light' + document.querySelector('html').setAttribute('theme', this.theme); + } + + changeLanguage() { + const checkLanguage = localStorage.getItem('qortalLanguage') + if (checkLanguage === null || checkLanguage.length === 0) { + localStorage.setItem('qortalLanguage', 'us') + use('us') + } else { + use(checkLanguage) + } + } + + renderFetchText() { + return html`${translate("walletpage.wchange1")}` + } + + renderWarning() { + return html`NOT ENOUGH ${this.listedCoins.get(this.selectedCoin).coinCode}` + } + + chartShowCoin() { + switch (this.listedCoins.get(this.selectedCoin).coinCode) { + case "BTC": + return html` chartsbtc.open()}>` + break + case "LTC": + return html` chartsltc.open()}>` + break + case "DOGE": + return html` chartsdoge.open()}>` + break + case "DGB": + return html` chartsdgb.open()}>` + break + case "RVN": + return html` chartsrvn.open()}>` + break + case "ARRR": + return html` chartsarrr.open()}>` + break + default: + break + } + } + + exchangeRateQort() { + switch (this.listedCoins.get(this.selectedCoin).coinCode) { + case "BTC": + this.qortRatio = this.qortbtc + break + case "LTC": + this.qortRatio = this.qortltc + break + case "DOGE": + this.qortRatio = this.qortdoge + break + case "DGB": + this.qortRatio = this.qortdgb + break + case "RVN": + this.qortRatio = this.qortrvn + break + case "ARRR": + this.qortRatio = this.qortarrr + break + default: + break + } + return html`${this.qortRatio}` + } + + exchangeRateForeign() { + if (this.listedCoins.get(this.selectedCoin).coinCode === "BTC") { + parentEpml.request('apiCall', { + url: `/crosschain/price/BITCOIN?inverse=false` + }).then((res) => { + this.btcqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.btcqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "LTC") { + parentEpml.request('apiCall', { + url: `/crosschain/price/LITECOIN?inverse=false` + }).then((res) => { + this.ltcqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.ltcqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "DOGE") { + parentEpml.request('apiCall', { + url: `/crosschain/price/DOGECOIN?inverse=false` + }).then((res) => { + this.dogeqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.dogeqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "DGB") { + parentEpml.request('apiCall', { + url: `/crosschain/price/DIGIBYTE?inverse=false` + }).then((res) => { + this.dgbqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.dgbqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "RVN") { + parentEpml.request('apiCall', { + url: `/crosschain/price/RAVENCOIN?inverse=false` + }).then((res) => { + this.rvnqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.rvnqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "ARRR") { + parentEpml.request('apiCall', { + url: `/crosschain/price/PIRATECHAIN?inverse=false` + }).then((res) => { + this.arrrqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.arrrqort}` + } + } + + async updateWalletBalance() { + let _url = `` + let _body = null + + switch (this.selectedCoin) { + case 'BITCOIN': + _url = `/crosschain/btc/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.derivedMasterPublicKey + break + case 'LITECOIN': + _url = `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey + break + case 'DOGECOIN': + _url = `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey + break + case 'DIGIBYTE': + _url = `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey + break + case 'RAVENCOIN': + _url = `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey + break + case 'PIRATECHAIN': + _url = `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58 + break + default: + break + } + + this.showGetWalletBance = true + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.listedCoins.get(this.selectedCoin).balance = (Number(res) / 1e8).toFixed(8) + } + }) + + this.showGetWalletBance = false + } + + async fetchWalletAddress(coin) { + switch (coin) { + case 'PIRATECHAIN': + let res = await parentEpml.request('apiCall', { + url: `/crosschain/arrr/walletaddress?apiKey=${this.getApiKey()}`, + method: 'POST', + body: `${window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58}` + }) + if (res != null && res.error != 1201) { + this.arrrWalletAddress = res + } + break + + default: + // Not used for other coins yet + break + } + } + + async setForeignCoin(coin, beingInitialized) { + let _this = this + this.selectedCoin = coin + + let coinSelectionMenu = this.shadowRoot.getElementById("coinSelectionMenu") + + if (beingInitialized) { + coinSelectionMenu.shadowRoot.querySelector('.mdc-select--outlined .mdc-select__anchor').setAttribute('style', 'padding-left: 60px;') + let pairIconContainer = document.createElement("span") + let pairicon = (_this.listedCoins.get(_this.selectedCoin).coinCode).toLowerCase() + pairIconContainer.setAttribute("class", "pairIconContainer") + pairIconContainer.setAttribute('style', 'left: 10px;top: 50%;transform: translate(0, -50%);height: 26px;width: 45px;position: absolute;background-repeat: no-repeat;background-size: cover;background-image: url(/img/qort' + pairicon + '.png);') + coinSelectionMenu.shadowRoot.querySelector('.mdc-select--outlined .mdc-select__anchor').appendChild(pairIconContainer) + } else { + let pairIconContainer = coinSelectionMenu.shadowRoot.querySelector(".mdc-select--outlined .mdc-select__anchor span.pairIconContainer") + let pairicon = (_this.listedCoins.get(_this.selectedCoin).coinCode).toLowerCase() + pairIconContainer.style.backgroundImage = 'url(/img/qort' + pairicon + '.png)' + } + + this.isLoadingHistoricTrades = true + this.isLoadingOpenTrades = true + this.createConnection() + this._openOrdersGrid.querySelector('#priceColumn').headerRenderer = function (root) { + const priceString2 = get("tradepage.tchange9") + root.innerHTML = '' + priceString2 + ' (' + _this.listedCoins.get(_this.selectedCoin).coinCode + ')' + } + this.clearSellForm() + this.clearBuyForm() + await this.updateWalletBalance() + await this.fetchWalletAddress(coin) + } + + displayTabContent(tab) { + const tabPane = this.shadowRoot.getElementById("tabs-1") + tabPane.setAttribute("activeIndex", (tab === 'buy') ? '0' : '1') + + const tabBuyContent = this.shadowRoot.getElementById('tab-buy-content') + tabBuyContent.style.display = (tab === 'buy') ? 'block' : 'none' + + const tabSellContent = this.shadowRoot.getElementById('tab-sell-content') + tabSellContent.style.display = (tab === 'sell') ? 'block' : 'none' + } + + setDefaultSellPrice() { + this.displayTabContent('sell') + const tabSellPrice = this.shadowRoot.getElementById('sellPriceInput') + tabSellPrice.value = this.qortRatio.isNaN ? 0 : this.qortRatio + } + + async reRenderHistoricTrades() { + this.requestUpdate() + await this.updateComplete + this.isLoadingHistoricTrades = false + } + + async reRenderOpenFilteredOrders() { + this.requestUpdate() + await this.updateComplete + this.isLoadingOpenTrades = false + } + + async reRenderMyOpenOrders() { + this.requestUpdate() + await this.updateComplete + this.isLoadingMyOpenOrders = false + } + + fillBuyForm(sellerRequest) { + this.shadowRoot.getElementById('buyAmountInput').value = parseFloat(sellerRequest.item.qortAmount) + this.shadowRoot.getElementById('buyPriceInput').value = this.round(parseFloat(sellerRequest.item.foreignAmount) / parseFloat(sellerRequest.item.qortAmount)) + this.shadowRoot.getElementById('buyTotalInput').value = parseFloat(sellerRequest.item.foreignAmount) + this.shadowRoot.getElementById('qortalAtAddress').value = sellerRequest.item.qortalAtAddress + const buyFunds = this.round(parseFloat(sellerRequest.item.foreignAmount)) + const haveFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(haveFunds) > Number(buyFunds)) { + this.buyBtnDisable = false + this.autoBuyWarning = false + this.displayTabContent('buy') + } else { + this.buyBtnDisable = true + this.autoBuyWarning = true + this.displayTabContent('buy') + } + + } + + processOfferingTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + const offerItem = { + ...offer, + qortAmount: parseFloat(offer.qortAmount), + price: parseFloat(offer.foreignAmount) / parseFloat(offer.qortAmount), + } + const addOffer = () => { + this.listedCoins.get(offer.foreignBlockchain).openOrders.unshift(offerItem) + } + const initOffer = () => { + this.listedCoins.get(offer.foreignBlockchain).openOrders.push(offerItem) + } + this.listedCoins.get(offer.foreignBlockchain).openOrders.length === 0 ? initOffer() : addOffer() + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null + } + } catch (e) { + console.log("Error adding offer from " + offer.foreignBlockchain) + } + } + + processRedeemedTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + + if (offer.qortalCreator === this.selectedAddress.address) { + if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + const offerItem = { + ...offer, + mode: 'SOLD' + } + this._myHistoricTradesGrid.items.unshift(offerItem) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null + } else if (offer.partnerQortalReceivingAddress === this.selectedAddress.address) { + if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + const offerItem = { + ...offer, + mode: 'BOUGHT' + } + this._myHistoricTradesGrid.items.unshift(offerItem) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null + } + const addNewHistoricTrade = () => { + this._historicTradesGrid.items.unshift(offer) + this._historicTradesGrid.clearCache() + } + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? addNewHistoricTrade() : null + + } + } catch (e) { + console.log("Error processing redeemed trade offer from " + offer.foreignBlockchain) + } + } + + processTradingTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + + if (offer.qortalCreator === this.selectedAddress.address && this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + this._openOrdersGrid.items.forEach((item, index) => { + if (item.qortalAtAddress === offer.qortalAtAddress) { + this._openOrdersGrid.items.splice(index, 1) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null + } + }) + this.listedCoins.get(offer.foreignBlockchain).openOrders = this.listedCoins.get(offer.foreignBlockchain).openOrders.filter((order) => order.qortalAtAddress !== offer.qortalAtAddress) + } + } catch (e) { + console.log("Error processing trading trade offer from " + offer.foreignBlockchain) + } + } + + processRefundedTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + + if (offer.qortalCreator === this.selectedAddress.address) { + if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + this._myHistoricTradesGrid.items.unshift(offer) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null + } + + } + } catch (e) { + console.log("Error processing refunded trade offer from " + offer.foreignBlockchain) + } + } + + processCancelledTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + + if (offer.qortalCreator === this.selectedAddress.address) { + if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + this._myHistoricTradesGrid.items.unshift(offer) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null + } + this._openOrdersGrid.items.forEach((item, index) => { + if (item.qortalAtAddress === offer.qortalAtAddress) { + this._openOrdersGrid.items.splice(index, 1) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null + } + }) + this.listedCoins.get(offer.foreignBlockchain).openOrders = this.listedCoins.get(offer.foreignBlockchain).openOrders.filter((order) => order.qortalAtAddress !== offer.qortalAtAddress) + this._stuckOrdersGrid.items.forEach((item, index) => { + if (item.qortalAtAddress === offer.qortalAtAddress) { + this._stuckOrdersGrid.items.splice(index, 1) + this._stuckOrdersGrid.clearCache() + } + }) + } + } catch (e) { + console.log("Error processing cancelled trade offer from " + offer.foreignBlockchain) + } + } + + /** + * TRADE OFFER STATES or MODE + * - OFFERING + * - REDEEMED + * - TRADING + * - REFUNDED + * - CANCELLED + */ + + processTradeOffers(offers) { + offers.forEach((offer) => { + if (offer.mode === 'OFFERING') { + this.processOfferingTrade(offer) + } else if (offer.mode === 'REDEEMED') { + this.processRedeemedTrade(offer) + } else if (offer.mode === 'TRADING') { + this.processTradingTrade(offer) + } else if (offer.mode === 'REFUNDED') { + this.processRefundedTrade(offer) + } else if (offer.mode === 'CANCELLED') { + this.processCancelledTrade(offer) + } + }) + } + + /** + * TradeBot Note by cat + * + * trade-bot entry states: + * - when you do /crosschain/tradebot/create, + * - it returns unsigned DEPLOY_AT for you to sign & broadcast + * - so initial trade-bot state is BOB_WAITING_FOR_AT_CONFIRM, because trade-bot is waiting for UI to sign & broadcast txn and for that txn to be confirmed into a block + * - once that happens & Bob's trade-bot notices that DEPLOY_AT has confirmed (and hence AT created and running), then it switches to BOB_WAITING_FOR_MESSAGE + * - which is Bob's trade-bot waiting for a message from Alice's trade-bot telling it (Bob's trade-bot) that Alice's trade-bot has funded P2SH-A and some other details + * - when that message is sent, Bob's trade-bot processes that message and sends its own message to the AT (which switches it to TRADING mode) + * - but the next state for Bob's trade-bot is to wait for Alice to spot AT is locked to her and for her to fund P2SH-B, hence BOB_WAITING_FOR_P2SH_B + * - at this point, Bob's trade-bot finds P2SH-B on the litecoin blockchain and can send secret-B to P2SH-B + * - when this happens, Alice uses secret-B and secret-A to redeem the QORT from the AT, so until Alice does this, Bob's trade-bot state is BOB_WAITING_FOR_AT_REDEEM + * - after Alice redeems QORT from AT, Bob can extract secret-A and capture the actual LTC funds from P2SH-A to his own litecoin account and hence his trade-bot moves to BOB_DONE + * - if anything goes wrong then refunds occur and Bob's trade-bot ends up at BOB_REFUNDED instead + * - I think you can probably guess the corresponding meaning of states for Alice's point of view, but if not I can go through those too? + * - Alice calls /crosschain/tradebot/respond which funds P2SH-A + * - so her trade-bot waits for that to appear in litecoin blockchain, so until then is ALICE_WAITING_FOR_P2SH_A + * - once the P2SH-A funding confirms, Alice's trade-bot can MESSAGE Bob's trade-bot with the details and changes to ALICE_WAITING_FOR_AT_LOCK + * - Bob's AT should then lock to trading with Alice (via those MESSAGEs above) and Alice's trade-bot notices this, (minimally) funds P2SH-B and waits until Bob 'spends' P2SH-B, hence ALICE_WATCH_P2SH_B + * - if Bob spends P2SH-B, then Alice can send secret-B and secret-A to the AT, claim the QORT and she's ALICE_DONE + * - if something goes wrong then her trade-bot needs to refund P2SH-B (if applicable) first (ALICE_REFUNDING_B) + * - and when that's done refund P2SH-A (ALICE_REFUNDING_A) + * - and when that's done her trade-bot ends up at ALICE_REFUNDED + * + * (PHEW) + */ + + processTradeBotStates(tradeStates) { + + /** + * BitcoinACCTv1 TRADEBOT STATES + * - BOB_WAITING_FOR_AT_CONFIRM + * - BOB_WAITING_FOR_MESSAGE + * - BOB_WAITING_FOR_AT_REDEEM + * - BOB_DONE + * - BOB_REFUNDED + * - ALICE_WAITING_FOR_AT_LOCK + * - ALICE_DONE + * - ALICE_REFUNDING_A + * - ALICE_REFUNDED + * + * @param {[{}]} states + */ + + const BitcoinACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { + this.changeTradeBotState(state, 'PENDING') + } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { + this.changeTradeBotState(state, 'LISTED') + } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { + this.changeTradeBotState(state, 'TRADING') + } else if (state.tradeState == 'BOB_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'BOB_REFUNDED') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + /** + * LitecoinACCTv1 TRADEBOT STATES + * - BOB_WAITING_FOR_AT_CONFIRM + * - BOB_WAITING_FOR_MESSAGE + * - BOB_WAITING_FOR_AT_REDEEM + * - BOB_DONE + * - BOB_REFUNDED + * - ALICE_WAITING_FOR_AT_LOCK + * - ALICE_DONE + * - ALICE_REFUNDING_A + * - ALICE_REFUNDED + * + * @param {[{}]} states + */ + + const LitecoinACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { + this.changeTradeBotState(state, 'PENDING') + } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { + this.changeTradeBotState(state, 'LISTED') + } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { + this.changeTradeBotState(state, 'TRADING') + } else if (state.tradeState == 'BOB_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'BOB_REFUNDED') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + /** + * DogecoinACCTv1 TRADEBOT STATES + * - BOB_WAITING_FOR_AT_CONFIRM + * - BOB_WAITING_FOR_MESSAGE + * - BOB_WAITING_FOR_AT_REDEEM + * - BOB_DONE + * - BOB_REFUNDED + * - ALICE_WAITING_FOR_AT_LOCK + * - ALICE_DONE + * - ALICE_REFUNDING_A + * - ALICE_REFUNDED + * + * @param {[{}]} states + */ + + const DogecoinACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { + this.changeTradeBotState(state, 'PENDING') + } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { + this.changeTradeBotState(state, 'LISTED') + } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { + this.changeTradeBotState(state, 'TRADING') + } else if (state.tradeState == 'BOB_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'BOB_REFUNDED') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + /** + * DigibyteACCTv1 TRADEBOT STATES + * - BOB_WAITING_FOR_AT_CONFIRM + * - BOB_WAITING_FOR_MESSAGE + * - BOB_WAITING_FOR_AT_REDEEM + * - BOB_DONE + * - BOB_REFUNDED + * - ALICE_WAITING_FOR_AT_LOCK + * - ALICE_DONE + * - ALICE_REFUNDING_A + * - ALICE_REFUNDED + * + * @param {[{}]} states + */ + + const DigibyteACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { + this.changeTradeBotState(state, 'PENDING') + } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { + this.changeTradeBotState(state, 'LISTED') + } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { + this.changeTradeBotState(state, 'TRADING') + } else if (state.tradeState == 'BOB_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'BOB_REFUNDED') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + /** + * RavencoinACCTv1 TRADEBOT STATES + * - BOB_WAITING_FOR_AT_CONFIRM + * - BOB_WAITING_FOR_MESSAGE + * - BOB_WAITING_FOR_AT_REDEEM + * - BOB_DONE + * - BOB_REFUNDED + * - ALICE_WAITING_FOR_AT_LOCK + * - ALICE_DONE + * - ALICE_REFUNDING_A + * - ALICE_REFUNDED + * + * @param {[{}]} states + */ + + const RavencoinACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { + this.changeTradeBotState(state, 'PENDING') + } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { + this.changeTradeBotState(state, 'LISTED') + } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { + this.changeTradeBotState(state, 'TRADING') + } else if (state.tradeState == 'BOB_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'BOB_REFUNDED') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + /** + * PirateChainACCTv1 TRADEBOT STATES + * - BOB_WAITING_FOR_AT_CONFIRM + * - BOB_WAITING_FOR_MESSAGE + * - BOB_WAITING_FOR_AT_REDEEM + * - BOB_DONE + * - BOB_REFUNDED + * - ALICE_WAITING_FOR_AT_LOCK + * - ALICE_DONE + * - ALICE_REFUNDING_A + * - ALICE_REFUNDED + * + * @param {[{}]} states + */ + + const PirateChainACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { + this.changeTradeBotState(state, 'PENDING') + } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { + this.changeTradeBotState(state, 'LISTED') + } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { + this.changeTradeBotState(state, 'TRADING') + } else if (state.tradeState == 'BOB_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'BOB_REFUNDED') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + switch (this.selectedCoin) { + case 'BITCOIN': + BitcoinACCTv1(tradeStates) + break + case 'LITECOIN': + LitecoinACCTv1(tradeStates) + break + case 'DOGECOIN': + DogecoinACCTv1(tradeStates) + break + case 'DIGIBYTE': + DigibyteACCTv1(tradeStates) + break + case 'RAVENCOIN': + RavencoinACCTv1(tradeStates) + break + case 'PIRATECHAIN': + PirateChainACCTv1(tradeStates) + break + default: + break + } + if (this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter === 1) { + setTimeout(() => this.filterStuckTrades(tradeStates), 250) + } + } + + changeTradeBotState(state, tradeState) { + this.isLoadingMyOpenOrders = true + const stateItem = { + ...state, + _tradeState: tradeState, + } + const item = this._myOrdersGrid.querySelector(`#${state.atAddress}`) + const addStateItem = () => { + this.reRenderMyOpenOrders() + this._myOrdersGrid.items.unshift(stateItem) + this._myOrdersGrid.clearCache() + } + const updateStateItem = () => { + this._myOrdersGrid.items.forEach((item, index) => { + if (item.atAddress === state.atAddress) { + this.reRenderMyOpenOrders() + this._myOrdersGrid.items.splice(index, 1) + this._myOrdersGrid.items.unshift(stateItem) + this._myOrdersGrid.clearCache() + } + }) + } + item ? updateStateItem() : addStateItem() + } + + handleCompletedState(state) { + this._myOrdersGrid.items.forEach((item, index) => { + if (item.atAddress === state.atAddress) { + this.reRenderMyOpenOrders() + this._myOrdersGrid.items.splice(index, 1) + this._myOrdersGrid.clearCache() + } + }) + } + + initSocket() { + let _relatedCoin = "" + let tradePresenceTxns = null + let offeringTrades = null + + self.addEventListener('message', function (event) { + switch (event.data.type) { + case 'open_orders': + offeringTrades = event.data.content + processOffersWithPresence() + break + case 'set_coin': + _relatedCoin = event.data.content + break + default: + break + } + }) + + const lessThanThirtyMinsAgo = (timestamp) => { + const THIRTYMINS = 1000 * 60 * 30 + const thirtyMinsAgo = Date.now() - THIRTYMINS + return timestamp > thirtyMinsAgo + } + + const filterOffersUsingTradePresence = (offeringTrade) => { + return offeringTrade.tradePresenceExpiry > Date.now(); + } + + const processOffersWithPresence = () => { + if (offeringTrades === null) return + + async function asyncForEach(array, callback) { + for (let index = 0; index < array.length; index++) { + await callback(array[index], index, array) + } + } + + const startOfferPresenceMapping = async () => { + + if (tradePresenceTxns !== null) { + await asyncForEach(tradePresenceTxns, async (tradePresence) => { + let offerIndex = offeringTrades.findIndex((offeringTrade) => offeringTrade.qortalCreatorTradeAddress === tradePresence.tradeAddress) + offerIndex !== -1 ? (offeringTrades[offerIndex].tradePresenceExpiry = tradePresence.timestamp) : null + }) + } + + let filteredOffers = offeringTrades.filter((offeringTrade) => filterOffersUsingTradePresence(offeringTrade)) + self.postMessage({ type: 'PRESENCE', data: { offers: offeringTrades, filteredOffers: filteredOffers, relatedCoin: _relatedCoin } }) + } + + startOfferPresenceMapping() + } + + const initTradeOffersWebSocket = (restarted = false) => { + let tradeOffersSocketCounter = 0 + let socketTimeout + let socketLink = `ws://NODEURL/websockets/crosschain/tradeoffers?foreignBlockchain=FOREIGN_BLOCKCHAIN&includeHistoric=true` + const socket = new WebSocket(socketLink) + socket.onopen = () => { + setTimeout(pingSocket, 50) + tradeOffersSocketCounter += 1 + } + socket.onmessage = (e) => { + e.relatedCoin = _relatedCoin + self.postMessage({ + type: 'TRADE_OFFERS', + data: e.data, + counter: tradeOffersSocketCounter, + isRestarted: restarted, + }) + tradeOffersSocketCounter += 1 + restarted = false + } + socket.onclose = () => { + clearTimeout(socketTimeout) + restartTradeOffersWebSocket() + } + socket.onerror = (e) => { + clearTimeout(socketTimeout) + } + const pingSocket = () => { + socket.send('ping') + socketTimeout = setTimeout(pingSocket, 295000) + } + } + + const initTradeBotWebSocket = (restarted = false) => { + let socketTimeout + let socketLink = `ws://NODEURL/websockets/crosschain/tradebot?foreignBlockchain=FOREIGN_BLOCKCHAIN` + const socket = new WebSocket(socketLink) + socket.onopen = () => { + setTimeout(pingSocket, 50) + } + socket.onmessage = (e) => { + e.relatedCoin = _relatedCoin + self.postMessage({ + type: 'TRADE_BOT', + data: e.data, + isRestarted: restarted, + }) + restarted = false + } + socket.onclose = () => { + clearTimeout(socketTimeout) + restartTradeBotWebSocket() + } + socket.onerror = (e) => { + clearTimeout(socketTimeout) + } + const pingSocket = () => { + socket.send('ping') + socketTimeout = setTimeout(pingSocket, 295000) + } + } + + const initTradePresenceWebSocket = (restarted = false) => { + let socketTimeout + let socketLink = `ws://NODEURL/websockets/crosschain/tradepresence` + const socket = new WebSocket(socketLink) + socket.onopen = () => { + setTimeout(pingSocket, 50) + } + socket.onmessage = (e) => { + tradePresenceTxns = JSON.parse(e.data) + processOffersWithPresence() + restarted = false + } + socket.onclose = () => { + clearTimeout(socketTimeout) + restartTradePresenceWebSocket() + } + socket.onerror = (e) => { + clearTimeout(socketTimeout) + } + const pingSocket = () => { + socket.send('ping') + socketTimeout = setTimeout(pingSocket, 295000) + } + } + + const restartTradePresenceWebSocket = () => { + setTimeout(() => initTradePresenceWebSocket(true), 50) + } + + const restartTradeOffersWebSocket = () => { + setTimeout(() => initTradeOffersWebSocket(true), 50) + } + + const restartTradeBotWebSocket = () => { + setTimeout(() => initTradeBotWebSocket(true), 50) + } + + initTradeOffersWebSocket() + initTradePresenceWebSocket() + initTradeBotWebSocket() + } + + async sellAction() { + this.isSellLoading = true + this.sellBtnDisable = true + await this.tradeFee() + const sellAmountInput = this.shadowRoot.getElementById('sellAmountInput').value + const sellTotalInput = this.shadowRoot.getElementById('sellTotalInput').value + const fundingQortAmount = this.round(parseFloat(sellAmountInput) + 0.001) + + const makeRequest = async () => { + let _receivingAddress = null + switch (this.selectedCoin) { + case 'BITCOIN': + _receivingAddress = this.selectedAddress.btcWallet.address + break + case 'LITECOIN': + _receivingAddress = this.selectedAddress.ltcWallet.address + break + case 'DOGECOIN': + _receivingAddress = this.selectedAddress.dogeWallet.address + break + case 'DIGIBYTE': + _receivingAddress = this.selectedAddress.dgbWallet.address + break + case 'RAVENCOIN': + _receivingAddress = this.selectedAddress.rvnWallet.address + break + case 'PIRATECHAIN': + _receivingAddress = this.arrrWalletAddress + break + default: + break + } return await parentEpml.request('tradeBotCreateRequest', { creatorPublicKey: this.selectedAddress.base58PublicKey, qortAmount: parseFloat(sellAmountInput), @@ -2247,579 +2264,576 @@ class TradePortal extends LitElement { foreignBlockchain: this.selectedCoin, foreignAmount: parseFloat(sellTotalInput), tradeTimeout: 120, - receivingAddress: _receivingAddress, + receivingAddress: _receivingAddress }) - } + } - const manageResponse = (response) => { - if (response === true) { - this.isSellLoading = false - this.sellBtnDisable = false - this.shadowRoot.getElementById('sellAmountInput').value = this.initialAmount - this.shadowRoot.getElementById('sellPriceInput').value = this.initialAmount - this.shadowRoot.getElementById('sellTotalInput').value = this.initialAmount - } else if (response === false) { - this.isSellLoading = false - this.sellBtnDisable = false - let snack2string = get("tradepage.tchange20") - parentEpml.request('showSnackBar', `${snack2string}`) - } else { - this.isSellLoading = false - this.sellBtnDisable = false - let snack3string = get("tradepage.tchange21") - parentEpml.request('showSnackBar', `${snack3string}: ${response.message}`) - } - } + const manageResponse = (response) => { + if (response === true) { + this.isSellLoading = false + this.sellBtnDisable = false + this.shadowRoot.getElementById('sellAmountInput').value = this.initialAmount + this.shadowRoot.getElementById('sellPriceInput').value = this.initialAmount + this.shadowRoot.getElementById('sellTotalInput').value = this.initialAmount + } else if (response === false) { + this.isSellLoading = false + this.sellBtnDisable = false + let snack2string = get("tradepage.tchange20") + parentEpml.request('showSnackBar', `${snack2string}`) + } else { + this.isSellLoading = false + this.sellBtnDisable = false + let snack3string = get("tradepage.tchange21") + parentEpml.request('showSnackBar', `${snack3string}: ${response.message}`) + } + } - if (this.round(parseFloat(fundingQortAmount) + parseFloat(this.listedCoins.get("QORTAL").tradeFee)) > parseFloat(this.listedCoins.get("QORTAL").balance)) { - this.isSellLoading = false - this.sellBtnDisable = false - let snack4string = get("tradepage.tchange22") - parentEpml.request('showSnackBar', `${snack4string}`) - return false - } else { - const res = await makeRequest() - manageResponse(res) - } - } + if (this.round(parseFloat(fundingQortAmount) + parseFloat(this.listedCoins.get("QORTAL").tradeFee)) > parseFloat(this.listedCoins.get("QORTAL").balance)) { + this.isSellLoading = false + this.sellBtnDisable = false + let snack4string = get("tradepage.tchange22") + parentEpml.request('showSnackBar', `${snack4string}`) + return false + } else { + const res = await makeRequest() + manageResponse(res) + } + } - async buyAction() { - this.isBuyLoading = true - this.buyBtnDisable = true - const qortalAtAddress = this.shadowRoot.getElementById('qortalAtAddress').value - let _foreignKey = "" + async buyAction() { + this.isBuyLoading = true + this.buyBtnDisable = true + const qortalAtAddress = this.shadowRoot.getElementById('qortalAtAddress').value + let _foreignKey = "" - switch (this.selectedCoin) { - case 'BITCOIN': - _foreignKey = this.selectedAddress.btcWallet.derivedMasterPrivateKey - break - case 'LITECOIN': - _foreignKey = this.selectedAddress.ltcWallet.derivedMasterPrivateKey - break - case 'DOGECOIN': - _foreignKey = this.selectedAddress.dogeWallet.derivedMasterPrivateKey - break - case 'DIGIBYTE': - _foreignKey = this.selectedAddress.dgbWallet.derivedMasterPrivateKey - break + switch (this.selectedCoin) { + case 'BITCOIN': + _foreignKey = this.selectedAddress.btcWallet.derivedMasterPrivateKey + break + case 'LITECOIN': + _foreignKey = this.selectedAddress.ltcWallet.derivedMasterPrivateKey + break + case 'DOGECOIN': + _foreignKey = this.selectedAddress.dogeWallet.derivedMasterPrivateKey + break + case 'DIGIBYTE': + _foreignKey = this.selectedAddress.dgbWallet.derivedMasterPrivateKey + break case 'RAVENCOIN': - _foreignKey = this.selectedAddress.rvnWallet.derivedMasterPrivateKey - break - case 'PIRATECHAIN': - _foreignKey = this.selectedAddress.arrrWallet.seed58 - break - default: - break - } + _foreignKey = this.selectedAddress.rvnWallet.derivedMasterPrivateKey + break + case 'PIRATECHAIN': + _foreignKey = this.selectedAddress.arrrWallet.seed58 + break + default: + break + } - const makeRequest = async () => { + const makeRequest = async () => { return await parentEpml.request('tradeBotRespondRequest', { atAddress: qortalAtAddress, foreignKey: _foreignKey, - receivingAddress: this.selectedAddress.address, + receivingAddress: this.selectedAddress.address }) - } + } - const manageResponse = (response) => { - if (response === true) { - this.isBuyLoading = false - this.buyBtnDisable = true - this.shadowRoot.getElementById('buyAmountInput').value = this.initialAmount - this.shadowRoot.getElementById('buyPriceInput').value = this.initialAmount - this.shadowRoot.getElementById('buyTotalInput').value = this.initialAmount - this.shadowRoot.getElementById('qortalAtAddress').value = '' - let snack5string = get("tradepage.tchange23") - parentEpml.request('showSnackBar', `${snack5string}`) - } else if (response === false) { - this.isBuyLoading = false - this.buyBtnDisable = false - let snack6string = get("tradepage.tchange24") - parentEpml.request('showSnackBar', `${snack6string}`) - } else { - this.isBuyLoading = false - this.buyBtnDisable = false - let snack7string = get("tradepage.tchange25") - parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) - } - } - const res = await makeRequest() - manageResponse(res) - } + const manageResponse = (response) => { + if (response === true) { + this.isBuyLoading = false + this.buyBtnDisable = true + this.shadowRoot.getElementById('buyAmountInput').value = this.initialAmount + this.shadowRoot.getElementById('buyPriceInput').value = this.initialAmount + this.shadowRoot.getElementById('buyTotalInput').value = this.initialAmount + this.shadowRoot.getElementById('qortalAtAddress').value = '' + let snack5string = get("tradepage.tchange23") + parentEpml.request('showSnackBar', `${snack5string}`) + } else if (response === false) { + this.isBuyLoading = false + this.buyBtnDisable = false + let snack6string = get("tradepage.tchange24") + parentEpml.request('showSnackBar', `${snack6string}`) + } else { + this.isBuyLoading = false + this.buyBtnDisable = false + let snack7string = get("tradepage.tchange25") + parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) + } + } + const res = await makeRequest() + manageResponse(res) + } - async cancelAction(state) { - const button = this.shadowRoot.querySelector(`mwc-button#${state.atAddress}`) - button.innerHTML = `` - this.cancelBtnDisable = true + async cancelAction(state) { + const button = this.shadowRoot.querySelector(`mwc-button#${state.atAddress}`) + button.innerHTML = `` + this.cancelBtnDisable = true - const makeRequest = async () => { + const makeRequest = async () => { return await parentEpml.request('deleteTradeOffer', { creatorPublicKey: this.selectedAddress.base58PublicKey, - atAddress: state.atAddress, + atAddress: state.atAddress }) - } + } - const manageResponse = (response) => { - if (response === true) { - button.remove() - this.cancelBtnDisable = false - let snack8string = get("tradepage.tchange26") - parentEpml.request('showSnackBar', `${snack8string}`) - } else if (response === false) { - button.innerHTML = 'CANCEL' - this.cancelBtnDisable = false - let snack9string = get("tradepage.tchange27") - parentEpml.request('showSnackBar', `${snack9string}`) - } else { - button.innerHTML = 'CANCEL' - this.cancelBtnDisable = false - let snack10string = get("tradepage.tchange28") - parentEpml.request('showSnackBar', `${snack10string}: ${response.message}`) - } - } - const res = await makeRequest() - manageResponse(res) - } + const manageResponse = (response) => { + if (response === true) { + button.remove() + this.cancelBtnDisable = false + let snack8string = get("tradepage.tchange26") + parentEpml.request('showSnackBar', `${snack8string}`) + } else if (response === false) { + button.innerHTML = 'CANCEL' + this.cancelBtnDisable = false + let snack9string = get("tradepage.tchange27") + parentEpml.request('showSnackBar', `${snack9string}`) + } else { + button.innerHTML = 'CANCEL' + this.cancelBtnDisable = false + let snack10string = get("tradepage.tchange28") + parentEpml.request('showSnackBar', `${snack10string}: ${response.message}`) + } + } + const res = await makeRequest() + manageResponse(res) + } - updateAccountBalance() { - clearTimeout(this.updateAccountBalanceTimeout) - parentEpml.request('apiCall', { - url: `/addresses/balance/${this.selectedAddress.address}?apiKey=${this.getApiKey()}`, - }) - .then((res) => { - this.listedCoins.get("QORTAL").balance = res - this.updateAccountBalanceTimeout = setTimeout(() => this.updateAccountBalance(), 10000) - }) - } + updateAccountBalance() { + clearTimeout(this.updateAccountBalanceTimeout) + parentEpml.request('apiCall', { + url: `/addresses/balance/${this.selectedAddress.address}?apiKey=${this.getApiKey()}`, + }).then((res) => { + this.listedCoins.get("QORTAL").balance = res + this.updateAccountBalanceTimeout = setTimeout(() => this.updateAccountBalance(), 10000) + }) + } - renderCancelButton(stateItem) { - if (stateItem.tradeState === 'BOB_WAITING_FOR_MESSAGE') { - return html` this.cancelAction(stateItem)}>${translate("tradepage.tchange29")}` - } else { - return '' - } - } + renderCancelButton(stateItem) { + if (stateItem.tradeState === 'BOB_WAITING_FOR_MESSAGE') { + return html` this.cancelAction(stateItem)}>${translate("tradepage.tchange29")}` + } else { + return '' + } + } - showStuckOrdersDialog() { - this.shadowRoot.querySelector('#manageStuckOrdersDialog').show() - } + showStuckOrdersDialog() { + this.shadowRoot.querySelector('#manageStuckOrdersDialog').show() + } - async cancelStuckOfferAction(offer) { - this.cancelStuckOfferBtnDisable = true + async cancelStuckOfferAction(offer) { + this.cancelStuckOfferBtnDisable = true - const makeRequest = async () => { + const makeRequest = async () => { return await parentEpml.request('deleteTradeOffer', { creatorPublicKey: this.selectedAddress.base58PublicKey, - atAddress: offer.qortalAtAddress, + atAddress: offer.qortalAtAddress }) - } + } - const manageResponse = (response) => { - if (response === true) { - this.cancelStuckOfferBtnDisable = false - let snack11string = get("tradepage.tchange26") - parentEpml.request('showSnackBar', `${snack11string}`) - } else if (response === false) { - this.cancelStuckOfferBtnDisable = false - let snack12string = get("tradepage.tchange27") - parentEpml.request('showSnackBar', `${snack12string}`) - } else { - this.cancelStuckOfferBtnDisable = false - let snack13string = get("tradepage.tchange28") - parentEpml.request('showSnackBar', `${snack13string}: ${response.message}`) - } - } - const res = await makeRequest() - manageResponse(res) - } + const manageResponse = (response) => { + if (response === true) { + this.cancelStuckOfferBtnDisable = false + let snack11string = get("tradepage.tchange26") + parentEpml.request('showSnackBar', `${snack11string}`) + } else if (response === false) { + this.cancelStuckOfferBtnDisable = false + let snack12string = get("tradepage.tchange27") + parentEpml.request('showSnackBar', `${snack12string}`) + } else { + this.cancelStuckOfferBtnDisable = false + let snack13string = get("tradepage.tchange28") + parentEpml.request('showSnackBar', `${snack13string}: ${response.message}`) + } + } + const res = await makeRequest() + manageResponse(res) + } - renderCancelStuckOfferButton(offerItem) { - if (offerItem.mode === 'OFFERING' && offerItem.qortalCreator === this.selectedAddress.address) { - return html` this.cancelStuckOfferAction(offerItem)}>CANCEL` - } else { - return '' - } - } + renderCancelStuckOfferButton(offerItem) { + if (offerItem.mode === 'OFFERING' && offerItem.qortalCreator === this.selectedAddress.address) { + return html` this.cancelStuckOfferAction(offerItem)}>CANCEL` + } else { + return '' + } + } - _checkSellAmount(e) { - const targetAmount = e.target.value - const target = e.target + _checkSellAmount(e) { + const targetAmount = e.target.value + const target = e.target - if (targetAmount.length === 0) { - this.isValidAmount = false - this.sellBtnDisable = true - e.target.blur() - e.target.focus() - e.target.invalid = true - } else { - const sellAmountInput = this.shadowRoot.getElementById('sellAmountInput').value - const sellPriceInput = this.shadowRoot.getElementById('sellPriceInput').value - this.shadowRoot.getElementById('sellTotalInput').value = this.round(parseFloat(sellAmountInput) * parseFloat(sellPriceInput)) - this.sellBtnDisable = false - } + if (targetAmount.length === 0) { + this.isValidAmount = false + this.sellBtnDisable = true + e.target.blur() + e.target.focus() + e.target.invalid = true + } else { + const sellAmountInput = this.shadowRoot.getElementById('sellAmountInput').value + const sellPriceInput = this.shadowRoot.getElementById('sellPriceInput').value + this.shadowRoot.getElementById('sellTotalInput').value = this.round(parseFloat(sellAmountInput) * parseFloat(sellPriceInput)) + this.sellBtnDisable = false + } - e.target.blur() - e.target.focus() + e.target.blur() + e.target.focus() - e.target.validityTransform = (newValue, nativeValidity) => { - if (newValue.includes('-') === true) { - this.sellBtnDisable = true - return { - valid: false, - } - } else if (!nativeValidity.valid) { - if (newValue.includes('.') === true) { - let myAmount = newValue.split('.') - if (myAmount[1].length > 8) { - this.sellBtnDisable = true - } else { - const sellAmountInput = this.shadowRoot.getElementById('sellAmountInput').value - const sellPriceInput = this.shadowRoot.getElementById('sellPriceInput').value - this.shadowRoot.getElementById('sellTotalInput').value = this.round(parseFloat(sellAmountInput) * parseFloat(sellPriceInput)) - this.sellBtnDisable = false - return { - valid: true, - } - } - } - } else { - const sellAmountInput = this.shadowRoot.getElementById('sellAmountInput').value - const sellPriceInput = this.shadowRoot.getElementById('sellPriceInput').value - this.shadowRoot.getElementById('sellTotalInput').value = this.round(parseFloat(sellAmountInput) * parseFloat(sellPriceInput)) - this.sellBtnDisable = false - } - } - } + e.target.validityTransform = (newValue, nativeValidity) => { + if (newValue.includes('-') === true) { + this.sellBtnDisable = true + return { + valid: false + } + } else if (!nativeValidity.valid) { + if (newValue.includes('.') === true) { + let myAmount = newValue.split('.') + if (myAmount[1].length > 8) { + this.sellBtnDisable = true + } else { + const sellAmountInput = this.shadowRoot.getElementById('sellAmountInput').value + const sellPriceInput = this.shadowRoot.getElementById('sellPriceInput').value + this.shadowRoot.getElementById('sellTotalInput').value = this.round(parseFloat(sellAmountInput) * parseFloat(sellPriceInput)) + this.sellBtnDisable = false + return { + valid: true + } + } + } + } else { + const sellAmountInput = this.shadowRoot.getElementById('sellAmountInput').value + const sellPriceInput = this.shadowRoot.getElementById('sellPriceInput').value + this.shadowRoot.getElementById('sellTotalInput').value = this.round(parseFloat(sellAmountInput) * parseFloat(sellPriceInput)) + this.sellBtnDisable = false + } + } + } - _checkBuyAmount(e) { - const targetAmount = e.target.value - const target = e.target + _checkBuyAmount(e) { + const targetAmount = e.target.value + const target = e.target - if (targetAmount.length === 0) { - this.isValidAmount = false - this.sellBtnDisable = true - e.target.blur() - e.target.focus() - e.target.invalid = true - } else { - this.buyBtnDisable = false - } + if (targetAmount.length === 0) { + this.isValidAmount = false + this.sellBtnDisable = true + e.target.blur() + e.target.focus() + e.target.invalid = true + } else { + this.buyBtnDisable = false + } - e.target.blur() - e.target.focus() + e.target.blur() + e.target.focus() - e.target.validityTransform = (newValue, nativeValidity) => { - if (newValue.includes('-') === true) { - this.buyBtnDisable = true - return { - valid: false, - } - } else if (!nativeValidity.valid) { - if (newValue.includes('.') === true) { - let myAmount = newValue.split('.') - if (myAmount[1].length > 8) { - this.buyBtnDisable = true - } else { - this.buyBtnDisable = false - return { - valid: true, - } - } - } - } else { - this.buyBtnDisable = false - } - } - } + e.target.validityTransform = (newValue, nativeValidity) => { + if (newValue.includes('-') === true) { + this.buyBtnDisable = true + return { + valid: false + } + } else if (!nativeValidity.valid) { + if (newValue.includes('.') === true) { + let myAmount = newValue.split('.') + if (myAmount[1].length > 8) { + this.buyBtnDisable = true + } else { + this.buyBtnDisable = false + return { + valid: true + } + } + } + } else { + this.buyBtnDisable = false + } + } + } - async tradeFee() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/transactions/unitfee?txType=DEPLOY_AT` - await fetch(url).then((response) => { - if (response.ok) { - return response.json() - } - return Promise.reject(response) - }).then((json) => { - this.listedCoins.get("QORTAL").tradeFee = (Number(json) * 2) / 1e8 - }) - } + async tradeFee() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/transactions/unitfee?txType=DEPLOY_AT` + await fetch(url).then((response) => { + if (response.ok) { + return response.json() + } + return Promise.reject(response) + }).then((json) => { + this.listedCoins.get("QORTAL").tradeFee = (Number(json) * 2) / 1e8 + }) + } + clearBuyForm() { + this.shadowRoot.getElementById('buyAmountInput').value = this.initialAmount + this.shadowRoot.getElementById('buyPriceInput').value = this.initialAmount + this.shadowRoot.getElementById('buyTotalInput').value = this.initialAmount + this.shadowRoot.getElementById('qortalAtAddress').value = '' + this.buyBtnDisable = true + } - getApiKey() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; - return myNode.apiKey; - } + clearSellForm() { + this.shadowRoot.getElementById('sellAmountInput').value = this.initialAmount + this.shadowRoot.getElementById('sellPriceInput').value = this.initialAmount + this.shadowRoot.getElementById('sellTotalInput').value = this.initialAmount + } - clearBuyForm() { - this.shadowRoot.getElementById('buyAmountInput').value = this.initialAmount - this.shadowRoot.getElementById('buyPriceInput').value = this.initialAmount - this.shadowRoot.getElementById('buyTotalInput').value = this.initialAmount - this.shadowRoot.getElementById('qortalAtAddress').value = '' - this.buyBtnDisable = true - } + /** + * Inline Worker - Takes in a function and a modifier then returns an instance of a Web Worker + * + * - Modifiers are simply an Array of Object containing placeholders (containers for variables used in the passedFunction ) in the and its values. + * These placeholders gets replaced with it value during instantiation of the function to be used by the Worker. + * - Example of modifiers: const modifiers = [ + * { searchValue: 'SELECTED_ADDRESS', replaceValue: this.selectedAddress.address, }, + * ] + * + * @param {Function} passedFunction + * @param {Array} modifiers + * @returns {Worker} Worker + */ - clearSellForm() { - this.shadowRoot.getElementById('sellAmountInput').value = this.initialAmount - this.shadowRoot.getElementById('sellPriceInput').value = this.initialAmount - this.shadowRoot.getElementById('sellTotalInput').value = this.initialAmount - } + inlineWorker(passedFunction, modifiers) { + let parsedFunction = `` - isEmptyArray(arr) { - if (!arr) { - return true - } - return arr.length === 0 - } + modifiers.forEach((modifier) => { + let regex = new RegExp(modifier.searchValue, 'g') + parsedFunction = parsedFunction.length === 0 ? `(function ${passedFunction.toString().trim().replace(regex, modifier.replaceValue)})()` : parsedFunction.toString().trim().replace(regex, modifier.replaceValue) + }) - round(number) { - return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) - } + const workerUrl = URL.createObjectURL(new Blob([parsedFunction], { type: 'text/javascript' })) + const worker = new Worker(workerUrl) + URL.revokeObjectURL(workerUrl) + return worker + } - /** - * Inline Worker - Takes in a function and a modifier then returns an instance of a Web Worker - * - * - Modifiers are simply an Array of Object containing placeholders (containers for variables used in the passedFunction ) in the and its values. - * These placeholders gets replaced with it value during instantiation of the function to be used by the Worker. - * - Example of modifiers: const modifiers = [ - * { searchValue: 'SELECTED_ADDRESS', replaceValue: this.selectedAddress.address, }, - * ] - * - * @param {Function} passedFunction - * @param {Array} modifiers - * @returns {Worker} Worker - */ + clearPaneCache() { + this._openOrdersGrid.clearCache() + this._myHistoricTradesGrid.clearCache() + this._historicTradesGrid.clearCache() + this._myOrdersGrid.clearCache() + } - inlineWorker(passedFunction, modifiers) { - let parsedFunction = `` + createConnection() { + if (workers.get(this.selectedCoin).tradesConnectedWorker !== null) { + this.isLoadingHistoricTrades = false + this.isLoadingOpenTrades = false + return + } - modifiers.forEach((modifier) => { - let regex = new RegExp(modifier.searchValue, 'g') - parsedFunction = parsedFunction.length === 0 ? `(function ${passedFunction.toString().trim().replace(regex, modifier.replaceValue)})()` : parsedFunction.toString().trim().replace(regex, modifier.replaceValue) - }) + const handleMessage = (message) => { + switch (message.type) { + case 'TRADE_OFFERS': + if (!message.isRestarted) { + this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter = message.counter + this.processTradeOffers(JSON.parse(message.data)) + this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter === 1 ? this.clearPaneCache() : null + workers.get(this.selectedCoin).tradesConnectedWorker.postMessage(this.listedCoins.get(this.selectedCoin).openOrders) + workers.get(this.selectedCoin).tradesConnectedWorker.postMessage({ type: "open_orders", content: this.listedCoins.get(this.selectedCoin).openOrders }) + } + return null + case 'TRADE_BOT': + if (!message.isRestarted) this.processTradeBotStates(JSON.parse(message.data)) + return null + case 'PRESENCE': + this.tradesPresenceCleaned = [] + this.listedCoins.get(message.data.relatedCoin).openOrders = message.data.offers + this.tradesPresenceCleaned = message.data.filteredOffers - const workerUrl = URL.createObjectURL(new Blob([parsedFunction], { type: 'text/javascript' })) - const worker = new Worker(workerUrl) - URL.revokeObjectURL(workerUrl) - return worker - } + const filterPresenceList = () => { + this.blockedTradesList.forEach(item => { + const toDelete = item.recipient + this.tradesPresenceCleaned = this.tradesPresenceCleaned.filter(el => { + return el.qortalCreatorTradeAddress !== toDelete + }) + }) + } - clearPaneCache() { - this._openOrdersGrid.clearCache() - this._myHistoricTradesGrid.clearCache() - this._historicTradesGrid.clearCache() - this._myOrdersGrid.clearCache() - } + filterPresenceList() + this.listedCoins.get(message.data.relatedCoin).openFilteredOrders = this.tradesPresenceCleaned + this.reRenderOpenFilteredOrders() + return null + default: + break + } + } - createConnection() { - if (workers.get(this.selectedCoin).tradesConnectedWorker !== null) { - this.isLoadingHistoricTrades = false - this.isLoadingOpenTrades = false - return - } + let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + let nodeUrl = myNode.domain + ':' + myNode.port - const handleMessage = (message) => { - switch (message.type) { - case 'TRADE_OFFERS': - if (!message.isRestarted) { - this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter = message.counter - this.processTradeOffers(JSON.parse(message.data)) - this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter === 1 ? this.clearPaneCache() : null - workers.get(this.selectedCoin).tradesConnectedWorker.postMessage(this.listedCoins.get(this.selectedCoin).openOrders) - workers.get(this.selectedCoin).tradesConnectedWorker.postMessage({ type: "open_orders", content: this.listedCoins.get(this.selectedCoin).openOrders }) - } - return null - case 'TRADE_BOT': - if (!message.isRestarted) this.processTradeBotStates(JSON.parse(message.data)) - return null - case 'PRESENCE': - this.tradesPresenceCleaned = [] - this.listedCoins.get(message.data.relatedCoin).openOrders = message.data.offers - this.tradesPresenceCleaned = message.data.filteredOffers + const modifiers = [ + { searchValue: 'NODEURL', replaceValue: nodeUrl }, + { searchValue: 'FOREIGN_BLOCKCHAIN', replaceValue: this.selectedCoin }, + ] - const filterPresenceList = () => { - this.blockedTradesList.forEach(item => { - const toDelete = item.recipient - this.tradesPresenceCleaned = this.tradesPresenceCleaned.filter(el => { - return el.qortalCreatorTradeAddress !== toDelete - }) - }) - } + workers.get(this.selectedCoin).tradesConnectedWorker = this.inlineWorker(this.initSocket, modifiers) - filterPresenceList() - this.listedCoins.get(message.data.relatedCoin).openFilteredOrders = this.tradesPresenceCleaned - this.reRenderOpenFilteredOrders() - return null - default: - break - } - } + workers.get(this.selectedCoin).tradesConnectedWorker.addEventListener('message', function (event) { handleMessage(event.data) }, { passive: true }) - let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - let nodeUrl = myNode.domain + ':' + myNode.port + workers.get(this.selectedCoin).tradesConnectedWorker.postMessage({ type: "set_coin", content: this.selectedCoin }) - const modifiers = [ - { searchValue: 'NODEURL', replaceValue: nodeUrl }, - { searchValue: 'FOREIGN_BLOCKCHAIN', replaceValue: this.selectedCoin }, - ] + } - workers.get(this.selectedCoin).tradesConnectedWorker = this.inlineWorker(this.initSocket, modifiers) + async getNewBlockedTrades() { + const unconfirmedTransactionsList = async () => { + const myNodeInf = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const myNodeUrl = myNodeInf.protocol + '://' + myNodeInf.domain + ':' + myNodeInf.port + const unconfirmedTransactionslUrl = `${myNodeUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` - workers.get(this.selectedCoin).tradesConnectedWorker.addEventListener('message', function (event) { handleMessage(event.data) }, { passive: true }) + var addBlockedTrades = JSON.parse(localStorage.getItem('failedTrades') || '[]') - workers.get(this.selectedCoin).tradesConnectedWorker.postMessage({ type: "set_coin", content: this.selectedCoin }) + await fetch(unconfirmedTransactionslUrl).then(response => { + return response.json() + }).then(data => { + data.map(item => { + const unconfirmedNessageTimeDiff = Date.now() - item.timestamp + const timeOneHour = 60 * 60 * 1000 + if (Number(unconfirmedNessageTimeDiff) > Number(timeOneHour)) { + const addBlocked = { + timestamp: item.timestamp, + recipient: item.recipient + } + addBlockedTrades.push(addBlocked) + } + }) + localStorage.setItem("failedTrades", JSON.stringify(addBlockedTrades)) + this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + }) + } - } + await unconfirmedTransactionsList() - async getNewBlockedTrades() { - const unconfirmedTransactionsList = async () => { - const myNodeInf = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const myNodeUrl = myNodeInf.protocol + '://' + myNodeInf.domain + ':' + myNodeInf.port - const unconfirmedTransactionslUrl = `${myNodeUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` + const filterUnconfirmedTransactionsList = async () => { + let cleanBlockedTrades = this.blockedTradesList.reduce((newArray, cut) => { + if (!newArray.some(obj => obj.recipient === cut.recipient)) { + newArray.push(cut) + } + return newArray + }, []) + localStorage.setItem("failedTrades", JSON.stringify(cleanBlockedTrades)) + this.blockedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") + } - var addBlockedTrades = JSON.parse(localStorage.getItem('failedTrades') || '[]') + await filterUnconfirmedTransactionsList() + } - await fetch(unconfirmedTransactionslUrl).then(response => { - return response.json() - }).then(data => { - data.map(item => { - const unconfirmedNessageTimeDiff = Date.now() - item.timestamp - const timeOneHour = 60 * 60 * 1000 - if (Number(unconfirmedNessageTimeDiff) > Number(timeOneHour)) { - const addBlocked = { - timestamp: item.timestamp, - recipient: item.recipient - } - addBlockedTrades.push(addBlocked) - } - }) - localStorage.setItem("failedTrades", JSON.stringify(addBlockedTrades)) - this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') - }) - } + handleStuckTrades() { + let tradeBotStates = [] - await unconfirmedTransactionsList() + self.addEventListener('message', function (event) { + tradeBotStates = event.data + }) - const filterUnconfirmedTransactionsList = async () => { - let cleanBlockedTrades = this.blockedTradesList.reduce((newArray, cut) => { - if(!newArray.some(obj => obj.recipient === cut.recipient)) { - newArray.push(cut) - } - return newArray - },[]) - localStorage.setItem("failedTrades", JSON.stringify(cleanBlockedTrades)) - this.blockedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } + const getCompletedTrades = async () => { + const url = `http://NODEURL/crosschain/trades?limit=25&reverse=true&foreignBlockchain=FOREIGN_BLOCKCHAIN` + const res = await fetch(url) + const historicTrades = await res.json() + const compareFn = (a, b) => { + return b.tradeTimestamp - a.tradeTimestamp + } + const sortedTrades = historicTrades.sort(compareFn) + self.postMessage({ type: 'HISTORIC_TRADES', data: sortedTrades }) + } - await filterUnconfirmedTransactionsList() - } - - handleStuckTrades() { - let tradeBotStates = [] - - self.addEventListener('message', function (event) { - tradeBotStates = event.data - }) - - const getCompletedTrades = async () => { - const url = `http://NODEURL/crosschain/trades?limit=25&reverse=true&foreignBlockchain=FOREIGN_BLOCKCHAIN` - const res = await fetch(url) - const historicTrades = await res.json() - const compareFn = (a, b) => { - return b.tradeTimestamp - a.tradeTimestamp - } - const sortedTrades = historicTrades.sort(compareFn) - self.postMessage({ type: 'HISTORIC_TRADES', data: sortedTrades }) - } - - const filterStuckOffers = (myOffers) => { - const myTradeBotStates = tradeBotStates.filter((state) => state.creatorAddress === 'SELECTED_ADDRESS') + const filterStuckOffers = (myOffers) => { + const myTradeBotStates = tradeBotStates.filter((state) => state.creatorAddress === 'SELECTED_ADDRESS') return myOffers.filter((myOffer) => { let value = myTradeBotStates.some((myTradeBotState) => myOffer.qortalAtAddress === myTradeBotState.atAddress) return !value }) - } + } - const getOffers = async () => { - const url = `http://NODEURL/crosschain/tradeoffers?foreignBlockchain=FOREIGN_BLOCKCHAIN` - const res = await fetch(url) - const openTradeOrders = await res.json() - const myOpenTradeOrders = await openTradeOrders.filter((order) => order.mode === 'OFFERING' && order.qortalCreator === 'SELECTED_ADDRESS') - const stuckOffers = filterStuckOffers(myOpenTradeOrders) - self.postMessage({ type: 'STUCK_OFFERS', data: stuckOffers }) - } - setTimeout(() => { getOffers() }, 1000) - setTimeout(() => { getCompletedTrades() }, 1000) - } + const getOffers = async () => { + const url = `http://NODEURL/crosschain/tradeoffers?foreignBlockchain=FOREIGN_BLOCKCHAIN` + const res = await fetch(url) + const openTradeOrders = await res.json() + const myOpenTradeOrders = await openTradeOrders.filter((order) => order.mode === 'OFFERING' && order.qortalCreator === 'SELECTED_ADDRESS') + const stuckOffers = filterStuckOffers(myOpenTradeOrders) + self.postMessage({ type: 'STUCK_OFFERS', data: stuckOffers }) + } + setTimeout(() => { getOffers() }, 1000) + setTimeout(() => { getCompletedTrades() }, 1000) + } - filterStuckTrades(states) { - if (workers.get(this.selectedCoin).handleStuckTradesConnectedWorker !== null) { - this.isLoadingOpenTrades = false - return - } + filterStuckTrades(states) { + if (workers.get(this.selectedCoin).handleStuckTradesConnectedWorker !== null) { + this.isLoadingOpenTrades = false + return + } - this.shadowRoot.getElementById('loadingHistoricTrades').style.display = "block"; - let isHandleTradesDone = false - let isHandleStuckOffersDone = false + this.shadowRoot.getElementById('loadingHistoricTrades').style.display = "block"; + let isHandleTradesDone = false + let isHandleStuckOffersDone = false - const handleMessage = (message) => { - switch (message.type) { - case 'HISTORIC_TRADES': - this.listedCoins.get(this.selectedCoin).historicTrades = message.data - this.reRenderHistoricTrades() - isHandleTradesDone = true - break - case 'STUCK_OFFERS': - doStuckOffers(message.data) - isHandleStuckOffersDone = true - break - default: - break - } - if (isHandleTradesDone === true && isHandleStuckOffersDone === true) return workers.get(this.selectedCoin).handleStuckTradesConnectedWorker.terminate() - } + const handleMessage = (message) => { + switch (message.type) { + case 'HISTORIC_TRADES': + this.listedCoins.get(this.selectedCoin).historicTrades = message.data + this.reRenderHistoricTrades() + isHandleTradesDone = true + break + case 'STUCK_OFFERS': + doStuckOffers(message.data) + isHandleStuckOffersDone = true + break + default: + break + } + if (isHandleTradesDone === true && isHandleStuckOffersDone === true) return workers.get(this.selectedCoin).handleStuckTradesConnectedWorker.terminate() + } - const doStuckOffers = (message) => { - const offers = message - const offerItem = (offer) => { - return { - ...offer, - price: this.round(parseFloat(offer.expectedForeignAmount) / parseFloat(offer.qortAmount)), - } - } - const addStuckOrders = (offerItem) => { - if (offerItem.qortalCreator === this.selectedAddress.address) { - this._stuckOrdersGrid.items.unshift(offerItem) - this._stuckOrdersGrid.clearCache() - } - } - const handleOffers = () => { - offers.forEach((offer) => { - addStuckOrders(offerItem(offer)) - }) - } - handleOffers() - } + const doStuckOffers = (message) => { + const offers = message + const offerItem = (offer) => { + return { + ...offer, + price: this.round(parseFloat(offer.expectedForeignAmount) / parseFloat(offer.qortAmount)), + } + } + const addStuckOrders = (offerItem) => { + if (offerItem.qortalCreator === this.selectedAddress.address) { + this._stuckOrdersGrid.items.unshift(offerItem) + this._stuckOrdersGrid.clearCache() + } + } + const handleOffers = () => { + offers.forEach((offer) => { + addStuckOrders(offerItem(offer)) + }) + } + handleOffers() + } - let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - let nodeUrl = myNode.domain + ':' + myNode.port + let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + let nodeUrl = myNode.domain + ':' + myNode.port - const modifiers = [ - { searchValue: 'NODEURL', replaceValue: nodeUrl }, - { searchValue: 'SELECTED_ADDRESS', replaceValue: this.selectedAddress.address, }, - { searchValue: 'FOREIGN_BLOCKCHAIN', replaceValue: this.selectedCoin, }, - ] + const modifiers = [ + { searchValue: 'NODEURL', replaceValue: nodeUrl }, + { searchValue: 'SELECTED_ADDRESS', replaceValue: this.selectedAddress.address, }, + { searchValue: 'FOREIGN_BLOCKCHAIN', replaceValue: this.selectedCoin, }, + ] - workers.get(this.selectedCoin).handleStuckTradesConnectedWorker = this.inlineWorker(this.handleStuckTrades, modifiers) - workers.get(this.selectedCoin).handleStuckTradesConnectedWorker.postMessage(states) - workers.get(this.selectedCoin).handleStuckTradesConnectedWorker.addEventListener( - 'message', - function (event) { - handleMessage(event.data) - }, - { passive: true } - ) - } + workers.get(this.selectedCoin).handleStuckTradesConnectedWorker = this.inlineWorker(this.handleStuckTrades, modifiers) + workers.get(this.selectedCoin).handleStuckTradesConnectedWorker.postMessage(states) + workers.get(this.selectedCoin).handleStuckTradesConnectedWorker.addEventListener( + 'message', + function (event) { + handleMessage(event.data) + }, + { passive: true } + ) + } + + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } -window.customElements.define('trade-portal', TradePortal) +window.customElements.define('trade-portal', TradePortal) \ No newline at end of file diff --git a/plugins/plugins/core/wallet/wallet-app.src.js b/plugins/plugins/core/wallet/wallet-app.src.js index 45b3cd61..a49333d4 100644 --- a/plugins/plugins/core/wallet/wallet-app.src.js +++ b/plugins/plugins/core/wallet/wallet-app.src.js @@ -1,15 +1,15 @@ -import {css, html, LitElement} from 'lit' -import {render} from 'lit/html.js' -import {Epml} from '../../../epml.js' +import { html, LitElement } from 'lit' +import { render } from 'lit/html.js' +import { Epml } from '../../../epml' +import { decryptData, encryptData } from '../../../../core/src/lockScreen' +import { multiWalletStyles } from '../components/plugins-css' import isElectron from 'is-electron' -import {get, registerTranslateConfig, translate, use} from '../../../../core/translate' -import Base58 from '../../../../crypto/api/deps/Base58.js' -import {decryptData, encryptData} from '../../../../core/src/lockScreen.js' import FileSaver from 'file-saver' -import '../components/ButtonIconCopy.js' -import '../components/QortalQrcodeGenerator.js' -import '../components/frag-file-input.js' -import '../components/time-elements/index.js' +import Base58 from '../../../../crypto/api/deps/Base58' +import '../components/ButtonIconCopy' +import '../components/QortalQrcodeGenerator' +import '../components/frag-file-input' +import '../components/time-elements/index' import '@material/mwc-button' import '@material/mwc-checkbox' import '@material/mwc-dialog' @@ -18,20 +18,22 @@ import '@material/mwc-icon' import '@material/mwc-icon-button' import '@material/mwc-tab-bar' import '@material/mwc-textfield' +import '@polymer/iron-icons/iron-icons.js' import '@polymer/paper-dialog/paper-dialog.js' import '@polymer/paper-progress/paper-progress.js' import '@polymer/paper-slider/paper-slider.js' import '@polymer/paper-spinner/paper-spinner-lite.js' import '@polymer/paper-icon-button/paper-icon-button.js' -import '@polymer/iron-icons/iron-icons.js' import '@vaadin/button' import '@vaadin/grid' import '@vaadin/icon' import '@vaadin/icons' import '@vaadin/password-field' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) @@ -39,4031 +41,3503 @@ const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) const coinsNames = ['qort', 'btc', 'ltc', 'doge', 'dgb', 'rvn', 'arrr'] class MultiWallet extends LitElement { - static get properties() { - return { - loading: { type: Boolean }, - transactions: { type: Object }, - lastBlock: { type: Object }, - selectedTransaction: { type: Object }, - isTextMenuOpen: { type: Boolean }, - wallets: { type: Map }, - _selectedWallet: 'qort', - nodeConfig: { type: Object }, - nodeDomain: { type: String }, - theme: { type: String, reflect: true }, - amount: { type: Number }, - recipient: { type: String }, - btcRecipient: { type: String }, - btcAmount: { type: Number }, - ltcRecipient: { type: String }, - ltcAmount: { type: Number }, - dogeRecipient: { type: String }, - dogeAmount: { type: Number }, - dgbRecipient: { type: String }, - dgbAmount: { type: Number }, - rvnRecipient: { type: String }, - rvnAmount: { type: Number }, - arrrRecipient: { type: String }, - arrrAmount: { type: Number }, - arrrMemo: { type: String }, - errorMessage: { type: String }, - arrrWalletAddress: { type: String }, - unusedWalletAddress: { type: String }, - successMessage: { type: String }, - sendMoneyLoading: { type: Boolean }, - btnDisable: { type: Boolean }, - qortWarning: { type: Boolean }, - isValidAmount: { type: Boolean }, - balance: { type: Number }, - balanceString: { type: String }, - btcServer: { type: Number }, - ltcServer: { type: Number }, - dogeServer: { type: Number }, - dgbServer: { type: Number }, - rvnServer: { type: Number }, - arrrServer: { type: Number }, - qortPaymentFee: { type: Number }, - btcFeePerByte: { type: Number }, - ltcFeePerByte: { type: Number }, - dogeFeePerByte: { type: Number }, - dgbFeePerByte: { type: Number }, - rvnFeePerByte: { type: Number }, - qortBook: { type: Array }, - btcBook: { type: Array }, - ltcBook: { type: Array }, - dogeBook: { type: Array }, - dgbBook: { type: Array }, - rvnBook: { type: Array }, - arrrBook: { type: Array }, - qortBookName: { type: String }, - btcBookName: { type: String }, - ltcBookName: { type: String }, - dogeBookName: { type: String }, - dgbBookName: { type: String }, - rvnBookName: { type: String }, - arrrBookName: { type: String }, - qortBookAddress: { type: String }, - btcBookAddress: { type: String }, - ltcBookAddress: { type: String }, - dogeBookAddress: { type: String }, - dgbBookAddress: { type: String }, - rvnBookAddress: { type: String }, - arrrBookAddress: { type: String }, - myElementId: { type: String }, - walletSalt: { type: String }, - walletStorageData: { type: String }, - walletLockScreenPass: { type: String }, - walletLockScreenSet: { type: String }, - walletLockPass: { type: String }, - walletLockSet: { type: String }, - myWalletLockScreenPass: { type: String }, - myWalletLockScreenSet: { type: String }, - walletHelperMessage: { type: String }, - bookQortalAddress: { type: String }, - bookBitcoinAddress: { type: String }, - bookLitecoinAddress: { type: String }, - bookDogecoinAddress: { type: String }, - bookDigibyteAddress: { type: String }, - bookRavencoinAddress: { type: String }, - bookPiratechainAddress: { type: String } - } - } - - static get observers() { - return ['_kmxKeyUp(amount)'] - } - - static get styles() { - return css` - * { - box-sizing: border-box; - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --mdc-theme-surface: var(--white); - --mdc-theme-error: rgb(255, 89, 89); - --mdc-dialog-content-ink-color: var(--black); - --mdc-dialog-min-width: 500px; - --mdc-dialog-max-width: 1024px; - --paper-input-container-focus-color: var(--mdc-theme-primary); - --lumo-primary-text-color: rgb(0, 167, 245); - --lumo-primary-color-50pct: rgba(0, 167, 245, 0.5); - --lumo-primary-color-10pct: rgba(0, 167, 245, 0.1); - --lumo-primary-color: hsl(199, 100%, 48%); - --lumo-base-color: var(--white); - --lumo-secondary-text-color: var(--sectxt); - --lumo-contrast-60pct: var(--vdicon); - --lumo-body-text-color: var(--black); - --_lumo-grid-border-color: var(--border); - --_lumo-grid-secondary-border-color: var(--border2); - } - - #pages { - display: flex; - flex-wrap: wrap; - padding: 10px 5px 5px 5px; - margin: 0px 20px 20px 20px; - } - - #pages > button { - user-select: none; - padding: 5px; - margin: 0 5px; - border-radius: 10%; - border: 0; - background: transparent; - font: inherit; - outline: none; - cursor: pointer; - color: var(--black); - } - - #pages > button:not([disabled]):hover, - #pages > button:focus { - color: #ccc; - background-color: #eee; - } - - #pages > button[selected] { - font-weight: bold; - color: var(--white); - background-color: #ccc; - } - - #pages > button[disabled] { - opacity: 0.5; - cursor: default; - } - - #tabs-height { - --mdc-tab-height: 50px; - } - - #tabs-1-content { - height: 100%; - padding-bottom: 10px; - } - - mwc-tab-bar { - --mdc-text-transform: none; - --mdc-tab-color-default: var(--black); - --mdc-tab-text-label-color-default: var(--black); - } - - paper-slider.blue { - --paper-slider-knob-color: var(--paper-light-blue-500); - --paper-slider-active-color: var(--paper-light-blue-500); - --paper-slider-pin-color: var(--paper-light-blue-500); - } - - paper-progress { - --paper-progress-active-color: var(--mdc-theme-primary); - } - - .red { - --mdc-theme-primary: #F44336; - } - - .green { - color: var(--paper-green-500); - } - - paper-spinner-lite { - height: 75px; - width: 75px; - --paper-spinner-color: var(--mdc-theme-primary); - --paper-spinner-stroke-width: 3px; - } - - .unconfirmed { - font-style: italic; - } - - .roboto { - font-family: 'Roboto', sans-serif; - } - - .mono { - font-family: 'Roboto Mono', monospace; - } - - .sans { - font-family: 'Open Sans', sans-serif; - } - - .magistral { - font-family: 'magistralbold'; - } - - .montserrat { - font-family: 'Montserrat', sans-serif; - } - - .maven { - font-family: 'MavenPro', sans-serif; - } - - .weight-100 { - font-weight: 100; - } - - .text-white-primary { - color: var(--white); - } - - .text-white-secondary { - color: var(--white-secondary); - } - - .text-white-disabled { - color: var(--white-disabled); - } - - .text-white-hint { - color: var(--white-divider); - } - - .white-bg { - height: 100vh; - background: var(--white); - } - - span { - font-size: 18px; - word-break: break-all; - } - - .floatleft { - float: left; - } - - .floatright { - float: right; - } - - .title { - font-weight: 600; - font-size: 12px; - line-height: 32px; - opacity: 0.66; - } - - #transactionList { - padding: 0; - } - - .color-in { - color: #02977e; - background-color: rgba(0, 201, 167, 0.2); - font-weight: 700; - font-size: 0.60938rem; - border-radius: 0.25rem !important; - padding: 0.2rem 0.5rem; - margin-left: 4px; - } - - .color-out { - color: #b47d00; - background-color: rgba(219, 154, 4, 0.2); - font-weight: 700; - font-size: 0.60938rem; - border-radius: 0.25rem !important; - padding: 0.2rem 0.5rem; - margin-left: 4px; - } - - body { - margin: 0; - padding: 0; - background: var(--white); - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - } - - h2 { - margin: 0; - color: var(--black); - font-weight: 400; - font: 24px/24px 'Open Sans', sans-serif; - } - - h3 { - margin: 0 0 5px; - color: var(--black); - font-weight: 600; - font-size: 18px; - line-height: 18px; - } - - .hrstyle { - color: var(--border); - border-radius: 80%; - margin-bottom: 1rem; - } - - .header-title { - display: inlinr; - font-size: 32px; - color: var(--black); - font-weight: 600; - text-align: center; - margin-top: 1rem; - } - - .fullWidth { - width: 100%; - } - - .wrapper { - margin: 0 auto; - height: 100%; - overflow: hidden; - border-radius: 8px; - background-color: var(--white); - } - - .wallet { - width: 200px; - height: 100vh; - border-top-left-radius: inherit; - border-bottom-left-radius: inherit; - border-right: 1px solid var(--border); - } - - .transactions-wrapper { - width: 100%; - padding: 30px 0 0 0; - height: 100%; - } - - .wallet-header { - margin: 0 20px; - color: var(--black); - } - - .wallet-address { - display: flex; - align-items: center; - font-size: 18px; - color: var(--black); - margin: 4px 0 20px; - } - - .wallet-balance { - display: inline-block; - font-weight: 600; - font-size: 32px; - color: var(--black); - } - - #transactions { - margin-top: 30px; - margin-left: 20px; - margin-right: 20px; - border-top: 1px solid var(--border); - padding-top: 0px; - height: 100%; - } - - .show { - animation: fade-in 0.3s 1; - } - - .transaction-item { - display: flex; - justify-content: space-between; - position: relative; - padding-left: 40px; - margin-bottom: 45px; - margin-right: 50px; - } - - .transaction-item::before { - position: absolute; - content: ''; - border: 2px solid #e1e1e1; - border-radius: 50%; - height: 25px; - width: 25px; - left: 0; - top: 10px; - box-sizing: border-box; - vertical-align: middle; - color: #666666; - } - - .credit::before { - content: '+'; - font-size: 25px; - line-height: 19px; - padding: 0 4px 0; - } - - .debit::before { - content: '-'; - font-size: 20px; - line-height: 21px; - padding: 0 5px; - } - - .transaction-item .details { - font-size: 14px; - line-height: 14px; - color: #999; - } - - .transaction-item_details { - width: 270px; - } - - .transaction-item_amount .amount { - font-weight: 600; - font-size: 18px; - line-height: 45px; - position: relative; - margin: 0; - display: inline-block; - } - - .active { - background: var(--menuactive); - } - - .currency-image { - display: inline-block; - height: 42px; - width: 42px; - background-repeat: no-repeat; - background-size: cover; - border-radius: 3px; - filter: grayscale(100%); - } - - .qort .currency-image { - background-image: url('/img/qort.png'); - } - - .btc .currency-image { - background-image: url('/img/btc.png'); - } - - .ltc .currency-image { - background-image: url('/img/ltc.png'); - } - - .doge .currency-image { - background-image: url('/img/doge.png'); - } - - .dgb .currency-image { - background-image: url('/img/dgb.png'); - } - - .rvn .currency-image { - background-image: url('/img/rvn.png'); - } - - .arrr .currency-image { - background-image: url('/img/arrr.png'); - } - - .card-list { - margin-top: 20px; - } - - .card-list .currency-image { - cursor: pointer; - margin-right: 15px; - transition: 0.1s; - } - - .card-list .currency-image:hover { - transform: scale(1.1); - } - - .buttons { - width: auto !important; - } - - .send-coin-dialog { - min-height: 300px; - min-width: 300px; - box-sizing: border-box; - position: relative; - } - - .unused-address-dialog { - min-height: 150px; - min-width: 550px; - box-sizing: border-box; - position: relative; - } - - .btn-clear-success { - --mdc-icon-button-size: 32px; - color: red; - } - - .btn-clear-error { - --mdc-icon-button-size: 32px; - color: green; - } - - @keyframes fade-in { - 0% { - opacity: 0; - } - 100% { - opacity: 1; - } - } - - .successBox { - height: 34px; - min-width: 300px; - width: 100%; - border: 1px solid green; - border-radius: 5px; - background-color: transparent; - margin-top: 15px; - } - - .errorBox { - height: 34px; - min-width: 300px; - width: 100%; - border: 1px solid red; - border-radius: 5px; - background-color: transparent; - margin-top: 15px; - } - - .qrcode-pos { - margin-top: -175px; - float: right; - } - - .send-pos { - margin-top: 20px; - margin-left: 20px; - width: 185px; - } - - .book-pos { - margin-top: -44px; - margin-left: 215px; - width: 185px; - } - - @media (max-width: 863px) { - .wallet { - width: 100%; - height: max-content; - border-top-right-radius: inherit; - padding-bottom: 25px; - } - .cards { - margin-top: 25px; - } - } - - .checkboxLabel:hover{ - cursor: pointer; - } - - .warning-text { - animation: blinker 1.5s linear infinite; - text-align: center; - margin-top: 10px; - color: rgb(255, 89, 89); - } - - @keyframes blinker { - 50% { - opacity: 0; - } - } - - @media (max-width: 764px) { - .wallet { - width: 100%; - height: max-content; - border-top-right-radius: inherit; - padding-bottom: 25px; - } - .cards { - margin-top: 25px; - } - } - - @media (max-width: 530px) { - h3 { - line-height: 24px; - } - .cards { - text-align: center; - } - .wallet-balance { - font-size: 22px; - } - } - - @media (max-width: 390px) { - .wallet { - height: max-content; - padding: 50px 25px; - } - .transactions-wrapper { - padding: 50px 25px; - } - h2 { - font: 18px/24px 'Open Sans', sans-serif; - } - } - - .setpass-wrapper { - width: 100%; - min-width: 400px; - max-width: 450px; - text-align: center; - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - padding: 10px 10px 0px; - box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1); - } - - .lock-wrapper { - width: 100%; - height: 100%; - min-width: 600px; - max-width: 600px; - min-height: 400px; - max-height: 400px; - text-align: center; - background: url("/img/qortal-lock.jpg"); - border: 1px solid var(--black); - border-radius: 25px; - padding: 10px 10px 0px; - } - - .text-wrapper { - width: 100%; - height: 100%; - min-width: 280px; - max-width: 280px; - min-height: 64px; - max-height: 64px; - text-align: center; - margin-left: 35px; - margin-top: 125px; - overflow: hidden; - } - - .lock-title-white { - font-family: 'magistralbold'; - font-weight: 700; - font-size: 26px; - line-height: 32px; - color: #ffffff; - } - - .lock-title-red { - font-family: 'magistralbold'; - font-weight: 700; - font-size: 26px; - line-height: 32px; - color: #df3636; - } - ` - } - - constructor() { - super() - - this.lastBlock = { - height: 0, - } - - this.balanceString = this.renderFetchText() - this.selectedTransaction = {} - this.isTextMenuOpen = false - this.loading = true - - this.nodeConfig = {} - this.nodeDomain = '' - this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'; - - this.qortBook = [] - this.btcBook = [] - this.ltcBook = [] - this.dogeBook = [] - this.dgbBook = [] - this.rvnBook = [] - this.arrrBook = [] - this.qortBookName = '' - this.btcBookName = '' - this.ltcBookName = '' - this.dogeBookName = '' - this.dgbBookName = '' - this.rvnBookName = '' - this.arrrBookName = '' - this.qortBookAddress = '' - this.btcBookAddress = '' - this.ltcBookAddress = '' - this.dogeBookAddress = '' - this.dgbBookAddress = '' - this.rvnBookAddress = '' - this.arrrBookAddress = '' - this.recipient = '' - this.btcRecipient = '' - this.ltcRecipient = '' - this.dogeRecipient = '' - this.dgbRecipient = '' - this.rvnRecipient = '' - this.arrrRecipient = '' - this.arrrMemo = '' - this.arrrWalletAddress = '' - this.unusedWalletAddress = '' - this.btcServer = '' - this.ltcServer = '' - this.dogeServer = '' - this.dgbServer = '' - this.rvnServer = '' - this.arrrServer = '' - this.errorMessage = '' - this.successMessage = '' - this.myElementId = '' - this.sendMoneyLoading = false - this.isValidAmount = false - this.btnDisable = false - this.qortWarning = false - this.balance = 0 - this.amount = 0 - this.btcAmount = 0 - this.ltcAmount = 0 - this.dogeAmount = 0 - this.dgbAmount = 0 - this.rvnAmount = 0 - this.arrrAmount = 0 - this.qortPaymentFee = 0.001 - this.btcFeePerByte = 100 - this.btcSatMinFee = 20 - this.btcSatMaxFee = 150 - this.ltcFeePerByte = 30 - this.ltcSatMinFee = 10 - this.ltcSatMaxFee = 100 - this.dogeFeePerByte = 1000 - this.dogeSatMinFee = 100 - this.dogeSatMaxFee = 10000 - this.dgbFeePerByte = 10 - this.dgbSatMinFee = 1 - this.dgbSatMaxFee = 100 - this.rvnFeePerByte = 1125 - this.rvnSatMinFee = 1000 - this.rvnSatMaxFee = 10000 - this.walletSalt = '' - this.walletStorageData = '' - this.walletLockScreenPass = '' - this.walletLockScreenSet = '' - this.walletLockPass = '' - this.walletLockSet = '' - this.myWalletLockScreenPass = '' - this.myWalletLockScreenSet = '' - this.walletHelperMessage = '' - this.bookQortalAddress = '' - this.bookBitcoinAddress = '' - this.bookLitecoinAddress = '' - this.bookDogecoinAddress = '' - this.bookDigibyteAddress = '' - this.bookRavencoinAddress = '' - this.bookPiratechainAddress = '' - - this.wallets = new Map() - - let coinProp = { - balance: 0, - wallet: null, - transactions: [], - fetchingWalletBalance: false, - fetchingWalletTransactions: false - } - - coinsNames.forEach((c, i) => { - this.wallets.set(c, { ...coinProp }) - }, this) - - this.wallets.get('qort').wallet = window.parent.reduxStore.getState().app.selectedAddress - this.wallets.get('btc').wallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet - this.wallets.get('ltc').wallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet - this.wallets.get('doge').wallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet - this.wallets.get('dgb').wallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet - this.wallets.get('rvn').wallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet - this.wallets.get('arrr').wallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet - - this._selectedWallet = 'qort' - - parentEpml.ready().then(() => { - parentEpml.subscribe('selected_address', async (selectedAddress) => { - selectedAddress = JSON.parse(selectedAddress) - if (!selectedAddress || Object.entries(selectedAddress).length === 0) return - - this.wallets.get('qort').wallet = selectedAddress - this.wallets.get('btc').wallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet - this.wallets.get('ltc').wallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet - this.wallets.get('doge').wallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet - this.wallets.get('dgb').wallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet - this.wallets.get('rvn').wallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet - this.wallets.get('arrr').wallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet - }) - parentEpml.subscribe('coin_balances', async (payload) => { - const coinBalances = JSON.parse(payload) - if(coinBalances[this._selectedWallet]){ - const res = coinBalances[this._selectedWallet].fullValue - let value = Number(res).toFixed(8) - if(this._selectedWallet !== 'qort'){ - value = (Number(res) / 1e8).toFixed(8) - } - this.wallets.get(this._selectedWallet).balance = value - this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase() - this.balance = this.wallets.get(this._selectedWallet).balance - } - }) - }) - - this.pingCoinBalancesController = this.pingCoinBalancesController.bind(this) - } - - refreshWallet(){ - const coin = this._selectedWallet - switch (coin) { - case 'qort': - this.tabWalletQort(); - break - case 'arrr': - this.tabWalletArrr(); - break - case 'btc': - this.tabWalletBtc(); - break; - case 'ltc': - this.tabWalletLtc(); - break; - case 'doge': - this.tabWalletDoge(); - break - case 'dgb': - this.tabWalletDgb() - break; - case 'rvn': - this.tabWalletRvn(); - break - default: - break - } - - } - - render() { - return html` -
    -
    - ${translate("walletpage.wchange22")} ${this.renderWalletLockButton()} -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    -

    -
    - ${translate("walletpage.wchange2")} - - -
    -
    - ${this.getSelectedWalletAddress()} - - -
    - - ${this.balanceString} - -
    - ${this.getSelectedWalletServer()} -
    -

    -
    - ${this.renderSendButton()} -
    -
    - ${this.renderAddressbookButton()} -
    -
    - -
    -
    - - ${this.loading ? html`` : ''} -
    -
    -
    - - -
    -

    ${translate("walletpage.wchange5")}

    -
    -
    -
    - ${translate("walletpage.wchange6")} -
    -
    - ${this.selectedTransaction.type} - ${this.selectedTransaction.txnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} -
    - ${translate("walletpage.wchange9")} -
    -
    ${this.selectedTransaction.type === 'AT' ? html`${this.selectedTransaction.atAddress}` : html`${this.selectedTransaction.creatorAddress}`}
    - ${translate("walletpage.wchange10")} -
    -
    - ${this.selectedTransaction.type === 'DEPLOY_AT' ? html`${this.renderCAB()}` : html`${this.renderSQB()}`} -
    -
    - ${!this.selectedTransaction.amount ? '' : html` - ${translate("walletpage.wchange11")} -
    -
    ${this.selectedTransaction.amount} QORT
    - `} - ${translate("walletpage.wchange12")} -
    -
    ${this.selectedTransaction.fee}
    - ${translate("walletpage.wchange13")} -
    -
    ${this.selectedTransaction.blockHeight}
    - ${translate("walletpage.wchange14")} -
    -
    ${new Date(this.selectedTransaction.timestamp).toString()}
    - ${translate("walletpage.wchange15")} -
    -
    ${this.selectedTransaction.signature}
    -
    - - ${translate("general.close")} - -
    - - -
    -

    ${translate("walletpage.wchange5")}

    -
    -
    -
    - ${translate("walletpage.wchange6")} -
    -
    - ${translate("walletpage.wchange40")} - ${this.selectedTransaction.btcTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} -
    - ${translate("walletpage.wchange9")} -
    -
    - ${this.selectedTransaction.btcSender} -
    - ${translate("walletpage.wchange10")} -
    -
    - ${this.selectedTransaction.btcReceiver} - this.sendToBtcAddress()} title="${translate("walletpage.wchange46")}"> - this.openAddBtcAddressDialog()} title="${translate("walletpage.wchange49")}"> -
    -
    - ${translate("walletpage.wchange12")} -
    -
    - ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} BTC -
    - ${translate("walletpage.wchange37")} -
    -
    - ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} BTC -
    - ${translate("walletpage.wchange14")} -
    -
    ${new Date(this.selectedTransaction.timestamp).toString()}
    - ${translate("walletpage.wchange16")} -
    -
    - ${this.selectedTransaction.txHash} -
    -
    - - ${translate("general.close")} - -
    - - -
    -

    ${translate("walletpage.wchange5")}

    -
    -
    -
    - ${translate("walletpage.wchange6")}e -
    -
    - ${translate("walletpage.wchange40")} - ${this.selectedTransaction.ltcTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} -
    - ${translate("walletpage.wchange9")} -
    -
    - ${this.selectedTransaction.ltcSender} -
    - ${translate("walletpage.wchange10")} -
    -
    - ${this.selectedTransaction.ltcReceiver} - this.sendToLtcAddress()} title="${translate("walletpage.wchange46")}"> - this.openAddLtcAddressDialog()} title="${translate("walletpage.wchange49")}"> -
    -
    - ${translate("walletpage.wchange12")} -
    -
    - ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} LTC -
    - ${translate("walletpage.wchange37")} -
    -
    - ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} LTC -
    - ${translate("walletpage.wchange14")} -
    -
    ${new Date(this.selectedTransaction.timestamp).toString()}
    - ${translate("walletpage.wchange16")} -
    -
    - ${this.selectedTransaction.txHash} -
    -
    - - ${translate("general.close")} - -
    - - -
    -

    ${translate("walletpage.wchange5")}

    -
    -
    -
    - ${translate("walletpage.wchange6")} -
    -
    - ${translate("walletpage.wchange40")} - ${this.selectedTransaction.dogeTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} -
    - ${translate("walletpage.wchange9")} -
    -
    - ${this.selectedTransaction.dogeSender} -
    -
    - ${translate("walletpage.wchange10")} -
    -
    - ${this.selectedTransaction.dogeReceiver} - this.sendToDogeAddress()} title="${translate("walletpage.wchange46")}"> - this.openAddDogeAddressDialog()} title="${translate("walletpage.wchange49")}"> -
    -
    - ${translate("walletpage.wchange12")} -
    -
    - ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} DOGE -
    - ${translate("walletpage.wchange37")} -
    -
    - ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} DOGE -
    - ${translate("walletpage.wchange14")} -
    -
    ${new Date(this.selectedTransaction.timestamp).toString()}
    - ${translate("walletpage.wchange16")} -
    -
    - ${this.selectedTransaction.txHash} -
    -
    - - ${translate("general.close")} - -
    - - -
    -

    ${translate("walletpage.wchange5")}

    -
    -
    -
    - ${translate("walletpage.wchange6")} -
    -
    - ${translate("walletpage.wchange40")} - ${this.selectedTransaction.dgbTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} -
    - ${translate("walletpage.wchange9")} -
    -
    - ${this.selectedTransaction.dgbSender} -
    - ${translate("walletpage.wchange10")} -
    -
    - ${this.selectedTransaction.dgbReceiver} - this.sendToDgbAddress()} title="${translate("walletpage.wchange46")}"> - this.openAddDgbAddressDialog()} title="${translate("walletpage.wchange49")}"> -
    -
    - ${translate("walletpage.wchange12")} -
    -
    - ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} DGB -
    - ${translate("walletpage.wchange37")} -
    -
    - ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} DGB -
    - ${translate("walletpage.wchange14")} -
    -
    ${new Date(this.selectedTransaction.timestamp).toString()}
    - ${translate("walletpage.wchange16")} -
    -
    - ${this.selectedTransaction.txHash} -
    -
    - - ${translate("general.close")} - -
    - - -
    -

    ${translate("walletpage.wchange5")}

    -
    -
    -
    - ${translate("walletpage.wchange6")} -
    -
    - ${translate("walletpage.wchange40")} - ${this.selectedTransaction.rvnTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} -
    - ${translate("walletpage.wchange9")} -
    -
    - ${this.selectedTransaction.rvnSender} -
    - ${translate("walletpage.wchange10")} -
    -
    - ${this.selectedTransaction.rvnReceiver} - this.sendToRvnAddress()} title="${translate("walletpage.wchange46")}"> - this.openAddRvnAddressDialog()} title="${translate("walletpage.wchange49")}"> -
    -
    - ${translate("walletpage.wchange12")} -
    -
    - ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} RVN -
    - ${translate("walletpage.wchange37")} -
    -
    - ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} RVN -
    - ${translate("walletpage.wchange14")} -
    -
    ${new Date(this.selectedTransaction.timestamp).toString()}
    - ${translate("walletpage.wchange16")} -
    -
    - ${this.selectedTransaction.txHash} -
    -
    - - ${translate("general.close")} - -
    - - -
    -

    ${translate("walletpage.wchange5")}

    -
    -
    -
    - ${translate("walletpage.wchange6")} -
    -
    - ${translate("walletpage.wchange40")} - ${this.selectedTransaction.arrrTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} -
    - ${translate("walletpage.wchange9")} -
    -
    - ${this.selectedTransaction.arrrSender} -
    - ${translate("walletpage.wchange10")} -
    -
    - ${this.selectedTransaction.arrrReceiver} - this.sendToArrrAddress()} title="${translate("walletpage.wchange46")}"> - this.openAddArrrAddressDialog()} title="${translate("walletpage.wchange49")}"> -
    -
    - ${translate("walletpage.wchange12")} -
    -
    - ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} ARRR -
    - ${translate("walletpage.wchange37")} -
    -
    - ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} ARRR -
    - ${translate("walletpage.wchange14")} -
    -
    ${new Date(this.selectedTransaction.timestamp).toString()}
    - ${translate("walletpage.wchange16")} -
    -
    - ${this.selectedTransaction.txHash} -
    -
    - - ${translate("general.close")} - -
    - - -
    -
    - -

    ${translate("walletpage.wchange17")} QORT

    -
    -
    -

    - ${translate("walletpage.wchange18")}:
    - ${this.getSelectedWalletAddress()} -

    -

    - ${translate("walletpage.wchange19")}:
    - ${this.balanceString}
    - - this.calculateQortAll()}> ${translate("walletpage.wchange45")} QORT -
      -

    -

    - - -

    -

    - - -

    -
    -

    ${translate("walletpage.wchange21")} ${this.qortPaymentFee} QORT

    -
    - ${this.renderClearSuccess()} - ${this.renderClearError()} - ${this.sendMoneyLoading ? html` ` : ''} -
    -
    - this.sendQort()}> - - ${translate("walletpage.wchange17")} QORT - -
    ${this.renderWarning()}
    -
    -
    -
    - - ${translate("general.close")} - -
    - - -
    -
    - -

    ${translate("walletpage.wchange17")} BTC

    -
    -
    -

    - From address:
    - ${this.getSelectedWalletAddress()} -

    -

    - Available balance:
    - ${this.balanceString}
    - - this.calculateBtcAll()}> ${translate("walletpage.wchange45")} BTC -
      -

    -

    - - -

    -

    - - -

    -
    -

    ${translate("walletpage.wchange24")}: ${(this.btcFeePerByte / 1e8).toFixed(8)} BTC
    ${translate("walletpage.wchange25")}

    - - -
    - ${this.renderClearSuccess()} - ${this.renderClearError()} - ${this.sendMoneyLoading ? html` ` : ''} -
    -
    - this.sendBtc()}> - - ${translate("walletpage.wchange17")} BTC - -
    -
    -
    - - ${translate("general.close")} - -
    - - -
    -
    - -

    ${translate("walletpage.wchange17")} LTC

    -
    -
    -

    - ${translate("walletpage.wchange18")}:
    - ${this.getSelectedWalletAddress()} -

    -

    - ${translate("walletpage.wchange19")}:
    - ${this.balanceString}
    - - this.calculateLtcAll()}> ${translate("walletpage.wchange45")} LTC -
      -

    -

    - - -

    -

    - - -

    -
    -

    ${translate("walletpage.wchange24")}: ${(this.ltcFeePerByte / 1e8).toFixed(8)} LTC
    ${translate("walletpage.wchange25")}

    - - -
    - ${this.renderClearSuccess()} - ${this.renderClearError()} - ${this.sendMoneyLoading ? html` ` : ''} -
    -
    - this.sendLtc()}> - - ${translate("walletpage.wchange17")} LTC - -
    -
    -
    - - ${translate("general.close")} - -
    - - -
    -
    - -

    ${translate("walletpage.wchange17")} DOGE

    -
    -
    -

    - ${translate("walletpage.wchange18")}:
    - ${this.getSelectedWalletAddress()} -

    -

    - ${translate("walletpage.wchange19")}:
    - ${this.balanceString}
    - - this.calculateDogeAll()}> ${translate("walletpage.wchange45")} DOGE -
      -

    -

    - - -

    -

    - - -

    -
    -

    - ${translate("walletpage.wchange24")}: ${(this.dogeFeePerByte / 1e8).toFixed(8)} DOGE
    ${translate("walletpage.wchange25")} -

    - - -
    - ${this.renderClearSuccess()} - ${this.renderClearError()} - ${this.sendMoneyLoading ? html` ` : ''} -
    -
    - this.sendDoge()}> - - ${translate("walletpage.wchange17")} DOGE - -
    -
    -
    - - ${translate("general.close")} - -
    - - -
    -
    - -

    ${translate("walletpage.wchange17")} DGB

    -
    -
    -

    - ${translate("walletpage.wchange18")}:
    - ${this.getSelectedWalletAddress()} -

    -

    - ${translate("walletpage.wchange19")}:
    - ${this.balanceString}
    - - this.calculateDgbAll()}> ${translate("walletpage.wchange45")} DGB -
      -

    -

    - - -

    -

    - - -

    -
    -

    - ${translate("walletpage.wchange24")}: ${(this.dgbFeePerByte / 1e8).toFixed(8)} DGB
    ${translate("walletpage.wchange25")} -

    - - -
    - ${this.renderClearSuccess()} - ${this.renderClearError()} - ${this.sendMoneyLoading ? html` ` : ''} -
    -
    - this.sendDgb()}> - - ${translate("walletpage.wchange17")} DGB - -
    -
    -
    - - ${translate("general.close")} - -
    - - -
    -
    - -

    ${translate("walletpage.wchange17")} RVN

    -
    -
    -

    - ${translate("walletpage.wchange18")}:
    - ${this.getSelectedWalletAddress()} -

    -

    - ${translate("walletpage.wchange19")}:
    - ${this.balanceString}
    - - this.calculateRvnAll()}> ${translate("walletpage.wchange45")} RVN -
      -

    -

    - - -

    -

    - - -

    -
    -

    - ${translate("walletpage.wchange24")}: ${(this.rvnFeePerByte / 1e8).toFixed(8)} RVN
    ${translate("walletpage.wchange25")} -

    - - -
    - ${this.renderClearSuccess()} - ${this.renderClearError()} - ${this.sendMoneyLoading ? html` ` : ''} -
    -
    - this.sendRvn()}> - - ${translate("walletpage.wchange17")} RVN - -
    -
    -
    - - ${translate("general.close")} - -
    - - -
    -
    - -

    ${translate("walletpage.wchange17")} ARRR

    -
    -
    -

    - ${translate("walletpage.wchange18")}:
    - ${this.getSelectedWalletAddress()} -

    -

    - ${translate("walletpage.wchange19")}:
    - ${this.balanceString}
    - - this.calculateArrrAll()}> ${translate("walletpage.wchange45")} ARRR -
      -

    -

    - - -

    -

    - - -

    -

    - - -

    -

    ${this.errorMessage}

    -

    ${this.successMessage}

    - ${this.sendMoneyLoading ? html` ` : ''} -
    -
    - this.sendArrr()}> - - ${translate("walletpage.wchange17")} ARRR - -
    -
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Qortal ${translate("walletpage.wchange47")}

    -
    -
    ${this.renderExportAddressbookButton()}
    ${this.renderImportAddressbookButton()}


    -
    -
    - - - - { - render(html`${this.renderSendFromQortAddressbookButton(data.item)}`, root); - }}> - - { - render(html` this.removeQortAddress(data.item.address)}>delete ${translate("nodepage.nchange12")}`, root) - }}> - - - ${this.isEmptyArray(this.qortBook) ? html` - ${translate("walletpage.wchange48")} - `: ''} - - ${translate("general.close")} - - this.openAddToQortAddressbook()} - > - ${translate("rewardsharepage.rchange14")} - -
    - - -
    - -

    Bitcoin ${translate("walletpage.wchange47")}

    -
    -
    ${this.renderExportAddressbookButton()}
    ${this.renderImportAddressbookButton()}


    -
    -
    - - - - { - render(html`${this.renderSendFromBtcAddressbookButton(data.item)}`, root); - }}> - - { - render(html` this.removeBtcAddress(data.item.address)}>delete ${translate("nodepage.nchange12")}`, root) - }}> - - - ${this.isEmptyArray(this.btcBook) ? html` - ${translate("walletpage.wchange48")} - `: ''} - - ${translate("general.close")} - - this.openAddToBtcAddressbook()} - > - ${translate("rewardsharepage.rchange14")} - -
    - - -
    - -

    Litecoin ${translate("walletpage.wchange47")}

    -
    -
    ${this.renderExportAddressbookButton()}
    ${this.renderImportAddressbookButton()}


    -
    -
    - - - - { - render(html`${this.renderSendFromLtcAddressbookButton(data.item)}`, root); - }}> - - { - render(html` this.removeLtcAddress(data.item.address)}>delete ${translate("nodepage.nchange12")}`, root) - }}> - - - ${this.isEmptyArray(this.ltcBook) ? html` - ${translate("walletpage.wchange48")} - `: ''} - - ${translate("general.close")} - - this.openAddToLtcAddressbook()} - > - ${translate("rewardsharepage.rchange14")} - -
    - - -
    - -

    Dogecoin ${translate("walletpage.wchange47")}

    -
    -
    ${this.renderExportAddressbookButton()}
    ${this.renderImportAddressbookButton()}


    -
    -
    - - - - { - render(html`${this.renderSendFromDogeAddressbookButton(data.item)}`, root); - }}> - - { - render(html` this.removeDogeAddress(data.item.address)}>delete ${translate("nodepage.nchange12")}`, root) - }}> - - - ${this.isEmptyArray(this.dogeBook) ? html` - ${translate("walletpage.wchange48")} - `: ''} - - ${translate("general.close")} - - this.openAddToDogeAddressbook()} - > - ${translate("rewardsharepage.rchange14")} - -
    - - -
    - -

    Digibyte ${translate("walletpage.wchange47")}

    -
    -
    ${this.renderExportAddressbookButton()}
    ${this.renderImportAddressbookButton()}


    -
    -
    - - - - { - render(html`${this.renderSendFromDgbAddressbookButton(data.item)}`, root); - }}> - - { - render(html` this.removeDgbAddress(data.item.address)}>delete ${translate("nodepage.nchange12")}`, root) - }}> - - - ${this.isEmptyArray(this.dgbBook) ? html` - ${translate("walletpage.wchange48")} - `: ''} - - ${translate("general.close")} - - this.openAddToDgbAddressbook()} - > - ${translate("rewardsharepage.rchange14")} - -
    - - -
    - -

    Ravencoin ${translate("walletpage.wchange47")}

    -
    -
    ${this.renderExportAddressbookButton()}
    ${this.renderImportAddressbookButton()}


    -
    -
    - - - - { - render(html`${this.renderSendFromRvnAddressbookButton(data.item)}`, root); - }}> - - { - render(html` this.removeRvnAddress(data.item.address)}>delete ${translate("nodepage.nchange12")}`, root) - }}> - - - ${this.isEmptyArray(this.rvnBook) ? html` - ${translate("walletpage.wchange48")} - `: ''} - - ${translate("general.close")} - - this.openAddToRvnAddressbook()} - > - ${translate("rewardsharepage.rchange14")} - -
    - - -
    - -

    Pirate Chain ${translate("walletpage.wchange47")}

    -
    -
    ${this.renderExportAddressbookButton()}
    ${this.renderImportAddressbookButton()}


    -
    -
    - - - - { - render(html`${this.renderSendFromArrrAddressbookButton(data.item)}`, root); - }}> - - { - render(html` this.removeArrrAddress(data.item.address)}>delete ${translate("nodepage.nchange12")}`, root) - }}> - - - ${this.isEmptyArray(this.arrrBook) ? html` - ${translate("walletpage.wchange48")} - `: ''} - - ${translate("general.close")} - - this.openAddToArrrAddressbook()} - > - ${translate("rewardsharepage.rchange14")} - -
    - - -
    - -

    Qortal ${translate("walletpage.wchange47")}


    -

    ${translate("walletpage.wchange49")}

    -
    -
    -
    -
    -

    - - -

    -

    - - -

    -
    -
    -
    - this.addToQortalAddressbook()}> - - ${translate("walletpage.wchange49")} - -
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Bitcoin ${translate("walletpage.wchange47")}


    -

    ${translate("walletpage.wchange49")}

    -
    -
    -
    -
    -

    - - -

    -

    - - -

    -
    -
    -
    - this.addToBitcoinAddressbook()}> - - ${translate("walletpage.wchange49")} - -
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Litecoin ${translate("walletpage.wchange47")}


    -

    ${translate("walletpage.wchange49")}

    -
    -
    -
    -
    -

    - - -

    -

    - - -

    -
    -
    -
    - this.addToLitecoinAddressbook()}> - - ${translate("walletpage.wchange49")} - -
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Dogecoin ${translate("walletpage.wchange47")}


    -

    ${translate("walletpage.wchange49")}

    -
    -
    -
    -
    -

    - - -

    -

    - - -

    -
    -
    -
    - this.addToDogecoinAddressbook()}> - - ${translate("walletpage.wchange49")} - -
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Digibyte ${translate("walletpage.wchange47")}


    -

    ${translate("walletpage.wchange49")}

    -
    -
    -
    -
    -

    - - -

    -

    - - -

    -
    -
    -
    - this.addToDigibyteAddressbook()}> - - ${translate("walletpage.wchange49")} - -
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Ravencoin ${translate("walletpage.wchange47")}


    -

    ${translate("walletpage.wchange49")}

    -
    -
    -
    -
    -

    - - -

    -

    - - -

    -
    -
    -
    - this.addToRavencoinAddressbook()}> - - ${translate("walletpage.wchange49")} - -
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Pirate Chain ${translate("walletpage.wchange47")}


    -

    ${translate("walletpage.wchange49")}

    -
    -
    -
    -
    -

    - - -

    -

    - - -

    -
    -
    -
    - this.addToPiratechainAddressbook()}> - - ${translate("walletpage.wchange49")} - -
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Qortal ${translate("walletpage.wchange53")}


    -
    -
    -
    -
    - -

    ${translate("walletpage.wchange56")}

    -
    ${translate("walletpage.wchange55")}
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Bitcoin ${translate("walletpage.wchange53")}


    -
    -
    -
    -
    - -

    ${translate("walletpage.wchange56")}

    -
    ${translate("walletpage.wchange55")}
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Litecoin ${translate("walletpage.wchange53")}


    -
    -
    -
    -
    - -

    ${translate("walletpage.wchange56")}

    -
    ${translate("walletpage.wchange55")}
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Dogecoin ${translate("walletpage.wchange53")}


    -
    -
    -
    -
    - -

    ${translate("walletpage.wchange56")}

    -
    ${translate("walletpage.wchange55")}
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Digibyte ${translate("walletpage.wchange53")}


    -
    -
    -
    -
    - -

    ${translate("walletpage.wchange56")}

    -
    ${translate("walletpage.wchange55")}
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Litecoin ${translate("walletpage.wchange53")}


    -
    -
    -
    -
    - -

    ${translate("walletpage.wchange56")}

    -
    ${translate("walletpage.wchange55")}
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Pirate Chain ${translate("walletpage.wchange53")}


    -
    -
    -
    -
    - -

    ${translate("walletpage.wchange56")}

    -
    ${translate("walletpage.wchange55")}
    -
    - - ${translate("general.close")} - -
    -
    - -
    -

    Qortal ${translate("tabmenu.tm5")} ${translate("login.lp1")}

    -
    -
    -
    -

    ${translate("login.lp2")}

    -

    ${translate("login.lp3")}

    -
    -
    - password - -
    -
    - password - -
    -
    - ${translate("login.lp4")} - ${translate("login.lp5")} -
    -
    - -
    -

    Qortal ${translate("tabmenu.tm5")} ${translate("login.lp1")}

    -
    -
    -
    -

    ${translate("login.lessthen8")}

    -
    -
    - ${translate("login.lp4")} - ${translate("login.lp5")} -
    -
    - -
    - ${translate("sidemenu.wallets")}
    - ${translate("login.lp9")} - ${translate("login.lp10")} -
    -
    - password - -
    - ${this.walletHelperMessage} -
    -
    -
    -
    - -
    -
    - ` - } - - firstUpdated() { - - this.changeTheme() - this.changeLanguage() - this.paymentFee() - this.getNodeConfig() - - this.bookQortalAddress = window.parent.reduxStore.getState().app.selectedAddress.address - this.bookBitcoinAddress = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address - this.bookLitecoinAddress = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address - this.bookDogecoinAddress = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address - this.bookDigibyteAddress = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address - this.bookRavencoinAddress = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address - this.bookPiratechainAddress = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address - - this.walletHelperMessage = this.renderWalletHelperPass() - - this.walletSalt = '' - this.walletSalt = Base58.encode(window.parent.reduxStore.getState().app.wallet._addresses[0].keyPair.privateKey) - - this.walletStorageData = '' - this.walletStorageData = window.parent.reduxStore.getState().app.selectedAddress.address - - this.walletLockScreenPass = '' - this.walletLockScreenPass = 'walletLockScreenPass-' + this.walletStorageData - - this.walletLockScreenSet = '' - this.walletLockScreenSet = 'walletLockScreenSet-' + this.walletStorageData - - this.walletLockPass = '' - this.walletLockPass = encryptData(false, this.walletSalt) - - this.walletLockSet = '' - this.walletLockSet = encryptData(false, this.walletSalt) - - if (localStorage.getItem(this.walletLockScreenPass) === null && localStorage.getItem(this.walletLockScreenSet) === null) { - localStorage.setItem(this.walletLockScreenPass, this.walletLockPass) - localStorage.setItem(this.walletLockScreenSet, this.walletLockSet) - this.myWalletLockScreenPass = '' - this.myWalletLockScreenPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt) - this.myWalletLockScreenSet = '' - this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt) - } else { - this.myWalletLockScreenPass = '' - this.myWalletLockScreenPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt) - this.myWalletLockScreenSet = '' - this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt) - } - - if (this.myWalletLockScreenSet === true) { - this.shadowRoot.getElementById('walletLockScreenActive').open() - } - - this.qortAddressbook() - this.btcAddressbook() - this.ltcAddressbook() - this.dogeAddressbook() - this.dgbAddressbook() - this.rvnAddressbook() - this.arrrAddressbook() - - this.transactionsDOM = this.shadowRoot.getElementById('transactionsDOM') - - this.showWallet() - - window.addEventListener('storage', () => { - const checkLanguage = localStorage.getItem('qortalLanguage') - const checkTheme = localStorage.getItem('qortalTheme') - - use(checkLanguage) - - if (checkTheme === 'dark') { - this.theme = 'dark' - } else { - this.theme = 'light' - } - document.querySelector('html').setAttribute('theme', this.theme) - }) - - if (!isElectron()) { - } else { - window.addEventListener('contextmenu', (event) => { - event.preventDefault() - window.parent.electronAPI.showMyMenu() - }) - } - - this.clearConsole() - - setInterval(() => { - this.clearConsole() - this.getNodeConfig() - }, 60000) - - setInterval(() => { - this.paymentFee() - }, 600000) - } - - async paymentFee() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/transactions/unitfee?txType=PAYMENT` - await fetch(url).then((response) => { - if (response.ok) { - return response.json() - } - return Promise.reject(response) - }).then((json) => { - this.qortPaymentFee = (Number(json) / 1e8).toFixed(8) - }) - } - - clearConsole() { - if (!isElectron()) { - } else { - console.clear() - window.parent.electronAPI.clearCache() - } - } - - pingCoinBalancesController(){ - if(!this._selectedWallet) return - const customEvent = new CustomEvent('ping-coin-controller-with-coin', { - detail: this._selectedWallet - }); - window.parent.dispatchEvent(customEvent); - } - - connectedCallback() { - super.connectedCallback() - this.intervalID = setInterval(this.pingCoinBalancesController, 30000) - } - - disconnectedCallback() { - super.disconnectedCallback() - if(this.intervalID) { - clearInterval(this.intervalID) - } - } - - renderWalletLockButton() { - if (this.myWalletLockScreenPass === false && this.myWalletLockScreenSet === false) { - return html` -
    - this.openWalletSetScreenLockPass()} title="${translate("login.lp11")}"> -
    - ` - } else if (this.myWalletLockScreenSet === false) { - return html` -
    - this.setWalletLockQortal()} title="${translate("login.lp11")}"> -
    - ` - } else if (this.myWalletLockScreenSet === true) { - return html` -
    - -
    - ` - } - } - - openWalletSetScreenLockPass() { - this.shadowRoot.getElementById('walletLockPassword').value = '' - this.shadowRoot.getElementById('walletLockPasswordConfirm').value = '' - this.shadowRoot.getElementById('setWalletLockScreenPass').open() - } - - closewWalletSetScreenLockPass() { - this.shadowRoot.getElementById('setWalletLockScreenPass').close() - } - - walletCheckPass() { - const walletPassword = this.shadowRoot.getElementById('walletLockPassword').value - const walletRePassword = this.shadowRoot.getElementById('walletLockPasswordConfirm').value - - if (walletPassword === '') { - let snackbar1string = get("login.pleaseenter") - parentEpml.request('showSnackBar', `${snackbar1string}`) - return - } - - if (walletPassword != walletRePassword) { - let snackbar2string = get("login.notmatch") - parentEpml.request('showSnackBar', `${snackbar2string}`) - return - } - - if (walletPassword.length < 8) { - let snackbar3string = get("login.lessthen8") - parentEpml.request('showSnackBar', `${snackbar3string}`) - this.walletExtraConfirm() - } - - if (walletPassword.length >= 8) { - this.setWalletNewScreenPass() - let snackbar4string = get("login.lp6") - parentEpml.request('showSnackBar', `${snackbar4string}`) - } - } - - walletExtraConfirm() { - this.shadowRoot.getElementById('setWalletLockScreenPass').close() - this.shadowRoot.getElementById('walletExtraConfirmPass').open() - } - - closWalletExtraConfirmPass() { - this.shadowRoot.getElementById('walletExtraConfirmPass').close() - this.shadowRoot.getElementById('walletLockPassword').value = '' - this.shadowRoot.getElementById('walletLockPasswordConfirm').value = '' - } - - setWalletNewScreenPass() { - const walletRawPassword = this.shadowRoot.getElementById('walletLockPassword').value - const walletCryptPassword = encryptData(walletRawPassword, this.walletSalt) - localStorage.setItem(this.walletLockScreenPass, walletCryptPassword) - this.myWalletLockScreenPass = '' - this.myWalletLockScreenPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt) - this.shadowRoot.getElementById('setWalletLockScreenPass').close() - this.shadowRoot.getElementById('walletExtraConfirmPass').close() - this.shadowRoot.getElementById('walletLockPassword').value = '' - this.shadowRoot.getElementById('walletLockPasswordConfirm').value = '' - } - - setWalletLockQortal() { - this.walletHelperMessage = this.renderWalletHelperPass() - this.walletLockSet = '' - this.walletLockSet = encryptData(true, this.walletSalt) - localStorage.setItem(this.walletLockScreenSet, this.walletLockSet) - this.myWalletLockScreenSet = '' - this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt) - this.shadowRoot.getElementById('walletLockScreenActive').open() - } - - walletPassKeyListener(e) { - if (e.key === 'Enter') { - this.closeWalletLockScreenActive() - } - } - - async closeWalletLockScreenActive() { - const myWalletPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt) - const walletCheckPass = this.shadowRoot.getElementById('walletUnlockPassword').value - const errDelay = ms => new Promise(res => setTimeout(res, ms)) - - if (walletCheckPass === myWalletPass) { - this.walletLockSet = '' - this.walletLockSet = encryptData(false, this.walletSalt) - localStorage.setItem(this.walletLockScreenSet, this.walletLockSet) - this.myWalletLockScreenSet = '' - this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt) - this.shadowRoot.getElementById('walletLockScreenActive').close() - this.shadowRoot.getElementById('walletUnlockPassword').value = '' - this.walletHelperMessage = this.renderWalletHelperPass() - } else { - this.shadowRoot.getElementById('walletUnlockPassword').value = '' - this.walletHelperMessage = this.renderWalletHelperErr() - await errDelay(3000) - this.walletHelperMessage = this.renderWalletHelperPass() - - } - } - - renderWalletHelperPass() { - return html`${translate("login.pleaseenter")}` - } - - renderWalletHelperErr() { - return html`${translate("login.lp8")}` - } - - renderWarning() { - return html`${translate("tradepage.tchange48")} QORT` - } - - renderClearSuccess() { - let strSuccessValue = this.successMessage - if (strSuccessValue === "") { - return html`` - } else { - return html` -
    - ${this.successMessage} - -
    -
    -

    ${translate("walletpage.wchange43")}

    -
    - ` - } - } - - renderClearError() { - let strErrorValue = this.errorMessage - if (strErrorValue === "") { - return html`` - } else { - return html` -
    - ${this.errorMessage} - -
    -
    -

    ${translate("walletpage.wchange44")}

    -
    - ` - } - } - - tabWalletQort() { - this._selectedWallet = 'qort' - this.showWallet() - } - - tabWalletBtc() { - this._selectedWallet = 'btc' - this.showWallet() - } - - tabWalletLtc() { - this._selectedWallet = 'ltc' - this.showWallet() - } - - tabWalletDoge() { - this._selectedWallet = 'doge' - this.showWallet() - } - - tabWalletDgb() { - this._selectedWallet = 'dgb' - this.showWallet() - } - - tabWalletRvn() { - this._selectedWallet = 'rvn' - this.showWallet() - } - - tabWalletArrr() { - this._selectedWallet = 'arrr' - this.showWallet() - } - - qortAddressbook() { - const storedQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress - if (localStorage.getItem(storedQortalAddressBook) === null) { - localStorage.setItem(storedQortalAddressBook, "") - } else { - this.qortBook = JSON.parse(localStorage.getItem(storedQortalAddressBook) || "[]") - } - } - - btcAddressbook() { - const storedBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress - if (localStorage.getItem(storedBitcoinAddressBook) === null) { - localStorage.setItem(storedBitcoinAddressBook, "") - } else { - this.btcBook = JSON.parse(localStorage.getItem(storedBitcoinAddressBook) || "[]") - } - } - - ltcAddressbook() { - const storedLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress - if (localStorage.getItem(storedLitecoinAddressBook) === null) { - localStorage.setItem(storedLitecoinAddressBook, "") - } else { - this.ltcBook = JSON.parse(localStorage.getItem(storedLitecoinAddressBook) || "[]") - } - } - - dogeAddressbook() { - const storedDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress - if (localStorage.getItem(storedDogecoinAddressBook) === null) { - localStorage.setItem(storedDogecoinAddressBook, "") - } else { - this.dogeBook = JSON.parse(localStorage.getItem(storedDogecoinAddressBook) || "[]") - } - } - - dgbAddressbook() { - const storedDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress - if (localStorage.getItem(storedDigibyteAddressBook) === null) { - localStorage.setItem(storedDigibyteAddressBook, "") - } else { - this.dgbBook = JSON.parse(localStorage.getItem(storedDigibyteAddressBook) || "[]") - } - } - - rvnAddressbook() { - const storedRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress - if (localStorage.getItem(storedRavencoinAddressBook) === null) { - localStorage.setItem(storedRavencoinAddressBook, "") - } else { - this.rvnBook = JSON.parse(localStorage.getItem(storedRavencoinAddressBook) || "[]") - } - } - - arrrAddressbook() { - const storedPiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress - if (localStorage.getItem(storedPiratechainAddressBook) === null) { - localStorage.setItem(storedPiratechainAddressBook, "") - } else { - this.arrrBook = JSON.parse(localStorage.getItem(storedPiratechainAddressBook) || "[]") - } - } - - openQortAddressbook() { - this.shadowRoot.querySelector("#qortBookDialog").show() - } - - openBtcAddressbook() { - this.shadowRoot.querySelector("#btcBookDialog").show() - } - - openLtcAddressbook() { - this.shadowRoot.querySelector("#ltcBookDialog").show() - } - - openDogeAddressbook() { - this.shadowRoot.querySelector("#dogeBookDialog").show() - } - - openDgbAddressbook() { - this.shadowRoot.querySelector("#dgbBookDialog").show() - } - - openRvnAddressbook() { - this.shadowRoot.querySelector("#rvnBookDialog").show() - } - - openArrrAddressbook() { - this.shadowRoot.querySelector("#arrrBookDialog").show() - } - - openAddQortAddressDialog() { - this.qortBookAddress = this.selectedTransaction.recipient - this.openAddToQortAddressbook() - this.shadowRoot.querySelector('#showTransactionDetailsDialog').close() - } - - openAddBtcAddressDialog() { - this.btcBookAddress = this.selectedTransaction.btcReceiver - this.openAddToBtcAddressbook() - this.shadowRoot.querySelector('#showBtcTransactionDetailsDialog').close() - } - - openAddLtcAddressDialog() { - this.ltcBookAddress = this.selectedTransaction.ltcReceiver - this.openAddToLtcAddressbook() - this.shadowRoot.querySelector('#showLtcTransactionDetailsDialog').close() - } - - openAddDogeAddressDialog() { - this.dogeBookAddress = this.selectedTransaction.dogeReceiver - this.openAddToDogeAddressbook() - this.shadowRoot.querySelector('#showDogeTransactionDetailsDialog').close() - } - - openAddDgbAddressDialog() { - this.dgbBookAddress = this.selectedTransaction.dgbReceiver - this.openAddToDgbAddressbook() - this.shadowRoot.querySelector('#showDgbTransactionDetailsDialog').close() - } - - openAddRvnAddressDialog() { - this.rvnBookAddress = this.selectedTransaction.rvnReceiver - this.openAddToRvnAddressbook() - this.shadowRoot.querySelector('#showRvnTransactionDetailsDialog').close() - } - - openAddArrrAddressDialog() { - this.arrrBookAddress = this.selectedTransaction.arrrReceiver - this.openAddToArrrAddressbook() - this.shadowRoot.querySelector('#showArrrTransactionDetailsDialog').close() - } - - openAddToQortAddressbook() { - this.shadowRoot.querySelector("#addQortAddressDialog").show() - } - - openAddToBtcAddressbook() { - this.shadowRoot.querySelector("#addBtcAddressDialog").show() - } - - openAddToLtcAddressbook() { - this.shadowRoot.querySelector("#addLtcAddressDialog").show() - } - - openAddToDogeAddressbook() { - this.shadowRoot.querySelector("#addDogeAddressDialog").show() - } - - openAddToDgbAddressbook() { - this.shadowRoot.querySelector("#addDgbAddressDialog").show() - } - - openAddToRvnAddressbook() { - this.shadowRoot.querySelector("#addRvnAddressDialog").show() - } - - openAddToArrrAddressbook() { - this.shadowRoot.querySelector("#addArrrAddressDialog").show() - } - - openImportQortAddressbook() { - this.shadowRoot.querySelector("#importQortAddressbookDialog").show() - } - - openImportBtcAddressbook() { - this.shadowRoot.querySelector("#importBtcAddressbookDialog").show() - } - - openImportLtcAddressbook() { - this.shadowRoot.querySelector("#importLtcAddressbookDialog").show() - } - - openImportDogeAddressbook() { - this.shadowRoot.querySelector("#importDogeAddressbookDialog").show() - } - - openImportDgbAddressbook() { - this.shadowRoot.querySelector("#importDgbAddressbookDialog").show() - } - - openImportRvnAddressbook() { - this.shadowRoot.querySelector("#importRvnAddressbookDialog").show() - } - - openImportArrrAddressbook() { - this.shadowRoot.querySelector("#importArrrAddressbookDialog").show() - } - - closeQortAddressDialog() { - this.shadowRoot.querySelector('#addQortAddressDialog').close() - this.shadowRoot.getElementById('qortNameInput').value = '' - this.shadowRoot.getElementById('qortAddressInput').value = '' - this.qortBookName = '' - this.qortBookAddress = '' - } - - closeBtcAddressDialog() { - this.shadowRoot.querySelector('#addBtcAddressDialog').close() - this.shadowRoot.getElementById('btcNameInput').value = '' - this.shadowRoot.getElementById('btcAddressInput').value = '' - this.btcBookName = '' - this.btcBookAddress = '' - } - - closeLtcAddressDialog() { - this.shadowRoot.querySelector('#addLtcAddressDialog').close() - this.shadowRoot.getElementById('ltcNameInput').value = '' - this.shadowRoot.getElementById('ltcAddressInput').value = '' - this.ltcBookName = '' - this.ltcBookAddress = '' - } - - closeDogeAddressDialog() { - this.shadowRoot.querySelector('#addDogeAddressDialog').close() - this.shadowRoot.getElementById('dogeNameInput').value = '' - this.shadowRoot.getElementById('dogeAddressInput').value = '' - this.dogeBookName = '' - this.dogeBookAddress = '' - } - - closeDgbAddressDialog() { - this.shadowRoot.querySelector('#addDgbAddressDialog').close() - this.shadowRoot.getElementById('dgbNameInput').value = '' - this.shadowRoot.getElementById('dgbAddressInput').value = '' - this.dgbBookName = '' - this.dgbBookAddress = '' - } - - closeRvnAddressDialog() { - this.shadowRoot.querySelector('#addRvnAddressDialog').close() - this.shadowRoot.getElementById('rvnNameInput').value = '' - this.shadowRoot.getElementById('rvnAddressInput').value = '' - this.rvnBookName = '' - this.rvnBookAddress = '' - } - - closeArrrAddressDialog() { - this.shadowRoot.querySelector('#addArrrAddressDialog').close() - this.shadowRoot.getElementById('arrrNameInput').value = '' - this.shadowRoot.getElementById('arrrAddressInput').value = '' - this.arrrBookName = '' - this.arrrBookAddress = '' - } - - closeImportQortAddressbookDialog() { - this.shadowRoot.querySelector("#importQortAddressbookDialog").close() - } - - closeImportBtcAddressbookDialog() { - this.shadowRoot.querySelector("#importBtcAddressbookDialog").close() - } - - closeImportLtcAddressbookDialog() { - this.shadowRoot.querySelector("#importLtcAddressbookDialog").close() - } - - closeImportDogeAddressbookDialog() { - this.shadowRoot.querySelector("#importDogeAddressbookDialog").close() - } - - closeImportDgbAddressbookDialog() { - this.shadowRoot.querySelector("#importDgbAddressbookDialog").close() - } - - closeImportRvnAddressbookDialog() { - this.shadowRoot.querySelector("#importRvnAddressbookDialog").close() - } - - closeImportArrrAddressbookDialog() { - this.shadowRoot.querySelector("#importArrrAddressbookDialog").close() - } - - addToQortalAddressbook() { - const myQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress - - let name = this.shadowRoot.getElementById('qortNameInput').value - let address = this.shadowRoot.getElementById('qortAddressInput').value - - var oldQortalBook = JSON.parse(localStorage.getItem(myQortalAddressBook) || "[]") - - if (name.length === 0) { - let qortbookstring1 = get("walletpage.wchange50") - parentEpml.request('showSnackBar', `${qortbookstring1}`) - return false - } - - if (address.length === 0) { - let qortbookstring2 = get("walletpage.wchange51") - parentEpml.request('showSnackBar', `${qortbookstring2}`) - return false - } - - const newQortalBookItem = { - name: name, - address: address - } - - oldQortalBook.push(newQortalBookItem) - - localStorage.setItem(myQortalAddressBook, JSON.stringify(oldQortalBook)) - - let qortbookstring2 = get("walletpage.wchange52") - parentEpml.request('showSnackBar', `${qortbookstring2}`) - - this.closeQortAddressDialog() - this.qortBook = JSON.parse(localStorage.getItem(myQortalAddressBook) || "[]") - } - - addToBitcoinAddressbook() { - const myBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress + static get properties() { + return { + loading: { type: Boolean }, + transactions: { type: Object }, + lastBlock: { type: Object }, + selectedTransaction: { type: Object }, + isTextMenuOpen: { type: Boolean }, + wallets: { type: Map }, + _selectedWallet: 'qort', + nodeConfig: { type: Object }, + nodeDomain: { type: String }, + theme: { type: String, reflect: true }, + amount: { type: Number }, + recipient: { type: String }, + btcRecipient: { type: String }, + btcAmount: { type: Number }, + ltcRecipient: { type: String }, + ltcAmount: { type: Number }, + dogeRecipient: { type: String }, + dogeAmount: { type: Number }, + dgbRecipient: { type: String }, + dgbAmount: { type: Number }, + rvnRecipient: { type: String }, + rvnAmount: { type: Number }, + arrrRecipient: { type: String }, + arrrAmount: { type: Number }, + arrrMemo: { type: String }, + errorMessage: { type: String }, + arrrWalletAddress: { type: String }, + unusedWalletAddress: { type: String }, + successMessage: { type: String }, + sendMoneyLoading: { type: Boolean }, + btnDisable: { type: Boolean }, + qortWarning: { type: Boolean }, + isValidAmount: { type: Boolean }, + balance: { type: Number }, + balanceString: { type: String }, + btcServer: { type: Number }, + ltcServer: { type: Number }, + dogeServer: { type: Number }, + dgbServer: { type: Number }, + rvnServer: { type: Number }, + arrrServer: { type: Number }, + qortPaymentFee: { type: Number }, + btcFeePerByte: { type: Number }, + ltcFeePerByte: { type: Number }, + dogeFeePerByte: { type: Number }, + dgbFeePerByte: { type: Number }, + rvnFeePerByte: { type: Number }, + qortBook: { type: Array }, + btcBook: { type: Array }, + ltcBook: { type: Array }, + dogeBook: { type: Array }, + dgbBook: { type: Array }, + rvnBook: { type: Array }, + arrrBook: { type: Array }, + qortBookName: { type: String }, + btcBookName: { type: String }, + ltcBookName: { type: String }, + dogeBookName: { type: String }, + dgbBookName: { type: String }, + rvnBookName: { type: String }, + arrrBookName: { type: String }, + qortBookAddress: { type: String }, + btcBookAddress: { type: String }, + ltcBookAddress: { type: String }, + dogeBookAddress: { type: String }, + dgbBookAddress: { type: String }, + rvnBookAddress: { type: String }, + arrrBookAddress: { type: String }, + myElementId: { type: String }, + walletSalt: { type: String }, + walletStorageData: { type: String }, + walletLockScreenPass: { type: String }, + walletLockScreenSet: { type: String }, + walletLockPass: { type: String }, + walletLockSet: { type: String }, + myWalletLockScreenPass: { type: String }, + myWalletLockScreenSet: { type: String }, + walletHelperMessage: { type: String }, + bookQortalAddress: { type: String }, + bookBitcoinAddress: { type: String }, + bookLitecoinAddress: { type: String }, + bookDogecoinAddress: { type: String }, + bookDigibyteAddress: { type: String }, + bookRavencoinAddress: { type: String }, + bookPiratechainAddress: { type: String } + } + } + + static get styles() { + return [multiWalletStyles] + } + + static get observers() { + return ['_kmxKeyUp(amount)'] + } + + constructor() { + super() + this.lastBlock = { + height: 0 + } + this.balanceString = this.renderFetchText() + this.selectedTransaction = {} + this.isTextMenuOpen = false + this.loading = true + this.nodeConfig = {} + this.nodeDomain = '' + this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' + this.qortBook = [] + this.btcBook = [] + this.ltcBook = [] + this.dogeBook = [] + this.dgbBook = [] + this.rvnBook = [] + this.arrrBook = [] + this.qortBookName = '' + this.btcBookName = '' + this.ltcBookName = '' + this.dogeBookName = '' + this.dgbBookName = '' + this.rvnBookName = '' + this.arrrBookName = '' + this.qortBookAddress = '' + this.btcBookAddress = '' + this.ltcBookAddress = '' + this.dogeBookAddress = '' + this.dgbBookAddress = '' + this.rvnBookAddress = '' + this.arrrBookAddress = '' + this.recipient = '' + this.btcRecipient = '' + this.ltcRecipient = '' + this.dogeRecipient = '' + this.dgbRecipient = '' + this.rvnRecipient = '' + this.arrrRecipient = '' + this.arrrMemo = '' + this.arrrWalletAddress = '' + this.unusedWalletAddress = '' + this.btcServer = '' + this.ltcServer = '' + this.dogeServer = '' + this.dgbServer = '' + this.rvnServer = '' + this.arrrServer = '' + this.errorMessage = '' + this.successMessage = '' + this.myElementId = '' + this.sendMoneyLoading = false + this.isValidAmount = false + this.btnDisable = false + this.qortWarning = false + this.balance = 0 + this.amount = 0 + this.btcAmount = 0 + this.ltcAmount = 0 + this.dogeAmount = 0 + this.dgbAmount = 0 + this.rvnAmount = 0 + this.arrrAmount = 0 + this.qortPaymentFee = 0.001 + this.btcFeePerByte = 100 + this.btcSatMinFee = 20 + this.btcSatMaxFee = 150 + this.ltcFeePerByte = 30 + this.ltcSatMinFee = 10 + this.ltcSatMaxFee = 100 + this.dogeFeePerByte = 1000 + this.dogeSatMinFee = 100 + this.dogeSatMaxFee = 10000 + this.dgbFeePerByte = 10 + this.dgbSatMinFee = 1 + this.dgbSatMaxFee = 100 + this.rvnFeePerByte = 1125 + this.rvnSatMinFee = 1000 + this.rvnSatMaxFee = 10000 + this.walletSalt = '' + this.walletStorageData = '' + this.walletLockScreenPass = '' + this.walletLockScreenSet = '' + this.walletLockPass = '' + this.walletLockSet = '' + this.myWalletLockScreenPass = '' + this.myWalletLockScreenSet = '' + this.walletHelperMessage = '' + this.bookQortalAddress = '' + this.bookBitcoinAddress = '' + this.bookLitecoinAddress = '' + this.bookDogecoinAddress = '' + this.bookDigibyteAddress = '' + this.bookRavencoinAddress = '' + this.bookPiratechainAddress = '' + this.wallets = new Map() + + let coinProp = { + balance: 0, + wallet: null, + transactions: [], + fetchingWalletBalance: false, + fetchingWalletTransactions: false + } + + coinsNames.forEach((c, i) => { + this.wallets.set(c, { ...coinProp }) + }, this) + + this.wallets.get('qort').wallet = window.parent.reduxStore.getState().app.selectedAddress + this.wallets.get('btc').wallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet + this.wallets.get('ltc').wallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet + this.wallets.get('doge').wallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet + this.wallets.get('dgb').wallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet + this.wallets.get('rvn').wallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet + this.wallets.get('arrr').wallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet + + this._selectedWallet = 'qort' + + parentEpml.ready().then(() => { + parentEpml.subscribe('selected_address', async (selectedAddress) => { + selectedAddress = JSON.parse(selectedAddress) + if (!selectedAddress || Object.entries(selectedAddress).length === 0) return + + this.wallets.get('qort').wallet = selectedAddress + this.wallets.get('btc').wallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet + this.wallets.get('ltc').wallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet + this.wallets.get('doge').wallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet + this.wallets.get('dgb').wallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet + this.wallets.get('rvn').wallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet + this.wallets.get('arrr').wallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet + }) + parentEpml.subscribe('coin_balances', async (payload) => { + const coinBalances = JSON.parse(payload) + if (coinBalances[this._selectedWallet]) { + const res = coinBalances[this._selectedWallet].fullValue + let value = Number(res).toFixed(8) + if (this._selectedWallet !== 'qort') { + value = (Number(res) / 1e8).toFixed(8) + } + this.wallets.get(this._selectedWallet).balance = value + this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase() + this.balance = this.wallets.get(this._selectedWallet).balance + } + }) + }) + + this.pingCoinBalancesController = this.pingCoinBalancesController.bind(this) + } + + refreshWallet() { + const coin = this._selectedWallet + switch (coin) { + case 'qort': + this.tabWalletQort() + break + case 'arrr': + this.tabWalletArrr() + break + case 'btc': + this.tabWalletBtc() + break; + case 'ltc': + this.tabWalletLtc() + break; + case 'doge': + this.tabWalletDoge() + break + case 'dgb': + this.tabWalletDgb() + break; + case 'rvn': + this.tabWalletRvn() + break + default: + break + } + } + + render() { + return html` +
    +
    + ${translate("walletpage.wchange22")} ${this.renderWalletLockButton()} +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + +
    +

    +
    + ${translate("walletpage.wchange2")} + +
    +
    + ${this.getSelectedWalletAddress()} + + +
    + + ${this.balanceString} + +
    + ${this.getSelectedWalletServer()} +
    +

    +
    + ${this.renderSendButton()} +
    +
    + ${this.renderAddressbookButton()} +
    +
    + +
    +
    + ${this.loading ? html` + + ` : ''} +
    +
    +
    + +
    +

    ${translate("walletpage.wchange5")}

    +
    +
    +
    + ${translate("walletpage.wchange6")} +
    +
    + ${this.selectedTransaction.type} + ${this.selectedTransaction.txnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} +
    + ${translate("walletpage.wchange9")} +
    +
    ${this.selectedTransaction.type === 'AT' ? html`${this.selectedTransaction.atAddress}` : html`${this.selectedTransaction.creatorAddress}`}
    + ${translate("walletpage.wchange10")} +
    +
    + ${this.selectedTransaction.type === 'DEPLOY_AT' ? html`${this.renderCAB()}` : html`${this.renderSQB()}`} +
    +
    + ${!this.selectedTransaction.amount ? '' : html` + ${translate("walletpage.wchange11")} +
    +
    ${this.selectedTransaction.amount} QORT
    + `} + ${translate("walletpage.wchange12")} +
    +
    ${this.selectedTransaction.fee}
    + ${translate("walletpage.wchange13")} +
    +
    ${this.selectedTransaction.blockHeight}
    + ${translate("walletpage.wchange14")} +
    +
    ${new Date(this.selectedTransaction.timestamp).toString()}
    + ${translate("walletpage.wchange15")} +
    +
    ${this.selectedTransaction.signature}
    +
    + + ${translate("general.close")} + +
    + +
    +

    ${translate("walletpage.wchange5")}

    +
    +
    +
    + ${translate("walletpage.wchange6")} +
    +
    + ${translate("walletpage.wchange40")} + ${this.selectedTransaction.btcTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} +
    + ${translate("walletpage.wchange9")} +
    +
    + ${this.selectedTransaction.btcSender} +
    + ${translate("walletpage.wchange10")} +
    +
    + ${this.selectedTransaction.btcReceiver} + this.sendToBtcAddress()} title="${translate("walletpage.wchange46")}"> + this.openAddBtcAddressDialog()} title="${translate("walletpage.wchange49")}"> +
    +
    + ${translate("walletpage.wchange12")} +
    +
    + ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} BTC +
    + ${translate("walletpage.wchange37")} +
    +
    + ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} BTC +
    + ${translate("walletpage.wchange14")} +
    +
    ${new Date(this.selectedTransaction.timestamp).toString()}
    + ${translate("walletpage.wchange16")} +
    +
    + ${this.selectedTransaction.txHash} +
    +
    + + ${translate("general.close")} + +
    + +
    +

    ${translate("walletpage.wchange5")}

    +
    +
    +
    + ${translate("walletpage.wchange6")}e +
    +
    + ${translate("walletpage.wchange40")} + ${this.selectedTransaction.ltcTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} +
    + ${translate("walletpage.wchange9")} +
    +
    + ${this.selectedTransaction.ltcSender} +
    + ${translate("walletpage.wchange10")} +
    +
    + ${this.selectedTransaction.ltcReceiver} + this.sendToLtcAddress()} title="${translate("walletpage.wchange46")}"> + this.openAddLtcAddressDialog()} title="${translate("walletpage.wchange49")}"> +
    +
    + ${translate("walletpage.wchange12")} +
    +
    + ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} LTC +
    + ${translate("walletpage.wchange37")} +
    +
    + ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} LTC +
    + ${translate("walletpage.wchange14")} +
    +
    ${new Date(this.selectedTransaction.timestamp).toString()}
    + ${translate("walletpage.wchange16")} +
    +
    + ${this.selectedTransaction.txHash} +
    +
    + + ${translate("general.close")} + +
    + +
    +

    ${translate("walletpage.wchange5")}

    +
    +
    +
    + ${translate("walletpage.wchange6")} +
    +
    + ${translate("walletpage.wchange40")} + ${this.selectedTransaction.dogeTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} +
    + ${translate("walletpage.wchange9")} +
    +
    + ${this.selectedTransaction.dogeSender} +
    +
    + ${translate("walletpage.wchange10")} +
    +
    + ${this.selectedTransaction.dogeReceiver} + this.sendToDogeAddress()} title="${translate("walletpage.wchange46")}"> + this.openAddDogeAddressDialog()} title="${translate("walletpage.wchange49")}"> +
    +
    + ${translate("walletpage.wchange12")} +
    +
    + ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} DOGE +
    + ${translate("walletpage.wchange37")} +
    +
    + ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} DOGE +
    + ${translate("walletpage.wchange14")} +
    +
    ${new Date(this.selectedTransaction.timestamp).toString()}
    + ${translate("walletpage.wchange16")} +
    +
    + ${this.selectedTransaction.txHash} +
    +
    + + ${translate("general.close")} + +
    + +
    +

    ${translate("walletpage.wchange5")}

    +
    +
    +
    + ${translate("walletpage.wchange6")} +
    +
    + ${translate("walletpage.wchange40")} + ${this.selectedTransaction.dgbTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} +
    + ${translate("walletpage.wchange9")} +
    +
    + ${this.selectedTransaction.dgbSender} +
    + ${translate("walletpage.wchange10")} +
    +
    + ${this.selectedTransaction.dgbReceiver} + this.sendToDgbAddress()} title="${translate("walletpage.wchange46")}"> + this.openAddDgbAddressDialog()} title="${translate("walletpage.wchange49")}"> +
    +
    + ${translate("walletpage.wchange12")} +
    +
    + ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} DGB +
    + ${translate("walletpage.wchange37")} +
    +
    + ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} DGB +
    + ${translate("walletpage.wchange14")} +
    +
    ${new Date(this.selectedTransaction.timestamp).toString()}
    + ${translate("walletpage.wchange16")} +
    +
    + ${this.selectedTransaction.txHash} +
    +
    + + ${translate("general.close")} + +
    + +
    +

    ${translate("walletpage.wchange5")}

    +
    +
    +
    + ${translate("walletpage.wchange6")} +
    +
    + ${translate("walletpage.wchange40")} + ${this.selectedTransaction.rvnTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} +
    + ${translate("walletpage.wchange9")} +
    +
    + ${this.selectedTransaction.rvnSender} +
    + ${translate("walletpage.wchange10")} +
    +
    + ${this.selectedTransaction.rvnReceiver} + this.sendToRvnAddress()} title="${translate("walletpage.wchange46")}"> + this.openAddRvnAddressDialog()} title="${translate("walletpage.wchange49")}"> +
    +
    + ${translate("walletpage.wchange12")} +
    +
    + ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} RVN +
    + ${translate("walletpage.wchange37")} +
    +
    + ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} RVN +
    + ${translate("walletpage.wchange14")} +
    +
    ${new Date(this.selectedTransaction.timestamp).toString()}
    + ${translate("walletpage.wchange16")} +
    +
    + ${this.selectedTransaction.txHash} +
    +
    + + ${translate("general.close")} + +
    + +
    +

    ${translate("walletpage.wchange5")}

    +
    +
    +
    + ${translate("walletpage.wchange6")} +
    +
    + ${translate("walletpage.wchange40")} + ${this.selectedTransaction.arrrTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} +
    + ${translate("walletpage.wchange9")} +
    +
    + ${this.selectedTransaction.arrrSender} +
    + ${translate("walletpage.wchange10")} +
    +
    + ${this.selectedTransaction.arrrReceiver} + this.sendToArrrAddress()} title="${translate("walletpage.wchange46")}"> + this.openAddArrrAddressDialog()} title="${translate("walletpage.wchange49")}"> +
    +
    + ${translate("walletpage.wchange12")} +
    +
    + ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} ARRR +
    + ${translate("walletpage.wchange37")} +
    +
    + ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} ARRR +
    + ${translate("walletpage.wchange14")} +
    +
    ${new Date(this.selectedTransaction.timestamp).toString()}
    + ${translate("walletpage.wchange16")} +
    +
    + ${this.selectedTransaction.txHash} +
    +
    + + ${translate("general.close")} + +
    + +
    +
    + +

    ${translate("walletpage.wchange17")} QORT

    +
    +
    +

    + ${translate("walletpage.wchange18")}:
    + ${this.getSelectedWalletAddress()} +

    +

    + ${translate("walletpage.wchange19")}:
    + ${this.balanceString}
    + + this.calculateQortAll()}> + + ${translate("walletpage.wchange45")} QORT + + +
      +

    +

    + + +

    +

    + + +

    +
    +

    ${translate("walletpage.wchange21")} ${this.qortPaymentFee} QORT

    +
    + ${this.renderClearSuccess()} + ${this.renderClearError()} + ${this.sendMoneyLoading ? html` + + ` : ''} +
    +
    + this.sendQort()}> + + ${translate("walletpage.wchange17")} QORT + +
    ${this.renderWarning()}
    +
    +
    +
    + + ${translate("general.close")} + +
    + +
    +
    + +

    ${translate("walletpage.wchange17")} BTC

    +
    +
    +

    + From address:
    + ${this.getSelectedWalletAddress()} +

    +

    + Available balance:
    + ${this.balanceString}
    + + this.calculateBtcAll()}> + + ${translate("walletpage.wchange45")} BTC + + +
      +

    +

    + + +

    +

    + + +

    +
    +

    ${translate("walletpage.wchange24")}: ${(this.btcFeePerByte / 1e8).toFixed(8)} BTC
    ${translate("walletpage.wchange25")}

    + + +
    + ${this.renderClearSuccess()} + ${this.renderClearError()} + ${this.sendMoneyLoading ? html` + + ` : ''} +
    +
    + this.sendBtc()}> + + ${translate("walletpage.wchange17")} BTC + +
    +
    +
    + + ${translate("general.close")} + +
    + +
    +
    + +

    ${translate("walletpage.wchange17")} LTC

    +
    +
    +

    + ${translate("walletpage.wchange18")}:
    + ${this.getSelectedWalletAddress()} +

    +

    + ${translate("walletpage.wchange19")}:
    + ${this.balanceString}
    + + this.calculateLtcAll()}> + + ${translate("walletpage.wchange45")} LTC + + +
      +

    +

    + + +

    +

    + + +

    +
    +

    ${translate("walletpage.wchange24")}: ${(this.ltcFeePerByte / 1e8).toFixed(8)} LTC
    ${translate("walletpage.wchange25")}

    + + +
    + ${this.renderClearSuccess()} + ${this.renderClearError()} + ${this.sendMoneyLoading ? html` + + ` : ''} +
    +
    + this.sendLtc()}> + + ${translate("walletpage.wchange17")} LTC + +
    +
    +
    + + ${translate("general.close")} + +
    + +
    +
    + +

    ${translate("walletpage.wchange17")} DOGE

    +
    +
    +

    + ${translate("walletpage.wchange18")}:
    + ${this.getSelectedWalletAddress()} +

    +

    + ${translate("walletpage.wchange19")}:
    + ${this.balanceString}
    + + this.calculateDogeAll()}> + + ${translate("walletpage.wchange45")} DOGE + + +
      +

    +

    + + +

    +

    + + +

    +
    +

    + ${translate("walletpage.wchange24")}: ${(this.dogeFeePerByte / 1e8).toFixed(8)} DOGE
    ${translate("walletpage.wchange25")} +

    + + +
    + ${this.renderClearSuccess()} + ${this.renderClearError()} + ${this.sendMoneyLoading ? html` + + ` : ''} +
    +
    + this.sendDoge()}> + + ${translate("walletpage.wchange17")} DOGE + +
    +
    +
    + + ${translate("general.close")} + +
    + +
    +
    + +

    ${translate("walletpage.wchange17")} DGB

    +
    +
    +

    + ${translate("walletpage.wchange18")}:
    + ${this.getSelectedWalletAddress()} +

    +

    + ${translate("walletpage.wchange19")}:
    + ${this.balanceString}
    + + this.calculateDgbAll()}> + + ${translate("walletpage.wchange45")} DGB + + +
      +

    +

    + + +

    +

    + + +

    +
    +

    + ${translate("walletpage.wchange24")}: ${(this.dgbFeePerByte / 1e8).toFixed(8)} DGB
    ${translate("walletpage.wchange25")} +

    + + +
    + ${this.renderClearSuccess()} + ${this.renderClearError()} + ${this.sendMoneyLoading ? html` + + ` : ''} +
    +
    + this.sendDgb()}> + + ${translate("walletpage.wchange17")} DGB + +
    +
    +
    + + ${translate("general.close")} + +
    + +
    +
    + +

    ${translate("walletpage.wchange17")} RVN

    +
    +
    +

    + ${translate("walletpage.wchange18")}:
    + ${this.getSelectedWalletAddress()} +

    +

    + ${translate("walletpage.wchange19")}:
    + ${this.balanceString}
    + + this.calculateRvnAll()}> + + ${translate("walletpage.wchange45")} RVN + + +
      +

    +

    + + +

    +

    + + +

    +
    +

    + ${translate("walletpage.wchange24")}: ${(this.rvnFeePerByte / 1e8).toFixed(8)} RVN
    ${translate("walletpage.wchange25")} +

    + + +
    + ${this.renderClearSuccess()} + ${this.renderClearError()} + ${this.sendMoneyLoading ? html` + + ` : ''} +
    +
    + this.sendRvn()}> + + ${translate("walletpage.wchange17")} RVN + +
    +
    +
    + + ${translate("general.close")} + +
    + +
    +
    + +

    ${translate("walletpage.wchange17")} ARRR

    +
    +
    +

    + ${translate("walletpage.wchange18")}:
    + ${this.getSelectedWalletAddress()} +

    +

    + ${translate("walletpage.wchange19")}:
    + ${this.balanceString}
    + + this.calculateArrrAll()}> + + ${translate("walletpage.wchange45")} ARRR + + +
      +

    +

    + + +

    +

    + + +

    +

    + + +

    +

    ${this.errorMessage}

    +

    ${this.successMessage}

    + ${this.sendMoneyLoading ? html` + + ` : ''} +
    +
    + this.sendArrr()}> + + ${translate("walletpage.wchange17")} ARRR + +
    +
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Qortal ${translate("walletpage.wchange47")}

    +
    +
    ${this.renderExportAddressbookButton()}
    +
    ${this.renderImportAddressbookButton()}
    +

    +
    +
    + + + + { + render(html`${this.renderSendFromQortAddressbookButton(data.item)}`, root) + }}> + + { + render(html` + this.removeQortAddress(data.item.address)}> + delete +  ${translate("nodepage.nchange12")} + + `, root) + }}> + + + ${this.isEmptyArray(this.qortBook) ? html` + ${translate("walletpage.wchange48")} + `: ''} + + ${translate("general.close")} + + this.openAddToQortAddressbook()} + > + ${translate("rewardsharepage.rchange14")} + +
    + +
    + +

    Bitcoin ${translate("walletpage.wchange47")}

    +
    +
    ${this.renderExportAddressbookButton()}
    +
    ${this.renderImportAddressbookButton()}
    +

    +
    +
    + + + + { + render(html`${this.renderSendFromBtcAddressbookButton(data.item)}`, root) + }}> + + { + render(html` + this.removeBtcAddress(data.item.address)}> + delete +  ${translate("nodepage.nchange12")} + + `, root) + }}> + + + ${this.isEmptyArray(this.btcBook) ? html` + ${translate("walletpage.wchange48")} + `: ''} + + ${translate("general.close")} + + this.openAddToBtcAddressbook()} + > + ${translate("rewardsharepage.rchange14")} + +
    + +
    + +

    Litecoin ${translate("walletpage.wchange47")}

    +
    +
    ${this.renderExportAddressbookButton()}
    +
    ${this.renderImportAddressbookButton()}
    +

    +
    +
    + + + + { + render(html`${this.renderSendFromLtcAddressbookButton(data.item)}`, root) + }}> + + { + render(html` + this.removeLtcAddress(data.item.address)}> + delete +  ${translate("nodepage.nchange12")} + + `, root) + }}> + + + ${this.isEmptyArray(this.ltcBook) ? html` + ${translate("walletpage.wchange48")} + `: ''} + + ${translate("general.close")} + + this.openAddToLtcAddressbook()} + > + ${translate("rewardsharepage.rchange14")} + +
    + +
    + +

    Dogecoin ${translate("walletpage.wchange47")}

    +
    +
    ${this.renderExportAddressbookButton()}
    +
    ${this.renderImportAddressbookButton()}
    +

    +
    +
    + + + + { + render(html`${this.renderSendFromDogeAddressbookButton(data.item)}`, root) + }}> + + { + render(html` + this.removeDogeAddress(data.item.address)}> + delete +  ${translate("nodepage.nchange12")} + + `, root) + }}> + + + ${this.isEmptyArray(this.dogeBook) ? html` + ${translate("walletpage.wchange48")} + `: ''} + + ${translate("general.close")} + + this.openAddToDogeAddressbook()} + > + ${translate("rewardsharepage.rchange14")} + +
    + +
    + +

    Digibyte ${translate("walletpage.wchange47")}

    +
    +
    ${this.renderExportAddressbookButton()}
    +
    ${this.renderImportAddressbookButton()}
    +

    +
    +
    + + + + { + render(html`${this.renderSendFromDgbAddressbookButton(data.item)}`, root) + }}> + + { + render(html` + this.removeDgbAddress(data.item.address)}> + delete +  ${translate("nodepage.nchange12")} + + `, root) + }}> + + + ${this.isEmptyArray(this.dgbBook) ? html` + ${translate("walletpage.wchange48")} + `: ''} + + ${translate("general.close")} + + this.openAddToDgbAddressbook()} + > + ${translate("rewardsharepage.rchange14")} + +
    + +
    + +

    Ravencoin ${translate("walletpage.wchange47")}

    +
    +
    ${this.renderExportAddressbookButton()}
    +
    ${this.renderImportAddressbookButton()}
    +

    +
    +
    + + + + { + render(html`${this.renderSendFromRvnAddressbookButton(data.item)}`, root) + }}> + + { + render(html` + this.removeRvnAddress(data.item.address)}> + delete +  ${translate("nodepage.nchange12")} + + `, root) + }}> + + + ${this.isEmptyArray(this.rvnBook) ? html` + ${translate("walletpage.wchange48")} + `: ''} + + ${translate("general.close")} + + this.openAddToRvnAddressbook()} + > + ${translate("rewardsharepage.rchange14")} + +
    + +
    + +

    Pirate Chain ${translate("walletpage.wchange47")}

    +
    +
    ${this.renderExportAddressbookButton()}
    +
    ${this.renderImportAddressbookButton()}
    +

    +
    +
    + + + + { + render(html`${this.renderSendFromArrrAddressbookButton(data.item)}`, root) + }}> + + { + render(html` + this.removeArrrAddress(data.item.address)}> + delete +  ${translate("nodepage.nchange12")} + + `, root) + }}> + + + ${this.isEmptyArray(this.arrrBook) ? html` + ${translate("walletpage.wchange48")} + `: ''} + + ${translate("general.close")} + + this.openAddToArrrAddressbook()} + > + ${translate("rewardsharepage.rchange14")} + +
    + +
    + +

    Qortal ${translate("walletpage.wchange47")}

    +
    +

    ${translate("walletpage.wchange49")}

    +
    +
    +
    +
    +

    + + +

    +

    + + +

    +
    +
    +
    + + this.addToQortalAddressbook()}> + + ${translate("walletpage.wchange49")} + +
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Bitcoin ${translate("walletpage.wchange47")}

    +
    +

    ${translate("walletpage.wchange49")}

    +
    +
    +
    +
    +

    + + +

    +

    + + +

    +
    +
    +
    + + this.addToBitcoinAddressbook()}> + + ${translate("walletpage.wchange49")} + +
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Litecoin ${translate("walletpage.wchange47")}

    +
    +

    ${translate("walletpage.wchange49")}

    +
    +
    +
    +
    +

    + + +

    +

    + + +

    +
    +
    +
    + + this.addToLitecoinAddressbook()}> + + ${translate("walletpage.wchange49")} + +
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Dogecoin ${translate("walletpage.wchange47")}

    +
    +

    ${translate("walletpage.wchange49")}

    +
    +
    +
    +
    +

    + + +

    +

    + + +

    +
    +
    +
    + + this.addToDogecoinAddressbook()}> + + ${translate("walletpage.wchange49")} + +
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Digibyte ${translate("walletpage.wchange47")}

    +
    +

    ${translate("walletpage.wchange49")}

    +
    +
    +
    +
    +

    + + +

    +

    + + +

    +
    +
    +
    + + this.addToDigibyteAddressbook()}> + + ${translate("walletpage.wchange49")} + +
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Ravencoin ${translate("walletpage.wchange47")}

    +
    +

    ${translate("walletpage.wchange49")}

    +
    +
    +
    +
    +

    + + +

    +

    + + +

    +
    +
    +
    + + this.addToRavencoinAddressbook()}> + + ${translate("walletpage.wchange49")} + +
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Pirate Chain ${translate("walletpage.wchange47")}

    +
    +

    ${translate("walletpage.wchange49")}

    +
    +
    +
    +
    +

    + + +

    +

    + + +

    +
    +
    +
    + + this.addToPiratechainAddressbook()}> + + ${translate("walletpage.wchange49")} + +
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Qortal ${translate("walletpage.wchange53")}

    +
    +
    +
    +
    +
    + +

    ${translate("walletpage.wchange56")}

    +
    ${translate("walletpage.wchange55")}
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Bitcoin ${translate("walletpage.wchange53")}

    +
    +
    +
    +
    +
    + +

    ${translate("walletpage.wchange56")}

    +
    ${translate("walletpage.wchange55")}
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Litecoin ${translate("walletpage.wchange53")}

    +
    +
    +
    +
    +
    + +

    ${translate("walletpage.wchange56")}

    +
    ${translate("walletpage.wchange55")}
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Dogecoin ${translate("walletpage.wchange53")}

    +
    +
    +
    +
    +
    + +

    ${translate("walletpage.wchange56")}

    +
    ${translate("walletpage.wchange55")}
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Digibyte ${translate("walletpage.wchange53")}

    +
    +
    +
    +
    +
    + +

    ${translate("walletpage.wchange56")}

    +
    ${translate("walletpage.wchange55")}
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Litecoin ${translate("walletpage.wchange53")}

    +
    +
    +
    +
    +
    + +

    ${translate("walletpage.wchange56")}

    +
    ${translate("walletpage.wchange55")}
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Pirate Chain ${translate("walletpage.wchange53")}

    +
    +
    +
    +
    +
    + +

    ${translate("walletpage.wchange56")}

    +
    ${translate("walletpage.wchange55")}
    +
    + + ${translate("general.close")} + +
    +
    + +
    +

    Qortal ${translate("tabmenu.tm5")} ${translate("login.lp1")}

    +
    +
    +
    +

    ${translate("login.lp2")}

    +

    ${translate("login.lp3")}

    +
    +
    + password + +
    +
    + password + +
    +
    + ${translate("login.lp4")} + ${translate("login.lp5")} +
    +
    + +
    +

    Qortal ${translate("tabmenu.tm5")} ${translate("login.lp1")}

    +
    +
    +
    +

    ${translate("login.lessthen8")}

    +
    +
    + ${translate("login.lp4")} + ${translate("login.lp5")} +
    +
    + +
    + ${translate("sidemenu.wallets")}
    + ${translate("login.lp9")} + ${translate("login.lp10")} +
    +
    + password + +
    + ${this.walletHelperMessage} +
    +
    +
    +
    + +
    +
    + ` + } + + firstUpdated() { + + this.changeTheme() + this.changeLanguage() + this.paymentFee() + this.getNodeConfig() + + this.bookQortalAddress = window.parent.reduxStore.getState().app.selectedAddress.address + this.bookBitcoinAddress = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address + this.bookLitecoinAddress = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address + this.bookDogecoinAddress = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address + this.bookDigibyteAddress = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address + this.bookRavencoinAddress = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address + this.bookPiratechainAddress = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address + + this.walletHelperMessage = this.renderWalletHelperPass() + + this.walletSalt = '' + this.walletSalt = Base58.encode(window.parent.reduxStore.getState().app.wallet._addresses[0].keyPair.privateKey) + + this.walletStorageData = '' + this.walletStorageData = window.parent.reduxStore.getState().app.selectedAddress.address + + this.walletLockScreenPass = '' + this.walletLockScreenPass = 'walletLockScreenPass-' + this.walletStorageData + + this.walletLockScreenSet = '' + this.walletLockScreenSet = 'walletLockScreenSet-' + this.walletStorageData + + this.walletLockPass = '' + this.walletLockPass = encryptData(false, this.walletSalt) + + this.walletLockSet = '' + this.walletLockSet = encryptData(false, this.walletSalt) + + if (localStorage.getItem(this.walletLockScreenPass) === null && localStorage.getItem(this.walletLockScreenSet) === null) { + localStorage.setItem(this.walletLockScreenPass, this.walletLockPass) + localStorage.setItem(this.walletLockScreenSet, this.walletLockSet) + this.myWalletLockScreenPass = '' + this.myWalletLockScreenPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt) + this.myWalletLockScreenSet = '' + this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt) + } else { + this.myWalletLockScreenPass = '' + this.myWalletLockScreenPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt) + this.myWalletLockScreenSet = '' + this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt) + } + + if (this.myWalletLockScreenSet === true) { + this.shadowRoot.getElementById('walletLockScreenActive').open() + } + + this.qortAddressbook() + this.btcAddressbook() + this.ltcAddressbook() + this.dogeAddressbook() + this.dgbAddressbook() + this.rvnAddressbook() + this.arrrAddressbook() + + this.transactionsDOM = this.shadowRoot.getElementById('transactionsDOM') + + this.showWallet() + + window.addEventListener('storage', () => { + const checkLanguage = localStorage.getItem('qortalLanguage') + const checkTheme = localStorage.getItem('qortalTheme') + + use(checkLanguage) + + if (checkTheme === 'dark') { + this.theme = 'dark' + } else { + this.theme = 'light' + } + document.querySelector('html').setAttribute('theme', this.theme) + }) + + if (!isElectron()) { + } else { + window.addEventListener('contextmenu', (event) => { + event.preventDefault() + window.parent.electronAPI.showMyMenu() + }) + } + + this.clearConsole() + + setInterval(() => { + this.clearConsole() + this.getNodeConfig() + }, 60000) + + setInterval(() => { + this.paymentFee() + }, 600000) + } + + async paymentFee() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/transactions/unitfee?txType=PAYMENT` + + await fetch(url).then((response) => { + if (response.ok) { + return response.json() + } + return Promise.reject(response) + }).then((json) => { + this.qortPaymentFee = (Number(json) / 1e8).toFixed(8) + }) + } + + clearConsole() { + if (!isElectron()) { + } else { + console.clear() + window.parent.electronAPI.clearCache() + } + } + + pingCoinBalancesController() { + if (!this._selectedWallet) return + const customEvent = new CustomEvent('ping-coin-controller-with-coin', { + detail: this._selectedWallet + }) + window.parent.dispatchEvent(customEvent) + } + + connectedCallback() { + super.connectedCallback() + this.intervalID = setInterval(this.pingCoinBalancesController, 30000) + } + + disconnectedCallback() { + super.disconnectedCallback() + if (this.intervalID) { + clearInterval(this.intervalID) + } + } + + renderWalletLockButton() { + if (this.myWalletLockScreenPass === false && this.myWalletLockScreenSet === false) { + return html` +
    + this.openWalletSetScreenLockPass()} title="${translate("login.lp11")}"> +
    + ` + } else if (this.myWalletLockScreenSet === false) { + return html` +
    + this.setWalletLockQortal()} title="${translate("login.lp11")}"> +
    + ` + } else if (this.myWalletLockScreenSet === true) { + return html` +
    + +
    + ` + } + } + + openWalletSetScreenLockPass() { + this.shadowRoot.getElementById('walletLockPassword').value = '' + this.shadowRoot.getElementById('walletLockPasswordConfirm').value = '' + this.shadowRoot.getElementById('setWalletLockScreenPass').open() + } + + closewWalletSetScreenLockPass() { + this.shadowRoot.getElementById('setWalletLockScreenPass').close() + } + + walletCheckPass() { + const walletPassword = this.shadowRoot.getElementById('walletLockPassword').value + const walletRePassword = this.shadowRoot.getElementById('walletLockPasswordConfirm').value + + if (walletPassword === '') { + let snackbar1string = get("login.pleaseenter") + parentEpml.request('showSnackBar', `${snackbar1string}`) + return + } + + if (walletPassword != walletRePassword) { + let snackbar2string = get("login.notmatch") + parentEpml.request('showSnackBar', `${snackbar2string}`) + return + } + + if (walletPassword.length < 8) { + let snackbar3string = get("login.lessthen8") + parentEpml.request('showSnackBar', `${snackbar3string}`) + this.walletExtraConfirm() + } + + if (walletPassword.length >= 8) { + this.setWalletNewScreenPass() + let snackbar4string = get("login.lp6") + parentEpml.request('showSnackBar', `${snackbar4string}`) + } + } + + walletExtraConfirm() { + this.shadowRoot.getElementById('setWalletLockScreenPass').close() + this.shadowRoot.getElementById('walletExtraConfirmPass').open() + } + + closWalletExtraConfirmPass() { + this.shadowRoot.getElementById('walletExtraConfirmPass').close() + this.shadowRoot.getElementById('walletLockPassword').value = '' + this.shadowRoot.getElementById('walletLockPasswordConfirm').value = '' + } + + setWalletNewScreenPass() { + const walletRawPassword = this.shadowRoot.getElementById('walletLockPassword').value + const walletCryptPassword = encryptData(walletRawPassword, this.walletSalt) + localStorage.setItem(this.walletLockScreenPass, walletCryptPassword) + this.myWalletLockScreenPass = '' + this.myWalletLockScreenPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt) + this.shadowRoot.getElementById('setWalletLockScreenPass').close() + this.shadowRoot.getElementById('walletExtraConfirmPass').close() + this.shadowRoot.getElementById('walletLockPassword').value = '' + this.shadowRoot.getElementById('walletLockPasswordConfirm').value = '' + } + + setWalletLockQortal() { + this.walletHelperMessage = this.renderWalletHelperPass() + this.walletLockSet = '' + this.walletLockSet = encryptData(true, this.walletSalt) + localStorage.setItem(this.walletLockScreenSet, this.walletLockSet) + this.myWalletLockScreenSet = '' + this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt) + this.shadowRoot.getElementById('walletLockScreenActive').open() + } + + walletPassKeyListener(e) { + if (e.key === 'Enter') { + this.closeWalletLockScreenActive() + } + } + + async closeWalletLockScreenActive() { + const myWalletPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt) + const walletCheckPass = this.shadowRoot.getElementById('walletUnlockPassword').value + const errDelay = ms => new Promise(res => setTimeout(res, ms)) + + if (walletCheckPass === myWalletPass) { + this.walletLockSet = '' + this.walletLockSet = encryptData(false, this.walletSalt) + localStorage.setItem(this.walletLockScreenSet, this.walletLockSet) + this.myWalletLockScreenSet = '' + this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt) + this.shadowRoot.getElementById('walletLockScreenActive').close() + this.shadowRoot.getElementById('walletUnlockPassword').value = '' + this.walletHelperMessage = this.renderWalletHelperPass() + } else { + this.shadowRoot.getElementById('walletUnlockPassword').value = '' + this.walletHelperMessage = this.renderWalletHelperErr() + await errDelay(3000) + this.walletHelperMessage = this.renderWalletHelperPass() + } + } + + renderWalletHelperPass() { + return html`${translate("login.pleaseenter")}` + } + + renderWalletHelperErr() { + return html`${translate("login.lp8")}` + } + + renderWarning() { + return html`${translate("tradepage.tchange48")} QORT` + } + + renderClearSuccess() { + let strSuccessValue = this.successMessage + if (strSuccessValue === "") { + return html`` + } else { + return html` +
    + ${this.successMessage} + + + +
    +
    +

    ${translate("walletpage.wchange43")}

    +
    + ` + } + } + + renderClearError() { + let strErrorValue = this.errorMessage + if (strErrorValue === "") { + return html`` + } else { + return html` +
    + ${this.errorMessage} + + + +
    +
    +

    ${translate("walletpage.wchange44")}

    +
    + ` + } + } + + tabWalletQort() { + this._selectedWallet = 'qort' + this.showWallet() + } + + tabWalletBtc() { + this._selectedWallet = 'btc' + this.showWallet() + } + + tabWalletLtc() { + this._selectedWallet = 'ltc' + this.showWallet() + } + + tabWalletDoge() { + this._selectedWallet = 'doge' + this.showWallet() + } + + tabWalletDgb() { + this._selectedWallet = 'dgb' + this.showWallet() + } + + tabWalletRvn() { + this._selectedWallet = 'rvn' + this.showWallet() + } + + tabWalletArrr() { + this._selectedWallet = 'arrr' + this.showWallet() + } + + qortAddressbook() { + const storedQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress + if (localStorage.getItem(storedQortalAddressBook) === null) { + localStorage.setItem(storedQortalAddressBook, "") + } else { + this.qortBook = JSON.parse(localStorage.getItem(storedQortalAddressBook) || "[]") + } + } + + btcAddressbook() { + const storedBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress + if (localStorage.getItem(storedBitcoinAddressBook) === null) { + localStorage.setItem(storedBitcoinAddressBook, "") + } else { + this.btcBook = JSON.parse(localStorage.getItem(storedBitcoinAddressBook) || "[]") + } + } + + ltcAddressbook() { + const storedLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress + if (localStorage.getItem(storedLitecoinAddressBook) === null) { + localStorage.setItem(storedLitecoinAddressBook, "") + } else { + this.ltcBook = JSON.parse(localStorage.getItem(storedLitecoinAddressBook) || "[]") + } + } + + dogeAddressbook() { + const storedDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress + if (localStorage.getItem(storedDogecoinAddressBook) === null) { + localStorage.setItem(storedDogecoinAddressBook, "") + } else { + this.dogeBook = JSON.parse(localStorage.getItem(storedDogecoinAddressBook) || "[]") + } + } + + dgbAddressbook() { + const storedDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress + if (localStorage.getItem(storedDigibyteAddressBook) === null) { + localStorage.setItem(storedDigibyteAddressBook, "") + } else { + this.dgbBook = JSON.parse(localStorage.getItem(storedDigibyteAddressBook) || "[]") + } + } + + rvnAddressbook() { + const storedRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress + if (localStorage.getItem(storedRavencoinAddressBook) === null) { + localStorage.setItem(storedRavencoinAddressBook, "") + } else { + this.rvnBook = JSON.parse(localStorage.getItem(storedRavencoinAddressBook) || "[]") + } + } + + arrrAddressbook() { + const storedPiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress + if (localStorage.getItem(storedPiratechainAddressBook) === null) { + localStorage.setItem(storedPiratechainAddressBook, "") + } else { + this.arrrBook = JSON.parse(localStorage.getItem(storedPiratechainAddressBook) || "[]") + } + } + + openQortAddressbook() { + this.shadowRoot.querySelector("#qortBookDialog").show() + } + + openBtcAddressbook() { + this.shadowRoot.querySelector("#btcBookDialog").show() + } + + openLtcAddressbook() { + this.shadowRoot.querySelector("#ltcBookDialog").show() + } + + openDogeAddressbook() { + this.shadowRoot.querySelector("#dogeBookDialog").show() + } + + openDgbAddressbook() { + this.shadowRoot.querySelector("#dgbBookDialog").show() + } + + openRvnAddressbook() { + this.shadowRoot.querySelector("#rvnBookDialog").show() + } + + openArrrAddressbook() { + this.shadowRoot.querySelector("#arrrBookDialog").show() + } + + openAddQortAddressDialog() { + this.qortBookAddress = this.selectedTransaction.recipient + this.openAddToQortAddressbook() + this.shadowRoot.querySelector('#showTransactionDetailsDialog').close() + } + + openAddBtcAddressDialog() { + this.btcBookAddress = this.selectedTransaction.btcReceiver + this.openAddToBtcAddressbook() + this.shadowRoot.querySelector('#showBtcTransactionDetailsDialog').close() + } + + openAddLtcAddressDialog() { + this.ltcBookAddress = this.selectedTransaction.ltcReceiver + this.openAddToLtcAddressbook() + this.shadowRoot.querySelector('#showLtcTransactionDetailsDialog').close() + } + + openAddDogeAddressDialog() { + this.dogeBookAddress = this.selectedTransaction.dogeReceiver + this.openAddToDogeAddressbook() + this.shadowRoot.querySelector('#showDogeTransactionDetailsDialog').close() + } + + openAddDgbAddressDialog() { + this.dgbBookAddress = this.selectedTransaction.dgbReceiver + this.openAddToDgbAddressbook() + this.shadowRoot.querySelector('#showDgbTransactionDetailsDialog').close() + } + + openAddRvnAddressDialog() { + this.rvnBookAddress = this.selectedTransaction.rvnReceiver + this.openAddToRvnAddressbook() + this.shadowRoot.querySelector('#showRvnTransactionDetailsDialog').close() + } + + openAddArrrAddressDialog() { + this.arrrBookAddress = this.selectedTransaction.arrrReceiver + this.openAddToArrrAddressbook() + this.shadowRoot.querySelector('#showArrrTransactionDetailsDialog').close() + } + + openAddToQortAddressbook() { + this.shadowRoot.querySelector("#addQortAddressDialog").show() + } + + openAddToBtcAddressbook() { + this.shadowRoot.querySelector("#addBtcAddressDialog").show() + } + + openAddToLtcAddressbook() { + this.shadowRoot.querySelector("#addLtcAddressDialog").show() + } + + openAddToDogeAddressbook() { + this.shadowRoot.querySelector("#addDogeAddressDialog").show() + } + + openAddToDgbAddressbook() { + this.shadowRoot.querySelector("#addDgbAddressDialog").show() + } + + openAddToRvnAddressbook() { + this.shadowRoot.querySelector("#addRvnAddressDialog").show() + } + + openAddToArrrAddressbook() { + this.shadowRoot.querySelector("#addArrrAddressDialog").show() + } + + openImportQortAddressbook() { + this.shadowRoot.querySelector("#importQortAddressbookDialog").show() + } + + openImportBtcAddressbook() { + this.shadowRoot.querySelector("#importBtcAddressbookDialog").show() + } + + openImportLtcAddressbook() { + this.shadowRoot.querySelector("#importLtcAddressbookDialog").show() + } + + openImportDogeAddressbook() { + this.shadowRoot.querySelector("#importDogeAddressbookDialog").show() + } + + openImportDgbAddressbook() { + this.shadowRoot.querySelector("#importDgbAddressbookDialog").show() + } + + openImportRvnAddressbook() { + this.shadowRoot.querySelector("#importRvnAddressbookDialog").show() + } + + openImportArrrAddressbook() { + this.shadowRoot.querySelector("#importArrrAddressbookDialog").show() + } + + closeQortAddressDialog() { + this.shadowRoot.querySelector('#addQortAddressDialog').close() + this.shadowRoot.getElementById('qortNameInput').value = '' + this.shadowRoot.getElementById('qortAddressInput').value = '' + this.qortBookName = '' + this.qortBookAddress = '' + } + + closeBtcAddressDialog() { + this.shadowRoot.querySelector('#addBtcAddressDialog').close() + this.shadowRoot.getElementById('btcNameInput').value = '' + this.shadowRoot.getElementById('btcAddressInput').value = '' + this.btcBookName = '' + this.btcBookAddress = '' + } + + closeLtcAddressDialog() { + this.shadowRoot.querySelector('#addLtcAddressDialog').close() + this.shadowRoot.getElementById('ltcNameInput').value = '' + this.shadowRoot.getElementById('ltcAddressInput').value = '' + this.ltcBookName = '' + this.ltcBookAddress = '' + } + + closeDogeAddressDialog() { + this.shadowRoot.querySelector('#addDogeAddressDialog').close() + this.shadowRoot.getElementById('dogeNameInput').value = '' + this.shadowRoot.getElementById('dogeAddressInput').value = '' + this.dogeBookName = '' + this.dogeBookAddress = '' + } + + closeDgbAddressDialog() { + this.shadowRoot.querySelector('#addDgbAddressDialog').close() + this.shadowRoot.getElementById('dgbNameInput').value = '' + this.shadowRoot.getElementById('dgbAddressInput').value = '' + this.dgbBookName = '' + this.dgbBookAddress = '' + } + + closeRvnAddressDialog() { + this.shadowRoot.querySelector('#addRvnAddressDialog').close() + this.shadowRoot.getElementById('rvnNameInput').value = '' + this.shadowRoot.getElementById('rvnAddressInput').value = '' + this.rvnBookName = '' + this.rvnBookAddress = '' + } + + closeArrrAddressDialog() { + this.shadowRoot.querySelector('#addArrrAddressDialog').close() + this.shadowRoot.getElementById('arrrNameInput').value = '' + this.shadowRoot.getElementById('arrrAddressInput').value = '' + this.arrrBookName = '' + this.arrrBookAddress = '' + } + + closeImportQortAddressbookDialog() { + this.shadowRoot.querySelector("#importQortAddressbookDialog").close() + } + + closeImportBtcAddressbookDialog() { + this.shadowRoot.querySelector("#importBtcAddressbookDialog").close() + } + + closeImportLtcAddressbookDialog() { + this.shadowRoot.querySelector("#importLtcAddressbookDialog").close() + } + + closeImportDogeAddressbookDialog() { + this.shadowRoot.querySelector("#importDogeAddressbookDialog").close() + } + + closeImportDgbAddressbookDialog() { + this.shadowRoot.querySelector("#importDgbAddressbookDialog").close() + } + + closeImportRvnAddressbookDialog() { + this.shadowRoot.querySelector("#importRvnAddressbookDialog").close() + } + + closeImportArrrAddressbookDialog() { + this.shadowRoot.querySelector("#importArrrAddressbookDialog").close() + } + + addToQortalAddressbook() { + const myQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress + + let name = this.shadowRoot.getElementById('qortNameInput').value + let address = this.shadowRoot.getElementById('qortAddressInput').value + + var oldQortalBook = JSON.parse(localStorage.getItem(myQortalAddressBook) || "[]") + + if (name.length === 0) { + let qortbookstring1 = get("walletpage.wchange50") + parentEpml.request('showSnackBar', `${qortbookstring1}`) + return false + } + + if (address.length === 0) { + let qortbookstring2 = get("walletpage.wchange51") + parentEpml.request('showSnackBar', `${qortbookstring2}`) + return false + } + + const newQortalBookItem = { + name: name, + address: address + } + + oldQortalBook.push(newQortalBookItem) + + localStorage.setItem(myQortalAddressBook, JSON.stringify(oldQortalBook)) + + let qortbookstring2 = get("walletpage.wchange52") + parentEpml.request('showSnackBar', `${qortbookstring2}`) + + this.closeQortAddressDialog() + this.qortBook = JSON.parse(localStorage.getItem(myQortalAddressBook) || "[]") + } + + addToBitcoinAddressbook() { + const myBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress - let name = this.shadowRoot.getElementById('btcNameInput').value - let address = this.shadowRoot.getElementById('btcAddressInput').value + let name = this.shadowRoot.getElementById('btcNameInput').value + let address = this.shadowRoot.getElementById('btcAddressInput').value - var oldBitcoinBook = JSON.parse(localStorage.getItem(myBitcoinAddressBook) || "[]") + var oldBitcoinBook = JSON.parse(localStorage.getItem(myBitcoinAddressBook) || "[]") - if (name.length === 0) { - let btcbookstring1 = get("walletpage.wchange50") - parentEpml.request('showSnackBar', `${btcbookstring1}`) - return false - } + if (name.length === 0) { + let btcbookstring1 = get("walletpage.wchange50") + parentEpml.request('showSnackBar', `${btcbookstring1}`) + return false + } - if (address.length === 0) { - let btcbookstring2 = get("walletpage.wchange51") - parentEpml.request('showSnackBar', `${btcbookstring2}`) - return false - } + if (address.length === 0) { + let btcbookstring2 = get("walletpage.wchange51") + parentEpml.request('showSnackBar', `${btcbookstring2}`) + return false + } - const newBitcoinBookItem = { - name: name, - address: address - } + const newBitcoinBookItem = { + name: name, + address: address + } - oldBitcoinBook.push(newBitcoinBookItem) + oldBitcoinBook.push(newBitcoinBookItem) - localStorage.setItem(myBitcoinAddressBook, JSON.stringify(oldBitcoinBook)) + localStorage.setItem(myBitcoinAddressBook, JSON.stringify(oldBitcoinBook)) - let btcbookstring3 = get("walletpage.wchange52") - parentEpml.request('showSnackBar', `${btcbookstring3}`) + let btcbookstring3 = get("walletpage.wchange52") + parentEpml.request('showSnackBar', `${btcbookstring3}`) - this.closeBtcAddressDialog() - this.btcBook = JSON.parse(localStorage.getItem(myBitcoinAddressBook) || "[]") - } + this.closeBtcAddressDialog() + this.btcBook = JSON.parse(localStorage.getItem(myBitcoinAddressBook) || "[]") + } - addToLitecoinAddressbook() { - const myLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress + addToLitecoinAddressbook() { + const myLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress - let name = this.shadowRoot.getElementById('ltcNameInput').value - let address = this.shadowRoot.getElementById('ltcAddressInput').value + let name = this.shadowRoot.getElementById('ltcNameInput').value + let address = this.shadowRoot.getElementById('ltcAddressInput').value - var oldLitecoinBook = JSON.parse(localStorage.getItem(myLitecoinAddressBook) || "[]") + var oldLitecoinBook = JSON.parse(localStorage.getItem(myLitecoinAddressBook) || "[]") - if (name.length === 0) { - let ltcbookstring1 = get("walletpage.wchange50") - parentEpml.request('showSnackBar', `${ltcbookstring1}`) - return false - } + if (name.length === 0) { + let ltcbookstring1 = get("walletpage.wchange50") + parentEpml.request('showSnackBar', `${ltcbookstring1}`) + return false + } - if (address.length === 0) { - let ltcbookstring2 = get("walletpage.wchange51") - parentEpml.request('showSnackBar', `${ltcbookstring2}`) - return false - } + if (address.length === 0) { + let ltcbookstring2 = get("walletpage.wchange51") + parentEpml.request('showSnackBar', `${ltcbookstring2}`) + return false + } - const newLitecoinBookItem = { - name: name, - address: address - } + const newLitecoinBookItem = { + name: name, + address: address + } - oldLitecoinBook.push(newLitecoinBookItem) + oldLitecoinBook.push(newLitecoinBookItem) - localStorage.setItem(myLitecoinAddressBook, JSON.stringify(oldLitecoinBook)) + localStorage.setItem(myLitecoinAddressBook, JSON.stringify(oldLitecoinBook)) - let ltcbookstring3 = get("walletpage.wchange52") - parentEpml.request('showSnackBar', `${ltcbookstring3}`) + let ltcbookstring3 = get("walletpage.wchange52") + parentEpml.request('showSnackBar', `${ltcbookstring3}`) - this.closeLtcAddressDialog() - this.ltcBook = JSON.parse(localStorage.getItem(myLitecoinAddressBook) || "[]") - } + this.closeLtcAddressDialog() + this.ltcBook = JSON.parse(localStorage.getItem(myLitecoinAddressBook) || "[]") + } - addToDogecoinAddressbook() { - const myDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress + addToDogecoinAddressbook() { + const myDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress - let name = this.shadowRoot.getElementById('dogeNameInput').value - let address = this.shadowRoot.getElementById('dogeAddressInput').value + let name = this.shadowRoot.getElementById('dogeNameInput').value + let address = this.shadowRoot.getElementById('dogeAddressInput').value - var oldDogecoinBook = JSON.parse(localStorage.getItem(myDogecoinAddressBook) || "[]") + var oldDogecoinBook = JSON.parse(localStorage.getItem(myDogecoinAddressBook) || "[]") - if (name.length === 0) { - let dogebookstring1 = get("walletpage.wchange50") - parentEpml.request('showSnackBar', `${dogebookstring1}`) - return false - } + if (name.length === 0) { + let dogebookstring1 = get("walletpage.wchange50") + parentEpml.request('showSnackBar', `${dogebookstring1}`) + return false + } - if (address.length === 0) { - let dogebookstring2 = get("walletpage.wchange51") - parentEpml.request('showSnackBar', `${dogebookstring2}`) - return false - } + if (address.length === 0) { + let dogebookstring2 = get("walletpage.wchange51") + parentEpml.request('showSnackBar', `${dogebookstring2}`) + return false + } - const newDogecoinBookItem = { - name: name, - address: address - } + const newDogecoinBookItem = { + name: name, + address: address + } - oldDogecoinBook.push(newDogecoinBookItem) + oldDogecoinBook.push(newDogecoinBookItem) - localStorage.setItem(myDogecoinAddressBook, JSON.stringify(oldDogecoinBook)) + localStorage.setItem(myDogecoinAddressBook, JSON.stringify(oldDogecoinBook)) - let dogebookstring3 = get("walletpage.wchange52") - parentEpml.request('showSnackBar', `${dogebookstring3}`) + let dogebookstring3 = get("walletpage.wchange52") + parentEpml.request('showSnackBar', `${dogebookstring3}`) - this.closeDogeAddressDialog() - this.dogeBook = JSON.parse(localStorage.getItem(myDogecoinAddressBook) || "[]") - } + this.closeDogeAddressDialog() + this.dogeBook = JSON.parse(localStorage.getItem(myDogecoinAddressBook) || "[]") + } - addToDigibyteAddressbook() { - const myDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress + addToDigibyteAddressbook() { + const myDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress - let name = this.shadowRoot.getElementById('dgbNameInput').value - let address = this.shadowRoot.getElementById('dgbAddressInput').value + let name = this.shadowRoot.getElementById('dgbNameInput').value + let address = this.shadowRoot.getElementById('dgbAddressInput').value - var oldDigibyteBook = JSON.parse(localStorage.getItem(myDigibyteAddressBook) || "[]") + var oldDigibyteBook = JSON.parse(localStorage.getItem(myDigibyteAddressBook) || "[]") - if (name.length === 0) { - let dgbbookstring1 = get("walletpage.wchange50") - parentEpml.request('showSnackBar', `${dgbbookstring1}`) - return false - } + if (name.length === 0) { + let dgbbookstring1 = get("walletpage.wchange50") + parentEpml.request('showSnackBar', `${dgbbookstring1}`) + return false + } - if (address.length === 0) { - let dgbbookstring2 = get("walletpage.wchange51") - parentEpml.request('showSnackBar', `${dgbbookstring2}`) - return false - } + if (address.length === 0) { + let dgbbookstring2 = get("walletpage.wchange51") + parentEpml.request('showSnackBar', `${dgbbookstring2}`) + return false + } - const newDigibyteBookItem = { - name: name, - address: address - } + const newDigibyteBookItem = { + name: name, + address: address + } - oldDigibyteBook.push(newDigibyteBookItem) + oldDigibyteBook.push(newDigibyteBookItem) - localStorage.setItem(myDigibyteAddressBook, JSON.stringify(oldDigibyteBook)) + localStorage.setItem(myDigibyteAddressBook, JSON.stringify(oldDigibyteBook)) - let dgbbookstring3 = get("walletpage.wchange52") - parentEpml.request('showSnackBar', `${dgbbookstring3}`) + let dgbbookstring3 = get("walletpage.wchange52") + parentEpml.request('showSnackBar', `${dgbbookstring3}`) - this.closeDgbAddressDialog() - this.dgbBook = JSON.parse(localStorage.getItem(myDigibyteAddressBook) || "[]") - } + this.closeDgbAddressDialog() + this.dgbBook = JSON.parse(localStorage.getItem(myDigibyteAddressBook) || "[]") + } - addToRavencoinAddressbook() { - const myRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress + addToRavencoinAddressbook() { + const myRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress - let name = this.shadowRoot.getElementById('rvnNameInput').value - let address = this.shadowRoot.getElementById('rvnAddressInput').value + let name = this.shadowRoot.getElementById('rvnNameInput').value + let address = this.shadowRoot.getElementById('rvnAddressInput').value - var oldRavencoinBook = JSON.parse(localStorage.getItem(myRavencoinAddressBook) || "[]") + var oldRavencoinBook = JSON.parse(localStorage.getItem(myRavencoinAddressBook) || "[]") - if (name.length === 0) { - let rvnbookstring1 = get("walletpage.wchange50") - parentEpml.request('showSnackBar', `${rvnbookstring1}`) - return false - } + if (name.length === 0) { + let rvnbookstring1 = get("walletpage.wchange50") + parentEpml.request('showSnackBar', `${rvnbookstring1}`) + return false + } - if (address.length === 0) { - let rvnbookstring2 = get("walletpage.wchange51") - parentEpml.request('showSnackBar', `${rvnbookstring2}`) - return false - } + if (address.length === 0) { + let rvnbookstring2 = get("walletpage.wchange51") + parentEpml.request('showSnackBar', `${rvnbookstring2}`) + return false + } - const newRavencoinBookItem = { - name: name, - address: address - } + const newRavencoinBookItem = { + name: name, + address: address + } - oldRavencoinBook.push(newRavencoinBookItem) + oldRavencoinBook.push(newRavencoinBookItem) - localStorage.setItem(myRavencoinAddressBook, JSON.stringify(oldRavencoinBook)) + localStorage.setItem(myRavencoinAddressBook, JSON.stringify(oldRavencoinBook)) - let rvnbookstring3 = get("walletpage.wchange52") - parentEpml.request('showSnackBar', `${rvnbookstring3}`) + let rvnbookstring3 = get("walletpage.wchange52") + parentEpml.request('showSnackBar', `${rvnbookstring3}`) - this.closeRvnAddressDialog() - this.rvnBook = JSON.parse(localStorage.getItem(myRavencoinAddressBook) || "[]") - } + this.closeRvnAddressDialog() + this.rvnBook = JSON.parse(localStorage.getItem(myRavencoinAddressBook) || "[]") + } - addToPiratechainAddressbook() { - const myPiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress + addToPiratechainAddressbook() { + const myPiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress - let name = this.shadowRoot.getElementById('arrrNameInput').value - let address = this.shadowRoot.getElementById('arrrAddressInput').value + let name = this.shadowRoot.getElementById('arrrNameInput').value + let address = this.shadowRoot.getElementById('arrrAddressInput').value - var oldPiratechainBook = JSON.parse(localStorage.getItem(myPiratechainAddressBook) || "[]") + var oldPiratechainBook = JSON.parse(localStorage.getItem(myPiratechainAddressBook) || "[]") - if (name.length === 0) { - let arrrbookstring1 = get("walletpage.wchange50") - parentEpml.request('showSnackBar', `${arrrbookstring1}`) - return false - } + if (name.length === 0) { + let arrrbookstring1 = get("walletpage.wchange50") + parentEpml.request('showSnackBar', `${arrrbookstring1}`) + return false + } - if (address.length === 0) { - let arrrbookstring2 = get("walletpage.wchange51") - parentEpml.request('showSnackBar', `${arrrbookstring2}`) - return false - } + if (address.length === 0) { + let arrrbookstring2 = get("walletpage.wchange51") + parentEpml.request('showSnackBar', `${arrrbookstring2}`) + return false + } - const newPiratechainBookItem = { - name: name, - address: address - } + const newPiratechainBookItem = { + name: name, + address: address + } - oldPiratechainBook.push(newPiratechainBookItem) + oldPiratechainBook.push(newPiratechainBookItem) - localStorage.setItem(myPiratechainAddressBook, JSON.stringify(oldPiratechainBook)) + localStorage.setItem(myPiratechainAddressBook, JSON.stringify(oldPiratechainBook)) - let arrrbookstring3 = get("walletpage.wchange52") - parentEpml.request('showSnackBar', `${arrrbookstring3}`) + let arrrbookstring3 = get("walletpage.wchange52") + parentEpml.request('showSnackBar', `${arrrbookstring3}`) - this.closeArrrAddressDialog() - this.arrrBook = JSON.parse(localStorage.getItem(myPiratechainAddressBook) || "[]") - } + this.closeArrrAddressDialog() + this.arrrBook = JSON.parse(localStorage.getItem(myPiratechainAddressBook) || "[]") + } - sendFromQortAddressbook(websiteObj) { + sendFromQortAddressbook(websiteObj) { this.recipient = websiteObj.address - this.openSendQort() - this.shadowRoot.querySelector('#qortBookDialog').close() - } + this.openSendQort() + this.shadowRoot.querySelector('#qortBookDialog').close() + } - sendFromBtcAddressbook(websiteObj) { + sendFromBtcAddressbook(websiteObj) { this.btcRecipient = websiteObj.address - this.openSendBtc() - this.shadowRoot.querySelector('#btcBookDialog').close() - } + this.openSendBtc() + this.shadowRoot.querySelector('#btcBookDialog').close() + } - sendFromLtcAddressbook(websiteObj) { + sendFromLtcAddressbook(websiteObj) { this.ltcRecipient = websiteObj.address - this.openSendLtc() - this.shadowRoot.querySelector('#ltcBookDialog').close() - } + this.openSendLtc() + this.shadowRoot.querySelector('#ltcBookDialog').close() + } - sendFromDogeAddressbook(websiteObj) { + sendFromDogeAddressbook(websiteObj) { this.dogeRecipient = websiteObj.address - this.openSendDoge() - this.shadowRoot.querySelector('#dogeBookDialog').close() - } + this.openSendDoge() + this.shadowRoot.querySelector('#dogeBookDialog').close() + } - sendFromDgbAddressbook(websiteObj) { + sendFromDgbAddressbook(websiteObj) { this.dgbRecipient = websiteObj.address - this.openSendDgb() - this.shadowRoot.querySelector('#dgbBookDialog').close() - } + this.openSendDgb() + this.shadowRoot.querySelector('#dgbBookDialog').close() + } - sendFromRvnAddressbook(websiteObj) { + sendFromRvnAddressbook(websiteObj) { this.rvnRecipient = websiteObj.address - this.openSendRvn() - this.shadowRoot.querySelector('#rvnBookDialog').close() - } + this.openSendRvn() + this.shadowRoot.querySelector('#rvnBookDialog').close() + } - sendFromArrrAddressbook(websiteObj) { + sendFromArrrAddressbook(websiteObj) { this.arrrRecipient = websiteObj.address - this.openSendArrr() - this.shadowRoot.querySelector('#arrrBookDialog').close() - } + this.openSendArrr() + this.shadowRoot.querySelector('#arrrBookDialog').close() + } - removeQortAddress(adressObj) { - const theQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress - const addressToRemove = adressObj - this.newQortBookFilter = [] - this.newQortBookFilter = this.qortBook.filter((item) => item.address !== addressToRemove) - const myNewObj = JSON.stringify(this.newQortBookFilter) - localStorage.removeItem(theQortalAddressBook) - localStorage.setItem(theQortalAddressBook, myNewObj) - this.qortBook = JSON.parse(localStorage.getItem(theQortalAddressBook) || "[]") - } + removeQortAddress(adressObj) { + const theQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress + const addressToRemove = adressObj + this.newQortBookFilter = [] + this.newQortBookFilter = this.qortBook.filter((item) => item.address !== addressToRemove) + const myNewObj = JSON.stringify(this.newQortBookFilter) + localStorage.removeItem(theQortalAddressBook) + localStorage.setItem(theQortalAddressBook, myNewObj) + this.qortBook = JSON.parse(localStorage.getItem(theQortalAddressBook) || "[]") + } - removeBtcAddress(adressObj) { - const theBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress - const addressToRemove = adressObj - this.newBtcBookFilter = [] - this.newBtcBookFilter = this.btcBook.filter((item) => item.address !== addressToRemove) - const myNewObj = JSON.stringify(this.newBtcBookFilter) - localStorage.removeItem(theBitcoinAddressBook) - localStorage.setItem(theBitcoinAddressBook, myNewObj) - this.btcBook = JSON.parse(localStorage.getItem(theBitcoinAddressBook) || "[]") - } + removeBtcAddress(adressObj) { + const theBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress + const addressToRemove = adressObj + this.newBtcBookFilter = [] + this.newBtcBookFilter = this.btcBook.filter((item) => item.address !== addressToRemove) + const myNewObj = JSON.stringify(this.newBtcBookFilter) + localStorage.removeItem(theBitcoinAddressBook) + localStorage.setItem(theBitcoinAddressBook, myNewObj) + this.btcBook = JSON.parse(localStorage.getItem(theBitcoinAddressBook) || "[]") + } - removeLtcAddress(adressObj) { - const theLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress - const addressToRemove = adressObj - this.newLtcBookFilter = [] - this.newLtcBookFilter = this.ltcBook.filter((item) => item.address !== addressToRemove) - const myNewObj = JSON.stringify(this.newLtcBookFilter) - localStorage.removeItem(theLitecoinAddressBook) - localStorage.setItem(theLitecoinAddressBook, myNewObj) - this.ltcBook = JSON.parse(localStorage.getItem(theLitecoinAddressBook) || "[]") - } + removeLtcAddress(adressObj) { + const theLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress + const addressToRemove = adressObj + this.newLtcBookFilter = [] + this.newLtcBookFilter = this.ltcBook.filter((item) => item.address !== addressToRemove) + const myNewObj = JSON.stringify(this.newLtcBookFilter) + localStorage.removeItem(theLitecoinAddressBook) + localStorage.setItem(theLitecoinAddressBook, myNewObj) + this.ltcBook = JSON.parse(localStorage.getItem(theLitecoinAddressBook) || "[]") + } - removeDogeAddress(adressObj) { - const theDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress - const addressToRemove = adressObj - this.newDogeBookFilter = [] - this.newDogeBookFilter = this.dogeBook.filter((item) => item.address !== addressToRemove) - const myNewObj = JSON.stringify(this.newDogeBookFilter) - localStorage.removeItem(theDogecoinAddressBook) - localStorage.setItem(theDogecoinAddressBook, myNewObj) - this.dogeBook = JSON.parse(localStorage.getItem(theDogecoinAddressBook) || "[]") - } + removeDogeAddress(adressObj) { + const theDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress + const addressToRemove = adressObj + this.newDogeBookFilter = [] + this.newDogeBookFilter = this.dogeBook.filter((item) => item.address !== addressToRemove) + const myNewObj = JSON.stringify(this.newDogeBookFilter) + localStorage.removeItem(theDogecoinAddressBook) + localStorage.setItem(theDogecoinAddressBook, myNewObj) + this.dogeBook = JSON.parse(localStorage.getItem(theDogecoinAddressBook) || "[]") + } - removeDgbAddress(adressObj) { - const theDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress - const addressToRemove = adressObj - this.newDgbBookFilter = [] - this.newDgbBookFilter = this.dgbBook.filter((item) => item.address !== addressToRemove) - const myNewObj = JSON.stringify(this.newDgbBookFilter) - localStorage.removeItem(theDigibyteAddressBook) - localStorage.setItem(theDigibyteAddressBook, myNewObj) - this.dgbBook = JSON.parse(localStorage.getItem(theDigibyteAddressBook) || "[]") - } + removeDgbAddress(adressObj) { + const theDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress + const addressToRemove = adressObj + this.newDgbBookFilter = [] + this.newDgbBookFilter = this.dgbBook.filter((item) => item.address !== addressToRemove) + const myNewObj = JSON.stringify(this.newDgbBookFilter) + localStorage.removeItem(theDigibyteAddressBook) + localStorage.setItem(theDigibyteAddressBook, myNewObj) + this.dgbBook = JSON.parse(localStorage.getItem(theDigibyteAddressBook) || "[]") + } - removeRvnAddress(adressObj) { - const theRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress - const addressToRemove = adressObj - this.newRvnBookFilter = [] - this.newRvnBookFilter = this.rvnBook.filter((item) => item.address !== addressToRemove) - const myNewObj = JSON.stringify(this.newRvnBookFilter) - localStorage.removeItem(theRavencoinAddressBook) - localStorage.setItem(theRavencoinAddressBook, myNewObj) - this.rvnBook = JSON.parse(localStorage.getItem(theRavencoinAddressBook) || "[]") - } + removeRvnAddress(adressObj) { + const theRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress + const addressToRemove = adressObj + this.newRvnBookFilter = [] + this.newRvnBookFilter = this.rvnBook.filter((item) => item.address !== addressToRemove) + const myNewObj = JSON.stringify(this.newRvnBookFilter) + localStorage.removeItem(theRavencoinAddressBook) + localStorage.setItem(theRavencoinAddressBook, myNewObj) + this.rvnBook = JSON.parse(localStorage.getItem(theRavencoinAddressBook) || "[]") + } - removeArrrAddress(adressObj) { - const thePiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress - const addressToRemove = adressObj - this.newArrrBookFilter = [] - this.newArrrBookFilter = this.arrrBook.filter((item) => item.address !== addressToRemove) - const myNewObj = JSON.stringify(this.newArrrBookFilter) - localStorage.removeItem(thePiratechainAddressBook) - localStorage.setItem(thePiratechainAddressBook, myNewObj) - this.arrrBook = JSON.parse(localStorage.getItem(thePiratechainAddressBook) || "[]") - } + removeArrrAddress(adressObj) { + const thePiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress + const addressToRemove = adressObj + this.newArrrBookFilter = [] + this.newArrrBookFilter = this.arrrBook.filter((item) => item.address !== addressToRemove) + const myNewObj = JSON.stringify(this.newArrrBookFilter) + localStorage.removeItem(thePiratechainAddressBook) + localStorage.setItem(thePiratechainAddressBook, myNewObj) + this.arrrBook = JSON.parse(localStorage.getItem(thePiratechainAddressBook) || "[]") + } - renderSendFromQortAddressbookButton(websiteObj) { - return html`` - } + renderSendFromQortAddressbookButton(websiteObj) { + return html`` + } - renderSendFromBtcAddressbookButton(websiteObj) { - return html`` - } + renderSendFromBtcAddressbookButton(websiteObj) { + return html`` + } - renderSendFromLtcAddressbookButton(websiteObj) { - return html`` - } + renderSendFromLtcAddressbookButton(websiteObj) { + return html`` + } - renderSendFromDogeAddressbookButton(websiteObj) { - return html`` - } + renderSendFromDogeAddressbookButton(websiteObj) { + return html`` + } - renderSendFromDgbAddressbookButton(websiteObj) { - return html`` - } + renderSendFromDgbAddressbookButton(websiteObj) { + return html`` + } - renderSendFromRvnAddressbookButton(websiteObj) { - return html`` - } + renderSendFromRvnAddressbookButton(websiteObj) { + return html`` + } - renderSendFromArrrAddressbookButton(websiteObj) { - return html`` - } + renderSendFromArrrAddressbookButton(websiteObj) { + return html`` + } - exportQortAddressbook() { - const expQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress - let bookname = "" - const qortBookData = JSON.stringify(localStorage.getItem(expQortalAddressBook)) - const qortBookSave = JSON.parse((qortBookData) || "[]") - const blob = new Blob([qortBookSave], { type: 'text/plain;charset=utf-8' }) - bookname = "qortal_addressbook." + this.bookQortalAddress + ".qort.json" - this.saveFileToDisk(blob, bookname) - } + exportQortAddressbook() { + const expQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress + let bookname = "" + const qortBookData = JSON.stringify(localStorage.getItem(expQortalAddressBook)) + const qortBookSave = JSON.parse((qortBookData) || "[]") + const blob = new Blob([qortBookSave], { type: 'text/plain;charset=utf-8' }) + bookname = "qortal_addressbook." + this.bookQortalAddress + ".qort.json" + this.saveFileToDisk(blob, bookname) + } - exportBtcAddressbook() { - const expBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress - let bookname = "" - const btcBookData = JSON.stringify(localStorage.getItem(expBitcoinAddressBook)) - const btcBookSave = JSON.parse((btcBookData) || "[]") - const blob = new Blob([btcBookSave], { type: 'text/plain;charset=utf-8' }) - bookname = "bitcoin_addressbook." + this.bookBitcoinAddress + ".btc.json" - this.saveFileToDisk(blob, bookname) - } + exportBtcAddressbook() { + const expBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress + let bookname = "" + const btcBookData = JSON.stringify(localStorage.getItem(expBitcoinAddressBook)) + const btcBookSave = JSON.parse((btcBookData) || "[]") + const blob = new Blob([btcBookSave], { type: 'text/plain;charset=utf-8' }) + bookname = "bitcoin_addressbook." + this.bookBitcoinAddress + ".btc.json" + this.saveFileToDisk(blob, bookname) + } - exportLtcAddressbook() { - const expLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress - let bookname = "" - const ltcBookData = JSON.stringify(localStorage.getItem(expLitecoinAddressBook)) - const ltcBookSave = JSON.parse((ltcBookData) || "[]") - const blob = new Blob([ltcBookSave], { type: 'text/plain;charset=utf-8' }) - bookname = "litecoin_addressbook." + this.bookLitecoinAddress + ".ltc.json" - this.saveFileToDisk(blob, bookname) - } + exportLtcAddressbook() { + const expLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress + let bookname = "" + const ltcBookData = JSON.stringify(localStorage.getItem(expLitecoinAddressBook)) + const ltcBookSave = JSON.parse((ltcBookData) || "[]") + const blob = new Blob([ltcBookSave], { type: 'text/plain;charset=utf-8' }) + bookname = "litecoin_addressbook." + this.bookLitecoinAddress + ".ltc.json" + this.saveFileToDisk(blob, bookname) + } - exportDogeAddressbook() { - const expDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress - let bookname = "" - const dogeBookData = JSON.stringify(localStorage.getItem(expDogecoinAddressBook)) - const dogeBookSave = JSON.parse((dogeBookData) || "[]") - const blob = new Blob([dogeBookSave], { type: 'text/plain;charset=utf-8' }) - bookname = "dogecoin_addressbook." + this.bookDogecoinAddress + ".doge.json" - this.saveFileToDisk(blob, bookname) - } + exportDogeAddressbook() { + const expDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress + let bookname = "" + const dogeBookData = JSON.stringify(localStorage.getItem(expDogecoinAddressBook)) + const dogeBookSave = JSON.parse((dogeBookData) || "[]") + const blob = new Blob([dogeBookSave], { type: 'text/plain;charset=utf-8' }) + bookname = "dogecoin_addressbook." + this.bookDogecoinAddress + ".doge.json" + this.saveFileToDisk(blob, bookname) + } - exportDgbAddressbook() { - const expDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress - let bookname = "" - const dgbBookData = JSON.stringify(localStorage.getItem(expDigibyteAddressBook)) - const dgbBookSave = JSON.parse((dgbBookData) || "[]") - const blob = new Blob([dgbBookSave], { type: 'text/plain;charset=utf-8' }) - bookname = "digibyte_addressbook." + this.bookDigibyteAddress + ".dgb.json" - this.saveFileToDisk(blob, bookname) - } + exportDgbAddressbook() { + const expDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress + let bookname = "" + const dgbBookData = JSON.stringify(localStorage.getItem(expDigibyteAddressBook)) + const dgbBookSave = JSON.parse((dgbBookData) || "[]") + const blob = new Blob([dgbBookSave], { type: 'text/plain;charset=utf-8' }) + bookname = "digibyte_addressbook." + this.bookDigibyteAddress + ".dgb.json" + this.saveFileToDisk(blob, bookname) + } - exportRvnAddressbook() { - const expRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress - let bookname = "" - const rvnBookData = JSON.stringify(localStorage.getItem(expRavencoinAddressBook)) - const rvnBookSave = JSON.parse((rvnBookData) || "[]") - const blob = new Blob([rvnBookSave], { type: 'text/plain;charset=utf-8' }) - bookname = "ravencoin_addressbook." + this.bookRavencoinAddress + ".rvn.json" - this.saveFileToDisk(blob, bookname) - } + exportRvnAddressbook() { + const expRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress + let bookname = "" + const rvnBookData = JSON.stringify(localStorage.getItem(expRavencoinAddressBook)) + const rvnBookSave = JSON.parse((rvnBookData) || "[]") + const blob = new Blob([rvnBookSave], { type: 'text/plain;charset=utf-8' }) + bookname = "ravencoin_addressbook." + this.bookRavencoinAddress + ".rvn.json" + this.saveFileToDisk(blob, bookname) + } - exportArrrAddressbook() { - const expPiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress - let bookname = "" - const arrrBookData = JSON.stringify(localStorage.getItem(expPiratechainAddressBook)) - const arrrBookSave = JSON.parse((arrrBookData) || "[]") - const blob = new Blob([arrrBookSave], { type: 'text/plain;charset=utf-8' }) - bookname = "piratechain_addressbook." + this.bookPiratechainAddress + ".arrr.json" - this.saveFileToDisk(blob, bookname) - } + exportArrrAddressbook() { + const expPiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress + let bookname = "" + const arrrBookData = JSON.stringify(localStorage.getItem(expPiratechainAddressBook)) + const arrrBookSave = JSON.parse((arrrBookData) || "[]") + const blob = new Blob([arrrBookSave], { type: 'text/plain;charset=utf-8' }) + bookname = "piratechain_addressbook." + this.bookPiratechainAddress + ".arrr.json" + this.saveFileToDisk(blob, bookname) + } - importQortAddressbook(file) { - const impQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress - localStorage.removeItem(impQortalAddressBook) - const newItems = JSON.parse((file) || "[]") - localStorage.setItem(impQortalAddressBook, JSON.stringify(newItems)) - this.qortBook = JSON.parse(localStorage.getItem(impQortalAddressBook) || "[]") - this.shadowRoot.querySelector('#importQortAddressbookDialog').close() - } + importQortAddressbook(file) { + const impQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress + localStorage.removeItem(impQortalAddressBook) + const newItems = JSON.parse((file) || "[]") + localStorage.setItem(impQortalAddressBook, JSON.stringify(newItems)) + this.qortBook = JSON.parse(localStorage.getItem(impQortalAddressBook) || "[]") + this.shadowRoot.querySelector('#importQortAddressbookDialog').close() + } - importBtcAddressbook(file) { - const impBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress - localStorage.removeItem(impBitcoinAddressBook) - const newItems = JSON.parse((file) || "[]") - localStorage.setItem(impBitcoinAddressBook, JSON.stringify(newItems)) - this.btcBook = JSON.parse(localStorage.getItem(impBitcoinAddressBook) || "[]") - this.shadowRoot.querySelector('#importBtcAddressbookDialog').close() - } + importBtcAddressbook(file) { + const impBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress + localStorage.removeItem(impBitcoinAddressBook) + const newItems = JSON.parse((file) || "[]") + localStorage.setItem(impBitcoinAddressBook, JSON.stringify(newItems)) + this.btcBook = JSON.parse(localStorage.getItem(impBitcoinAddressBook) || "[]") + this.shadowRoot.querySelector('#importBtcAddressbookDialog').close() + } - importLtcAddressbook(file) { - const impLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress - localStorage.removeItem(impLitecoinAddressBook) - const newItems = JSON.parse((file) || "[]") - localStorage.setItem(impLitecoinAddressBook, JSON.stringify(newItems)) - this.ltcBook = JSON.parse(localStorage.getItem(impLitecoinAddressBook) || "[]") - this.shadowRoot.querySelector('#importLtcAddressbookDialog').close() - } + importLtcAddressbook(file) { + const impLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress + localStorage.removeItem(impLitecoinAddressBook) + const newItems = JSON.parse((file) || "[]") + localStorage.setItem(impLitecoinAddressBook, JSON.stringify(newItems)) + this.ltcBook = JSON.parse(localStorage.getItem(impLitecoinAddressBook) || "[]") + this.shadowRoot.querySelector('#importLtcAddressbookDialog').close() + } - importDogeAddressbook(file) { - const impDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress - localStorage.removeItem(impDogecoinAddressBook) - const newItems = JSON.parse((file) || "[]") - localStorage.setItem(impDogecoinAddressBook, JSON.stringify(newItems)) - this.dogeBook = JSON.parse(localStorage.getItem(impDogecoinAddressBook) || "[]") - this.shadowRoot.querySelector('#importDogeAddressbookDialog').close() - } + importDogeAddressbook(file) { + const impDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress + localStorage.removeItem(impDogecoinAddressBook) + const newItems = JSON.parse((file) || "[]") + localStorage.setItem(impDogecoinAddressBook, JSON.stringify(newItems)) + this.dogeBook = JSON.parse(localStorage.getItem(impDogecoinAddressBook) || "[]") + this.shadowRoot.querySelector('#importDogeAddressbookDialog').close() + } - importDgbAddressbook(file) { - const impDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress - localStorage.removeItem(impDigibyteAddressBook) - const newItems = JSON.parse((file) || "[]") - localStorage.setItem(impDigibyteAddressBook, JSON.stringify(newItems)) - this.dgbBook = JSON.parse(localStorage.getItem(impDigibyteAddressBook) || "[]") - this.shadowRoot.querySelector('#importDgbAddressbookDialog').close() - } + importDgbAddressbook(file) { + const impDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress + localStorage.removeItem(impDigibyteAddressBook) + const newItems = JSON.parse((file) || "[]") + localStorage.setItem(impDigibyteAddressBook, JSON.stringify(newItems)) + this.dgbBook = JSON.parse(localStorage.getItem(impDigibyteAddressBook) || "[]") + this.shadowRoot.querySelector('#importDgbAddressbookDialog').close() + } - importRvnAddressbook(file) { - const impRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress - localStorage.removeItem(impRavencoinAddressBook) - const newItems = JSON.parse((file) || "[]") - localStorage.setItem(impRavencoinAddressBook, JSON.stringify(newItems)) - this.rvnBook = JSON.parse(localStorage.getItem(impRavencoinAddressBook) || "[]") - this.shadowRoot.querySelector('#importRvnAddressbookDialog').close() - } + importRvnAddressbook(file) { + const impRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress + localStorage.removeItem(impRavencoinAddressBook) + const newItems = JSON.parse((file) || "[]") + localStorage.setItem(impRavencoinAddressBook, JSON.stringify(newItems)) + this.rvnBook = JSON.parse(localStorage.getItem(impRavencoinAddressBook) || "[]") + this.shadowRoot.querySelector('#importRvnAddressbookDialog').close() + } - importArrrAddressbook(file) { - const impPiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress - localStorage.removeItem(impPiratechainAddressBook) - const newItems = JSON.parse((file) || "[]") - localStorage.setItem(impPiratechainAddressBook, JSON.stringify(newItems)) - this.arrrBook = JSON.parse(localStorage.getItem(impPiratechainAddressBook) || "[]") - this.shadowRoot.querySelector('#importArrrAddressbookDialog').close() - } + importArrrAddressbook(file) { + const impPiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress + localStorage.removeItem(impPiratechainAddressBook) + const newItems = JSON.parse((file) || "[]") + localStorage.setItem(impPiratechainAddressBook, JSON.stringify(newItems)) + this.arrrBook = JSON.parse(localStorage.getItem(impPiratechainAddressBook) || "[]") + this.shadowRoot.querySelector('#importArrrAddressbookDialog').close() + } - closeQortDialog() { - this.shadowRoot.querySelector('#sendQortDialog').close() - this.shadowRoot.getElementById('amountInput').value = '' - this.shadowRoot.getElementById('recipient').value = '' - this.recipient = '' - this.amount = 0 - this.successMessage = '' - this.errorMessage = '' - } + closeQortDialog() { + this.shadowRoot.querySelector('#sendQortDialog').close() + this.shadowRoot.getElementById('amountInput').value = '' + this.shadowRoot.getElementById('recipient').value = '' + this.recipient = '' + this.amount = 0 + this.successMessage = '' + this.errorMessage = '' + } - closeBtcDialog() { - this.shadowRoot.querySelector('#sendBtcDialog').close() - this.shadowRoot.getElementById('btcAmountInput').value = 0 - this.shadowRoot.getElementById('btcRecipient').value = '' - this.btcRecipient = '' - this.btcAmount = 0 - this.successMessage = '' - this.errorMessage = '' - } + closeBtcDialog() { + this.shadowRoot.querySelector('#sendBtcDialog').close() + this.shadowRoot.getElementById('btcAmountInput').value = 0 + this.shadowRoot.getElementById('btcRecipient').value = '' + this.btcRecipient = '' + this.btcAmount = 0 + this.successMessage = '' + this.errorMessage = '' + } - closeLtcDialog() { - this.shadowRoot.querySelector('#sendLtcDialog').close() - this.shadowRoot.getElementById('ltcAmountInput').value = 0 - this.shadowRoot.getElementById('ltcRecipient').value = '' - this.ltcRecipient = '' - this.ltcAmount = 0 - this.successMessage = '' - this.errorMessage = '' - } + closeLtcDialog() { + this.shadowRoot.querySelector('#sendLtcDialog').close() + this.shadowRoot.getElementById('ltcAmountInput').value = 0 + this.shadowRoot.getElementById('ltcRecipient').value = '' + this.ltcRecipient = '' + this.ltcAmount = 0 + this.successMessage = '' + this.errorMessage = '' + } - closeDogeDialog() { - this.shadowRoot.querySelector('#sendDogeDialog').close() - this.shadowRoot.getElementById('dogeAmountInput').value = 0 - this.shadowRoot.getElementById('dogeRecipient').value = '' - this.dogeRecipient = '' - this.dogeAmount = 0 - this.successMessage = '' - this.errorMessage = '' - } + closeDogeDialog() { + this.shadowRoot.querySelector('#sendDogeDialog').close() + this.shadowRoot.getElementById('dogeAmountInput').value = 0 + this.shadowRoot.getElementById('dogeRecipient').value = '' + this.dogeRecipient = '' + this.dogeAmount = 0 + this.successMessage = '' + this.errorMessage = '' + } - closeDgbDialog() { - this.shadowRoot.querySelector('#sendDgbDialog').close() - this.shadowRoot.getElementById('dgbAmountInput').value = 0 - this.shadowRoot.getElementById('dgbRecipient').value = '' - this.dgbRecipient = '' - this.dgbAmount = 0 - this.successMessage = '' - this.errorMessage = '' - } + closeDgbDialog() { + this.shadowRoot.querySelector('#sendDgbDialog').close() + this.shadowRoot.getElementById('dgbAmountInput').value = 0 + this.shadowRoot.getElementById('dgbRecipient').value = '' + this.dgbRecipient = '' + this.dgbAmount = 0 + this.successMessage = '' + this.errorMessage = '' + } - closeRvnDialog() { - this.shadowRoot.querySelector('#sendRvnDialog').close() - this.shadowRoot.getElementById('rvnAmountInput').value = 0 - this.shadowRoot.getElementById('rvRecipient').value = '' - this.rvnRecipient = '' - this.rvnAmount = 0 - this.successMessage = '' - this.errorMessage = '' - } + closeRvnDialog() { + this.shadowRoot.querySelector('#sendRvnDialog').close() + this.shadowRoot.getElementById('rvnAmountInput').value = 0 + this.shadowRoot.getElementById('rvRecipient').value = '' + this.rvnRecipient = '' + this.rvnAmount = 0 + this.successMessage = '' + this.errorMessage = '' + } - closeArrrDialog() { - this.shadowRoot.querySelector('#sendArrrDialog').close() - this.shadowRoot.getElementById('arrrRecipient').value = '' - this.shadowRoot.getElementById('arrrMemo').value = '' - this.arrrRecipient = '' - this.arrrMemo='' - this.arrrAmount = 0 - this.successMessage = '' - this.errorMessage = '' - } + closeArrrDialog() { + this.shadowRoot.querySelector('#sendArrrDialog').close() + this.shadowRoot.getElementById('arrrRecipient').value = '' + this.shadowRoot.getElementById('arrrMemo').value = '' + this.arrrRecipient = '' + this.arrrMemo = '' + this.arrrAmount = 0 + this.successMessage = '' + this.errorMessage = '' + } - sendToQortAddress() { - this.recipient = this.selectedTransaction.recipient - this.openSendQort() - this.shadowRoot.querySelector('#showTransactionDetailsDialog').close() - } + sendToQortAddress() { + this.recipient = this.selectedTransaction.recipient + this.openSendQort() + this.shadowRoot.querySelector('#showTransactionDetailsDialog').close() + } - sendToBtcAddress() { - this.btcRecipient = this.selectedTransaction.btcReceiver - this.openSendBtc() - this.shadowRoot.querySelector('#showBtcTransactionDetailsDialog').close() - } + sendToBtcAddress() { + this.btcRecipient = this.selectedTransaction.btcReceiver + this.openSendBtc() + this.shadowRoot.querySelector('#showBtcTransactionDetailsDialog').close() + } - sendToLtcAddress() { - this.ltcRecipient = this.selectedTransaction.ltcReceiver - this.openSendLtc() - this.shadowRoot.querySelector('#showLtcTransactionDetailsDialog').close() - } + sendToLtcAddress() { + this.ltcRecipient = this.selectedTransaction.ltcReceiver + this.openSendLtc() + this.shadowRoot.querySelector('#showLtcTransactionDetailsDialog').close() + } - sendToDogeAddress() { - this.dogeRecipient = this.selectedTransaction.dogeReceiver - this.openSendDoge() - this.shadowRoot.querySelector('#showDogeTransactionDetailsDialog').close() - } + sendToDogeAddress() { + this.dogeRecipient = this.selectedTransaction.dogeReceiver + this.openSendDoge() + this.shadowRoot.querySelector('#showDogeTransactionDetailsDialog').close() + } - sendToDgbAddress() { - this.dgbRecipient = this.selectedTransaction.dgbReceiver - this.openSendDgb() - this.shadowRoot.querySelector('#showDgbTransactionDetailsDialog').close() - } + sendToDgbAddress() { + this.dgbRecipient = this.selectedTransaction.dgbReceiver + this.openSendDgb() + this.shadowRoot.querySelector('#showDgbTransactionDetailsDialog').close() + } - sendToRvnAddress() { - this.rvnRecipient = this.selectedTransaction.rvnReceiver - this.openSendRvn() - this.shadowRoot.querySelector('#showRvnTransactionDetailsDialog').close() - } + sendToRvnAddress() { + this.rvnRecipient = this.selectedTransaction.rvnReceiver + this.openSendRvn() + this.shadowRoot.querySelector('#showRvnTransactionDetailsDialog').close() + } - sendToArrrAddress() { - this.arrrRecipient = this.selectedTransaction.arrrReceiver - this.openSendArrr() - this.shadowRoot.querySelector('#showArrrTransactionDetailsDialog').close() - } + sendToArrrAddress() { + this.arrrRecipient = this.selectedTransaction.arrrReceiver + this.openSendArrr() + this.shadowRoot.querySelector('#showArrrTransactionDetailsDialog').close() + } - calculateQortAll() { - this.amount = 0 - this.shadowRoot.getElementById('amountInput').value = this.amount - if (this.balance < 0.01100000) { - let not_enough_string = get("walletpage.wchange26") - parentEpml.request('showSnackBar', `${not_enough_string}`) - } else { - this.amount = (this.balance - 0.01100000).toFixed(8) - this.shadowRoot.getElementById('amountInput').value = this.amount - this.shadowRoot.getElementById('amountInput').blur() - this.shadowRoot.getElementById('amountInput').focus() - } - } + calculateQortAll() { + this.amount = 0 + this.shadowRoot.getElementById('amountInput').value = this.amount + if (this.balance < 0.01100000) { + let not_enough_string = get("walletpage.wchange26") + parentEpml.request('showSnackBar', `${not_enough_string}`) + } else { + this.amount = (this.balance - 0.01100000).toFixed(8) + this.shadowRoot.getElementById('amountInput').value = this.amount + this.shadowRoot.getElementById('amountInput').blur() + this.shadowRoot.getElementById('amountInput').focus() + } + } - calculateBtcAll() { - if (this.balance < 0.00051000) { - let not_enough_string = get("walletpage.wchange26") - parentEpml.request('showSnackBar', `${not_enough_string}`) - } else { - this.btcAmount = (this.balance - 0.00050000).toFixed(8) - this.btcFeePerByte = 100 - } - } + calculateBtcAll() { + if (this.balance < 0.00051000) { + let not_enough_string = get("walletpage.wchange26") + parentEpml.request('showSnackBar', `${not_enough_string}`) + } else { + this.btcAmount = (this.balance - 0.00050000).toFixed(8) + this.btcFeePerByte = 100 + } + } - calculateLtcAll() { - if (this.balance < 0.00031000) { - let not_enough_string = get("walletpage.wchange26") - parentEpml.request('showSnackBar', `${not_enough_string}`) - } else { - this.ltcAmount = (this.balance - 0.00030000).toFixed(8) - this.ltcFeePerByte = 15 - } - } + calculateLtcAll() { + if (this.balance < 0.00031000) { + let not_enough_string = get("walletpage.wchange26") + parentEpml.request('showSnackBar', `${not_enough_string}`) + } else { + this.ltcAmount = (this.balance - 0.00030000).toFixed(8) + this.ltcFeePerByte = 15 + } + } - calculateDogeAll() { - if (this.balance < 0.05100000) { - let not_enough_string = get("walletpage.wchange26") - parentEpml.request('showSnackBar', `${not_enough_string}`) - } else { - this.dogeAmount = (this.balance - 0.05000000).toFixed(8) - this.dogeFeePerByte = 1000 - } - } + calculateDogeAll() { + if (this.balance < 0.05100000) { + let not_enough_string = get("walletpage.wchange26") + parentEpml.request('showSnackBar', `${not_enough_string}`) + } else { + this.dogeAmount = (this.balance - 0.05000000).toFixed(8) + this.dogeFeePerByte = 1000 + } + } - calculateDgbAll() { - if (this.balance < 0.00005100) { - let not_enough_string = get("walletpage.wchange26") - parentEpml.request('showSnackBar', `${not_enough_string}`) - } else { - this.dgbAmount = (this.balance - 0.00005000).toFixed(8) - this.dgbFeePerByte = 10 - } - } + calculateDgbAll() { + if (this.balance < 0.00005100) { + let not_enough_string = get("walletpage.wchange26") + parentEpml.request('showSnackBar', `${not_enough_string}`) + } else { + this.dgbAmount = (this.balance - 0.00005000).toFixed(8) + this.dgbFeePerByte = 10 + } + } - calculateRvnAll() { - if (this.balance < 0.00572500) { - let not_enough_string = get("walletpage.wchange26") - parentEpml.request('showSnackBar', `${not_enough_string}`) - } else { - this.rvnAmount = (this.balance - 0.00562500).toFixed(8) - this.rvnFeePerByte = 1125 - } - } + calculateRvnAll() { + if (this.balance < 0.00572500) { + let not_enough_string = get("walletpage.wchange26") + parentEpml.request('showSnackBar', `${not_enough_string}`) + } else { + this.rvnAmount = (this.balance - 0.00562500).toFixed(8) + this.rvnFeePerByte = 1125 + } + } - calculateArrrAll() { - if (this.balance < 0.00011000) { - let not_enough_string = get("walletpage.wchange26") - parentEpml.request('showSnackBar', `${not_enough_string}`) - } else { - this.arrrAmount = (this.balance - 0.00010000).toFixed(8) - } - } + calculateArrrAll() { + if (this.balance < 0.00011000) { + let not_enough_string = get("walletpage.wchange26") + parentEpml.request('showSnackBar', `${not_enough_string}`) + } else { + this.arrrAmount = (this.balance - 0.00010000).toFixed(8) + } + } - renderSQB() { - let displaybutton = this.selectedTransaction.recipient - if (displaybutton == null) { - return html`${this.selectedTransaction.recipient}` - } else { - return html` - ${this.selectedTransaction.recipient} - this.sendToQortAddress()} title="${translate("walletpage.wchange46")}"> - this.openAddQortAddressDialog()} title="${translate("walletpage.wchange49")}"> - ` - } - } + renderSQB() { + let displaybutton = this.selectedTransaction.recipient + if (displaybutton == null) { + return html`${this.selectedTransaction.recipient}` + } else { + return html` + ${this.selectedTransaction.recipient} + this.sendToQortAddress()} title="${translate("walletpage.wchange46")}"> + this.openAddQortAddressDialog()} title="${translate("walletpage.wchange49")}"> + ` + } + } - renderCAB() { - return html` + renderCAB() { + return html` ${this.selectedTransaction.aTAddress} ` - } + } - renderFetchText() { - return html`${translate("walletpage.wchange1")}` - } + renderFetchText() { + return html`${translate("walletpage.wchange1")}` + } - renderInvalidText() { - return html`${translate("walletpage.wchange27")}` - } + renderInvalidText() { + return html`${translate("walletpage.wchange27")}` + } - renderReceiverText() { - return html`${translate("walletpage.wchange29")}` - } + renderReceiverText() { + return html`${translate("walletpage.wchange29")}` + } - renderSuccessText() { - return html`${translate("walletpage.wchange30")}` - } + renderSuccessText() { + return html`${translate("walletpage.wchange30")}` + } - renderFailText() { - return html`${translate("walletpage.wchange31")}` - } + renderFailText() { + return html`${translate("walletpage.wchange31")}` + } - renderOutText() { - return html`${translate("walletpage.wchange7")}` - } + renderOutText() { + return html`${translate("walletpage.wchange7")}` + } - renderInText() { - return html`${translate("walletpage.wchange8")}` - } + renderInText() { + return html`${translate("walletpage.wchange8")}` + } - _checkAmount(e) { - const targetAmount = e.target.value - const target = e.target + _checkAmount(e) { + const targetAmount = e.target.value + const target = e.target - if (targetAmount.length === 0) { - this.isValidAmount = false - this.btnDisable = true + if (targetAmount.length === 0) { + this.isValidAmount = false + this.btnDisable = true - e.target.blur() - e.target.focus() + e.target.blur() + e.target.focus() - e.target.invalid = true - e.target.validationMessage = this.renderInvalidText() - } else { - this.btnDisable = false - } + e.target.invalid = true + e.target.validationMessage = this.renderInvalidText() + } else { + this.btnDisable = false + } - e.target.blur() - e.target.focus() + e.target.blur() + e.target.focus() - e.target.validityTransform = (newValue, nativeValidity) => { - if (newValue.includes('-') === true) { - this.btnDisable = true - target.validationMessage = this.renderInvalidText() + e.target.validityTransform = (newValue, nativeValidity) => { + if (newValue.includes('-') === true) { + this.btnDisable = true + target.validationMessage = this.renderInvalidText() - return { - valid: false, - } - } else if (!nativeValidity.valid) { - if (newValue.includes('.') === true) { - let myAmount = newValue.split('.') - if (myAmount[1].length > 8) { - this.btnDisable = true - target.validationMessage = this.renderInvalidText() - } else { - return { - valid: true, - } - } - } - } else { - this.btnDisable = false - } - } - } + return { + valid: false + } + } else if (!nativeValidity.valid) { + if (newValue.includes('.') === true) { + let myAmount = newValue.split('.') + if (myAmount[1].length > 8) { + this.btnDisable = true + target.validationMessage = this.renderInvalidText() + } else { + return { + valid: true + } + } + } + } else { + this.btnDisable = false + } + } + } - checkQortAmount(e) { - const targetAmount = e.target.value - const target = e.target - this.btnDisable = true - this.qortWarning = false + checkQortAmount(e) { + const targetAmount = e.target.value + const target = e.target + this.btnDisable = true + this.qortWarning = false - if (targetAmount.length === 0) { - this.isValidAmount = false - this.btnDisable = true - this.qortWarning = false - e.target.blur() - e.target.focus() - e.target.invalid = true - } else { - const checkQortAmountInput = this.shadowRoot.getElementById('amountInput').value - const checkQortAmount = this.round(parseFloat(checkQortAmountInput)) - const myFunds = this.round(parseFloat(this.balance - 0.01100000)) - if (Number(myFunds) >= Number(checkQortAmount)) { - this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput - this.btnDisable = false - this.qortWarning = false - } else { - this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput - this.btnDisable = true - this.qortWarning = true - } - } + if (targetAmount.length === 0) { + this.isValidAmount = false + this.btnDisable = true + this.qortWarning = false + e.target.blur() + e.target.focus() + e.target.invalid = true + } else { + const checkQortAmountInput = this.shadowRoot.getElementById('amountInput').value + const checkQortAmount = this.round(parseFloat(checkQortAmountInput)) + const myFunds = this.round(parseFloat(this.balance - 0.01100000)) + if (Number(myFunds) >= Number(checkQortAmount)) { + this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput + this.btnDisable = false + this.qortWarning = false + } else { + this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput + this.btnDisable = true + this.qortWarning = true + } + } - e.target.blur() - e.target.focus() + e.target.blur() + e.target.focus() - e.target.validityTransform = (newValue, nativeValidity) => { - if (newValue.includes('-') === true) { - this.btnDisable = true - this.qortWarning = false - return { - valid: false, - } - } else if (!nativeValidity.valid) { - if (newValue.includes('.') === true) { - let myAmount = newValue.split('.') - if (myAmount[1].length > 8) { - this.btnDisable = true - this.qortWarning = false - } else { - const checkQortAmountInput = this.shadowRoot.getElementById('amountInput').value - const checkQortAmount = this.round(parseFloat(checkQortAmountInput)) - const myFunds = this.round(parseFloat(this.balance - 0.01100000)) - if (Number(myFunds) >= Number(checkQortAmount)) { - this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput - this.btnDisable = false - this.qortWarning = false - } else { - this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput - this.btnDisable = true - this.qortWarning = true - } - return { - valid: true, - } - } - } - } else { - const checkQortAmountInput = this.shadowRoot.getElementById('amountInput').value - const checkQortAmount = this.round(parseFloat(checkQortAmountInput)) - const myFunds = this.round(parseFloat(this.balance - 0.01100000)) - if (Number(myFunds) >= Number(checkQortAmount)) { - this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput - this.btnDisable = false - this.qortWarning = false - } else { - this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput - this.btnDisable = true - this.qortWarning = true - } - } - } - } + e.target.validityTransform = (newValue, nativeValidity) => { + if (newValue.includes('-') === true) { + this.btnDisable = true + this.qortWarning = false + return { + valid: false + } + } else if (!nativeValidity.valid) { + if (newValue.includes('.') === true) { + let myAmount = newValue.split('.') + if (myAmount[1].length > 8) { + this.btnDisable = true + this.qortWarning = false + } else { + const checkQortAmountInput = this.shadowRoot.getElementById('amountInput').value + const checkQortAmount = this.round(parseFloat(checkQortAmountInput)) + const myFunds = this.round(parseFloat(this.balance - 0.01100000)) + if (Number(myFunds) >= Number(checkQortAmount)) { + this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput + this.btnDisable = false + this.qortWarning = false + } else { + this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput + this.btnDisable = true + this.qortWarning = true + } + return { + valid: true + } + } + } + } else { + const checkQortAmountInput = this.shadowRoot.getElementById('amountInput').value + const checkQortAmount = this.round(parseFloat(checkQortAmountInput)) + const myFunds = this.round(parseFloat(this.balance - 0.01100000)) + if (Number(myFunds) >= Number(checkQortAmount)) { + this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput + this.btnDisable = false + this.qortWarning = false + } else { + this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput + this.btnDisable = true + this.qortWarning = true + } + } + } + } - async sendQort() { - const sendFee = this.qortPaymentFee - const amount = this.shadowRoot.getElementById('amountInput').value - let recipient = this.shadowRoot.getElementById('recipient').value + async sendQort() { + const sendFee = this.qortPaymentFee + const amount = this.shadowRoot.getElementById('amountInput').value + let recipient = this.shadowRoot.getElementById('recipient').value - this.sendMoneyLoading = true - this.btnDisable = true + this.sendMoneyLoading = true + this.btnDisable = true - if (parseFloat(amount) + parseFloat(0.001) > parseFloat(this.balance)) { - this.sendMoneyLoading = false - this.btnDisable = false - let snack1string = get("walletpage.wchange26") - parentEpml.request('showSnackBar', `${snack1string}`) - return false - } + if (parseFloat(amount) + parseFloat(0.001) > parseFloat(this.balance)) { + this.sendMoneyLoading = false + this.btnDisable = false + let snack1string = get("walletpage.wchange26") + parentEpml.request('showSnackBar', `${snack1string}`) + return false + } - if (parseFloat(amount) <= 0) { - this.sendMoneyLoading = false - this.btnDisable = false - let snack2string = get("walletpage.wchange27") - parentEpml.request('showSnackBar', `${snack2string}`) - return false - } + if (parseFloat(amount) <= 0) { + this.sendMoneyLoading = false + this.btnDisable = false + let snack2string = get("walletpage.wchange27") + parentEpml.request('showSnackBar', `${snack2string}`) + return false + } - if (recipient.length === 0) { - this.sendMoneyLoading = false - this.btnDisable = false - let snack3string = get("walletpage.wchange28") - parentEpml.request('showSnackBar', `${snack3string}`) - return false - } + if (recipient.length === 0) { + this.sendMoneyLoading = false + this.btnDisable = false + let snack3string = get("walletpage.wchange28") + parentEpml.request('showSnackBar', `${snack3string}`) + return false + } - const getLastRef = async () => { - return await parentEpml.request('apiCall', { - type: 'api', - url: `/addresses/lastreference/${this.getSelectedWalletAddress()}`, - }) - } + const getLastRef = async () => { + return await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/lastreference/${this.getSelectedWalletAddress()}` + }) + } - const validateName = async (receiverName) => { - let myRes - let myNameRes = await parentEpml.request('apiCall', { - type: 'api', - url: `/names/${receiverName}`, - }) + const validateName = async (receiverName) => { + let myRes + let myNameRes = await parentEpml.request('apiCall', { + type: 'api', + url: `/names/${receiverName}` + }) - if (myNameRes.error === 401) { - myRes = false - } else { - myRes = myNameRes - } - return myRes - } + if (myNameRes.error === 401) { + myRes = false + } else { + myRes = myNameRes + } + return myRes + } - const validateAddress = async (receiverAddress) => { + const validateAddress = async (receiverAddress) => { return await window.parent.validateAddress(receiverAddress) - } + } - const validateReceiver = async (recipient) => { - let lastRef = await getLastRef() - let isAddress + const validateReceiver = async (recipient) => { + let lastRef = await getLastRef() + let isAddress - try { - isAddress = await validateAddress(recipient) - } catch (err) { - isAddress = false - } + try { + isAddress = await validateAddress(recipient) + } catch (err) { + isAddress = false + } - if (isAddress) { - let myTransaction = await makeTransactionRequest(recipient, lastRef) - getTxnRequestResponse(myTransaction) - } else { - let myNameRes = await validateName(recipient) - if (myNameRes !== false) { - let myNameAddress = myNameRes.owner - let myTransaction = await makeTransactionRequest(myNameAddress, lastRef) - getTxnRequestResponse(myTransaction) - } else { - console.error(this.renderReceiverText()) - this.errorMessage = this.renderReceiverText() - this.sendMoneyLoading = false - this.btnDisable = false - } - } - } + if (isAddress) { + let myTransaction = await makeTransactionRequest(recipient, lastRef) + getTxnRequestResponse(myTransaction) + } else { + let myNameRes = await validateName(recipient) + if (myNameRes !== false) { + let myNameAddress = myNameRes.owner + let myTransaction = await makeTransactionRequest(myNameAddress, lastRef) + getTxnRequestResponse(myTransaction) + } else { + console.error(this.renderReceiverText()) + this.errorMessage = this.renderReceiverText() + this.sendMoneyLoading = false + this.btnDisable = false + } + } + } - const getName = async (recipient)=> { - try { - const getNames = await parentEpml.request("apiCall", { - type: "api", - url: `/names/address/${recipient}`, - }) - if(getNames?.length > 0 ){ - return getNames[0].name - } else { - return '' - } - } catch (error) { - return "" - } - } + const getName = async (recipient) => { + try { + const getNames = await parentEpml.request("apiCall", { + type: "api", + url: `/names/address/${recipient}` + }) + if (getNames?.length > 0) { + return getNames[0].name + } else { + return '' + } + } catch (error) { + return '' + } + } - const makeTransactionRequest = async (receiver, lastRef) => { - let myReceiver = receiver - let mylastRef = lastRef - let dialogamount = get("transactions.amount") - let dialogAddress = get("login.address") - let dialogName = get("login.name") - let dialogto = get("transactions.to") - let recipientName = await getName(myReceiver) + const makeTransactionRequest = async (receiver, lastRef) => { + let myReceiver = receiver + let mylastRef = lastRef + let dialogamount = get("transactions.amount") + let dialogAddress = get("login.address") + let dialogName = get("login.name") + let dialogto = get("transactions.to") + let recipientName = await getName(myReceiver) - return await parentEpml.request('transaction', { - type: 2, - nonce: this.wallets.get(this._selectedWallet).wallet.nonce, - params: { - recipient: myReceiver, - recipientName: recipientName, - amount: amount, - lastReference: mylastRef, - fee: sendFee, - dialogamount: dialogamount, - dialogto: dialogto, - dialogAddress, - dialogName - }, - }) - } + return await parentEpml.request('transaction', { + type: 2, + nonce: this.wallets.get(this._selectedWallet).wallet.nonce, + params: { + recipient: myReceiver, + recipientName: recipientName, + amount: amount, + lastReference: mylastRef, + fee: sendFee, + dialogamount: dialogamount, + dialogto: dialogto, + dialogAddress, + dialogName + }, + }) + } - const getTxnRequestResponse = (txnResponse) => { - if (txnResponse.success === false && txnResponse.message) { - this.errorMessage = txnResponse.message - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(txnResponse) - } else if (txnResponse.success === true && !txnResponse.data.error) { - this.shadowRoot.getElementById('amountInput').value = '' - this.shadowRoot.getElementById('recipient').value = '' - this.errorMessage = '' - this.recipient = '' - this.amount = 0 - this.successMessage = this.renderSuccessText() - this.sendMoneyLoading = false - this.btnDisable = false - } else { - this.errorMessage = txnResponse.data.message - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(txnResponse) - } - } - await validateReceiver(recipient) - await this.showWallet() - } + const getTxnRequestResponse = (txnResponse) => { + if (txnResponse.success === false && txnResponse.message) { + this.errorMessage = txnResponse.message + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } else if (txnResponse.success === true && !txnResponse.data.error) { + this.shadowRoot.getElementById('amountInput').value = '' + this.shadowRoot.getElementById('recipient').value = '' + this.errorMessage = '' + this.recipient = '' + this.amount = 0 + this.successMessage = this.renderSuccessText() + this.sendMoneyLoading = false + this.btnDisable = false + } else { + this.errorMessage = txnResponse.data.message + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } + } + await validateReceiver(recipient) + await this.showWallet() + } - async sendBtc() { - const btcAmount = this.shadowRoot.getElementById('btcAmountInput').value - let btcRecipient = this.shadowRoot.getElementById('btcRecipient').value - const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey + async sendBtc() { + const btcAmount = this.shadowRoot.getElementById('btcAmountInput').value + let btcRecipient = this.shadowRoot.getElementById('btcRecipient').value + const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey - this.sendMoneyLoading = true - this.btnDisable = true + this.sendMoneyLoading = true + this.btnDisable = true - const makeRequest = async () => { - const opts = { - xprv58: xprv58, - receivingAddress: btcRecipient, - bitcoinAmount: btcAmount, - feePerByte: (this.btcFeePerByte / 1e8).toFixed(8), - } - return await parentEpml.request('sendBtc', opts) - } + const makeRequest = async () => { + const opts = { + xprv58: xprv58, + receivingAddress: btcRecipient, + bitcoinAmount: btcAmount, + feePerByte: (this.btcFeePerByte / 1e8).toFixed(8) + } + return await parentEpml.request('sendBtc', opts) + } - const manageResponse = (response) => { - if (response.length === 64) { - this.shadowRoot.getElementById('btcAmountInput').value = 0 - this.shadowRoot.getElementById('btcRecipient').value = '' - this.errorMessage = '' - this.btcRecipient = '' - this.btcAmount = 0 - this.successMessage = this.renderSuccessText() - this.sendMoneyLoading = false - this.btnDisable = false - } else if (response === false) { - this.errorMessage = this.renderFailText() - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(txnResponse) - } else { - this.errorMessage = response.message - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(response) - } - } - const res = await makeRequest() - manageResponse(res) - await this.showWallet() - } + const manageResponse = (response) => { + if (response.length === 64) { + this.shadowRoot.getElementById('btcAmountInput').value = 0 + this.shadowRoot.getElementById('btcRecipient').value = '' + this.errorMessage = '' + this.btcRecipient = '' + this.btcAmount = 0 + this.successMessage = this.renderSuccessText() + this.sendMoneyLoading = false + this.btnDisable = false + } else if (response === false) { + this.errorMessage = this.renderFailText() + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } else { + this.errorMessage = response.message + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(response) + } + } + const res = await makeRequest() + manageResponse(res) + await this.showWallet() + } - async sendLtc() { - const ltcAmount = this.shadowRoot.getElementById('ltcAmountInput').value - const ltcRecipient = this.shadowRoot.getElementById('ltcRecipient').value - const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey + async sendLtc() { + const ltcAmount = this.shadowRoot.getElementById('ltcAmountInput').value + const ltcRecipient = this.shadowRoot.getElementById('ltcRecipient').value + const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey - this.sendMoneyLoading = true - this.btnDisable = true + this.sendMoneyLoading = true + this.btnDisable = true - const makeRequest = async () => { - const opts = { - xprv58: xprv58, - receivingAddress: ltcRecipient, - litecoinAmount: ltcAmount, - feePerByte: (this.ltcFeePerByte / 1e8).toFixed(8), - } + const makeRequest = async () => { + const opts = { + xprv58: xprv58, + receivingAddress: ltcRecipient, + litecoinAmount: ltcAmount, + feePerByte: (this.ltcFeePerByte / 1e8).toFixed(8) + } return await parentEpml.request('sendLtc', opts) - } + } - const manageResponse = (response) => { - if (response.length === 64) { - this.shadowRoot.getElementById('ltcAmountInput').value = 0 - this.shadowRoot.getElementById('ltcRecipient').value = '' - this.errorMessage = '' - this.ltcRecipient = '' - this.ltcAmount = 0 - this.successMessage = this.renderSuccessText() - this.sendMoneyLoading = false - this.btnDisable = false - } else if (response === false) { - this.errorMessage = this.renderFailText() - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(txnResponse) - } else { - this.errorMessage = response.message - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(response) - } - } - const res = await makeRequest() - manageResponse(res) - await this.showWallet() - } + const manageResponse = (response) => { + if (response.length === 64) { + this.shadowRoot.getElementById('ltcAmountInput').value = 0 + this.shadowRoot.getElementById('ltcRecipient').value = '' + this.errorMessage = '' + this.ltcRecipient = '' + this.ltcAmount = 0 + this.successMessage = this.renderSuccessText() + this.sendMoneyLoading = false + this.btnDisable = false + } else if (response === false) { + this.errorMessage = this.renderFailText() + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } else { + this.errorMessage = response.message + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(response) + } + } + const res = await makeRequest() + manageResponse(res) + await this.showWallet() + } - async sendDoge() { - const dogeAmount = this.shadowRoot.getElementById('dogeAmountInput').value - let dogeRecipient = this.shadowRoot.getElementById('dogeRecipient').value - const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey + async sendDoge() { + const dogeAmount = this.shadowRoot.getElementById('dogeAmountInput').value + let dogeRecipient = this.shadowRoot.getElementById('dogeRecipient').value + const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey - this.sendMoneyLoading = true - this.btnDisable = true + this.sendMoneyLoading = true + this.btnDisable = true - const makeRequest = async () => { - const opts = { - xprv58: xprv58, - receivingAddress: dogeRecipient, - dogecoinAmount: dogeAmount, - feePerByte: (this.dogeFeePerByte / 1e8).toFixed(8), - } - return await parentEpml.request('sendDoge', opts) - } + const makeRequest = async () => { + const opts = { + xprv58: xprv58, + receivingAddress: dogeRecipient, + dogecoinAmount: dogeAmount, + feePerByte: (this.dogeFeePerByte / 1e8).toFixed(8) + } + return await parentEpml.request('sendDoge', opts) + } - const manageResponse = (response) => { - if (response.length === 64) { - this.shadowRoot.getElementById('dogeAmountInput').value = 0 - this.shadowRoot.getElementById('dogeRecipient').value = '' - this.errorMessage = '' - this.dogeRecipient = '' - this.dogeAmount = 0 - this.successMessage = this.renderSuccessText() - this.sendMoneyLoading = false - this.btnDisable = false - } else if (response === false) { - this.errorMessage = this.renderFailText() - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(txnResponse) - } else { - this.errorMessage = response.message - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(response) - } - } - const res = await makeRequest() - manageResponse(res) - await this.showWallet() - } + const manageResponse = (response) => { + if (response.length === 64) { + this.shadowRoot.getElementById('dogeAmountInput').value = 0 + this.shadowRoot.getElementById('dogeRecipient').value = '' + this.errorMessage = '' + this.dogeRecipient = '' + this.dogeAmount = 0 + this.successMessage = this.renderSuccessText() + this.sendMoneyLoading = false + this.btnDisable = false + } else if (response === false) { + this.errorMessage = this.renderFailText() + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } else { + this.errorMessage = response.message + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(response) + } + } + const res = await makeRequest() + manageResponse(res) + await this.showWallet() + } - async sendDgb() { - const dgbAmount = this.shadowRoot.getElementById('dgbAmountInput').value - let dgbRecipient = this.shadowRoot.getElementById('dgbRecipient').value - const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey + async sendDgb() { + const dgbAmount = this.shadowRoot.getElementById('dgbAmountInput').value + let dgbRecipient = this.shadowRoot.getElementById('dgbRecipient').value + const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey - this.sendMoneyLoading = true - this.btnDisable = true + this.sendMoneyLoading = true + this.btnDisable = true - const makeRequest = async () => { - const opts = { - xprv58: xprv58, - receivingAddress: dgbRecipient, - digibyteAmount: dgbAmount, - feePerByte: (this.dgbFeePerByte / 1e8).toFixed(8), - } - return await parentEpml.request('sendDgb', opts) - } + const makeRequest = async () => { + const opts = { + xprv58: xprv58, + receivingAddress: dgbRecipient, + digibyteAmount: dgbAmount, + feePerByte: (this.dgbFeePerByte / 1e8).toFixed(8) + } + return await parentEpml.request('sendDgb', opts) + } - const manageResponse = (response) => { - if (response.length === 64) { - this.shadowRoot.getElementById('dgbAmountInput').value = 0 - this.shadowRoot.getElementById('dgbRecipient').value = '' - this.errorMessage = '' - this.dgbRecipient = '' - this.dgbAmount = 0 - this.successMessage = this.renderSuccessText() - this.sendMoneyLoading = false - this.btnDisable = false - } else if (response === false) { - this.errorMessage = this.renderFailText() - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(txnResponse) - } else { - this.errorMessage = response.message - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(response) - } - } - const res = await makeRequest() - manageResponse(res) - await this.showWallet() - } + const manageResponse = (response) => { + if (response.length === 64) { + this.shadowRoot.getElementById('dgbAmountInput').value = 0 + this.shadowRoot.getElementById('dgbRecipient').value = '' + this.errorMessage = '' + this.dgbRecipient = '' + this.dgbAmount = 0 + this.successMessage = this.renderSuccessText() + this.sendMoneyLoading = false + this.btnDisable = false + } else if (response === false) { + this.errorMessage = this.renderFailText() + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } else { + this.errorMessage = response.message + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(response) + } + } + const res = await makeRequest() + manageResponse(res) + await this.showWallet() + } - async sendRvn() { - const rvnAmount = this.shadowRoot.getElementById('rvnAmountInput').value - let rvnRecipient = this.shadowRoot.getElementById('rvnRecipient').value - const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey + async sendRvn() { + const rvnAmount = this.shadowRoot.getElementById('rvnAmountInput').value + let rvnRecipient = this.shadowRoot.getElementById('rvnRecipient').value + const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey - this.sendMoneyLoading = true - this.btnDisable = true + this.sendMoneyLoading = true + this.btnDisable = true - const makeRequest = async () => { - const opts = { - xprv58: xprv58, - receivingAddress: rvnRecipient, - ravencoinAmount: rvnAmount, - feePerByte: (this.rvnFeePerByte / 1e8).toFixed(8), - } + const makeRequest = async () => { + const opts = { + xprv58: xprv58, + receivingAddress: rvnRecipient, + ravencoinAmount: rvnAmount, + feePerByte: (this.rvnFeePerByte / 1e8).toFixed(8) + } return await parentEpml.request('sendRvn', opts) - } - - const manageResponse = (response) => { - if (response.length === 64) { - this.shadowRoot.getElementById('rvnAmountInput').value = 0 - this.shadowRoot.getElementById('rvnRecipient').value = '' - this.errorMessage = '' - this.rvnRecipient = '' - this.rvnAmount = 0 - this.successMessage = this.renderSuccessText() - this.sendMoneyLoading = false - this.btnDisable = false - } else if (response === false) { - this.errorMessage = this.renderFailText() - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(txnResponse) - } else { - this.errorMessage = response.message - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(response) - } - } - const res = await makeRequest() - manageResponse(res) - await this.showWallet() - } - - async sendArrr() { - const arrrAmount = this.shadowRoot.getElementById('arrrAmountInput').value - let arrrRecipient = this.shadowRoot.getElementById('arrrRecipient').value - let arrrMemo = this.shadowRoot.getElementById('arrrMemo').value - const seed58 = this.wallets.get(this._selectedWallet).wallet.seed58 - - this.sendMoneyLoading = true - this.btnDisable = true - - const makeRequest = async () => { - const opts = { - entropy58: seed58, - receivingAddress: arrrRecipient, - arrrAmount: arrrAmount, - memo: arrrMemo - } - return await parentEpml.request('sendArrr', opts) - } - - const manageResponse = (response) => { - if (response.length === 64) { - this.shadowRoot.getElementById('arrrAmountInput').value = 0 - this.shadowRoot.getElementById('arrrRecipient').value = '' - this.shadowRoot.getElementById('arrrMemo').value = '' - this.errorMessage = '' - this.arrrRecipient = '' - this.arrrMemo='' - this.arrrAmount = 0 - this.successMessage = this.renderSuccessText() - this.sendMoneyLoading = false - this.btnDisable = false - } else if (response === false) { - this.errorMessage = this.renderFailText() - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(txnResponse) - } else { - this.errorMessage = response.message - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(response) - } - } - const res = await makeRequest() - manageResponse(res) - await this.showWallet() - } - - async showWallet() { - this.transactionsDOM.hidden = true - this.loading = true - - if (this._selectedWallet == 'qort') { - if (!window.parent.reduxStore.getState().app.blockInfo.height) { - await parentEpml.request('apiCall', { url: `/blocks/height`, type: 'api' }) - .then(height => parentEpml.request('updateBlockInfo', { height })) - } - } - const coin = this._selectedWallet - await this.fetchWalletAddress(this._selectedWallet) - await this.fetchWalletServer(this._selectedWallet) - await this.fetchWalletDetails(this._selectedWallet) - await this.fetchWalletServer(this._selectedWallet) - if (this._selectedWallet == coin) { - await this.renderTransactions() - await this.getTransactionGrid(this._selectedWallet) - await this.updateItemsFromPage(1, true) - this.loading = false - this.transactionsDOM.hidden = false - } - } - - async fetchWalletDetails(coin) { - switch (coin) { - case 'qort': - this.balanceString = this.renderFetchText() - parentEpml.request('apiCall', { - url: `/addresses/balance/${this.wallets.get('qort').wallet.address}?apiKey=${this.getApiKey()}`, - }) - .then((res) => { - if (isNaN(Number(res))) { - let snack4string = get("walletpage.wchange32") - parentEpml.request('showSnackBar', `${snack4string}`) - } else { - if (this._selectedWallet == coin) { - this.wallets.get(coin).balance = Number(res).toFixed(8) - this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase() - this.balance = this.wallets.get(this._selectedWallet).balance - } - } - }) - const txsQort = await parentEpml.request('apiCall', { - url: `/transactions/search?address=${this.wallets.get('qort').wallet.address}&confirmationStatus=CONFIRMED&reverse=true&txType=PAYMENT&txType=REGISTER_NAME&txType=UPDATE_NAME&txType=SELL_NAME&txType=CANCEL_SELL_NAME&txType=BUY_NAME&txType=CREATE_POLL&txType=VOTE_ON_POLL&txType=ARBITRARY&txType=ISSUE_ASSET&txType=TRANSFER_ASSET&txType=CREATE_ASSET_ORDER&txType=CANCEL_ASSET_ORDER&txType=MULTI_PAYMENT&txType=DEPLOY_AT&txType=MESSAGE&txType=AIRDROP&txType=AT&txType=CREATE_GROUP&txType=UPDATE_GROUP&txType=ADD_GROUP_ADMIN&txType=REMOVE_GROUP_ADMIN&txType=GROUP_BAN&txType=CANCEL_GROUP_BAN&txType=GROUP_KICK&txType=GROUP_INVITE&txType=CANCEL_GROUP_INVITE&txType=JOIN_GROUP&txType=LEAVE_GROUP&txType=GROUP_APPROVAL&txType=SET_GROUP&txType=UPDATE_ASSET&txType=ACCOUNT_FLAGS&txType=ENABLE_FORGING&txType=REWARD_SHARE&txType=ACCOUNT_LEVEL&txType=TRANSFER_PRIVS&txType=PRESENCE`, - }) - const pendingTxsQort = await parentEpml.request('apiCall', { - url: `/transactions/unconfirmed?creator=${this.wallets.get('qort').wallet.base58PublicKey}&reverse=true&txType=PAYMENT&txType=REGISTER_NAME&txType=UPDATE_NAME&txType=SELL_NAME&txType=CANCEL_SELL_NAME&txType=BUY_NAME&txType=CREATE_POLL&txType=VOTE_ON_POLL&txType=ARBITRARY&txType=ISSUE_ASSET&txType=TRANSFER_ASSET&txType=CREATE_ASSET_ORDER&txType=CANCEL_ASSET_ORDER&txType=MULTI_PAYMENT&txType=DEPLOY_AT&txType=MESSAGE&txType=AIRDROP&txType=AT&txType=CREATE_GROUP&txType=UPDATE_GROUP&txType=ADD_GROUP_ADMIN&txType=REMOVE_GROUP_ADMIN&txType=GROUP_BAN&txType=CANCEL_GROUP_BAN&txType=GROUP_KICK&txType=GROUP_INVITE&txType=CANCEL_GROUP_INVITE&txType=JOIN_GROUP&txType=LEAVE_GROUP&txType=GROUP_APPROVAL&txType=SET_GROUP&txType=UPDATE_ASSET&txType=ACCOUNT_FLAGS&txType=ENABLE_FORGING&txType=REWARD_SHARE&txType=ACCOUNT_LEVEL&txType=TRANSFER_PRIVS&txType=PRESENCE`, - }) - if (this._selectedWallet == coin) { - this.wallets.get(coin).transactions = pendingTxsQort.concat(txsQort) - } - break - case 'btc': - case 'ltc': - case 'doge': - case 'dgb': - case 'rvn': - this.balanceString = this.renderFetchText() - const walletName = `${coin}Wallet` - parentEpml.request('apiCall', { - url: `/crosschain/${coin}/walletbalance?apiKey=${this.getApiKey()}`, - method: 'POST', - body: `${window.parent.reduxStore.getState().app.selectedAddress[walletName].derivedMasterPublicKey}`, - }) - .then((res) => { - if (isNaN(Number(res))) { - let snack5string = get("walletpage.wchange33") - let snack6string = get("walletpage.wchange34") - parentEpml.request('showSnackBar', `${snack5string} ${coin.toLocaleUpperCase()} ${snack6string}!`) - } else { - if (this._selectedWallet == coin) { - this.wallets.get(this._selectedWallet).balance = (Number(res) / 1e8).toFixed(8) - this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase() - this.balance = this.wallets.get(this._selectedWallet).balance - } - } - }) - - const txs = await parentEpml.request('apiCall', { - url: `/crosschain/${coin}/wallettransactions?apiKey=${this.getApiKey()}`, - method: 'POST', - body: `${window.parent.reduxStore.getState().app.selectedAddress[walletName].derivedMasterPublicKey}`, - }) - - const compareFn = (a, b) => { - return b.timestamp - a.timestamp - } - - const sortedTransactions = txs.sort(compareFn) - if (this._selectedWallet == coin) { - this.wallets.get(this._selectedWallet).transactions = sortedTransactions - } - break - case 'arrr': - const arrrWalletName = `${coin}Wallet` - - const res = await parentEpml.request('apiCall', { - url: `/crosschain/${coin}/syncstatus?apiKey=${this.getApiKey()}`, - method: 'POST', - body: `${window.parent.reduxStore.getState().app.selectedAddress[arrrWalletName].seed58}`, - }) - - if (coin != this._selectedWallet) { - // We've switched away from this coin - } - - if (res.indexOf('<') > -1) { - this.balanceString = this.renderFetchText() - await new Promise(resolve => setTimeout(resolve, 2000)) - await this.showWallet() - return - } else if (res !== "Synchronized") { - this.balanceString = res - await new Promise(resolve => setTimeout(resolve, 2000)) - await this.showWallet() - return - } - - this.balanceString = this.renderFetchText() - - parentEpml.request('apiCall', { - url: `/crosschain/${coin}/walletbalance?apiKey=${this.getApiKey()}`, - method: 'POST', - body: `${window.parent.reduxStore.getState().app.selectedAddress[arrrWalletName].seed58}`, - }) - .then((res) => { - if (isNaN(Number(res))) { - let snack5string = get("walletpage.wchange33") - let snack6string = get("walletpage.wchange34") - parentEpml.request('showSnackBar', `${snack5string} ${coin.toLocaleUpperCase()} ${snack6string}!`) - } else { - if (this._selectedWallet == coin) { - this.wallets.get(this._selectedWallet).balance = (Number(res) / 1e8).toFixed(8) - this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase() - this.balance = this.wallets.get(this._selectedWallet).balance - } - } - }) - - const arrrTxs = await parentEpml.request('apiCall', { - url: `/crosschain/${coin}/wallettransactions?apiKey=${this.getApiKey()}`, - method: 'POST', - body: `${window.parent.reduxStore.getState().app.selectedAddress[arrrWalletName].seed58}`, - }) - - const arrrCompareFn = (a, b) => { - return b.timestamp - a.timestamp - } - - const arrrSortedTransactions = arrrTxs.sort(arrrCompareFn) - - if (this._selectedWallet == coin) { - this.wallets.get(this._selectedWallet).transactions = arrrSortedTransactions - } - break - default: - break - } - } - - async fetchWalletAddress(coin) { - switch (coin) { - case 'arrr': - const arrrWalletName = `${coin}Wallet` - let res = await parentEpml.request('apiCall', { - url: `/crosschain/${coin}/walletaddress?apiKey=${this.getApiKey()}`, - method: 'POST', - body: `${window.parent.reduxStore.getState().app.selectedAddress[arrrWalletName].seed58}`, - }) - if (res != null && res.error != 1201 && res.length === 78) { - this.arrrWalletAddress = res - } - break - - default: - // Not used for other coins yet - break - } - } - - renderSendButton() { - if ( this._selectedWallet === "qort" ) { - return html` this.openSendQort()}> ${translate("walletpage.wchange17")} QORT` - } else if ( this._selectedWallet === "btc" ) { - return html` this.openSendBtc()}> ${translate("walletpage.wchange17")} BTC` - } else if ( this._selectedWallet === "ltc" ) { - return html` this.openSendLtc()}> ${translate("walletpage.wchange17")} LTC` - } else if ( this._selectedWallet === "doge" ) { - return html` this.openSendDoge()}> ${translate("walletpage.wchange17")} DOGE` - } else if ( this._selectedWallet === "dgb" ) { - return html` this.openSendDgb()}> ${translate("walletpage.wchange17")} DGB` - } else if ( this._selectedWallet === "rvn" ) { - return html` this.openSendRvn()}> ${translate("walletpage.wchange17")} RVN` - } else if ( this._selectedWallet === "arrr" ) { - return html` this.openSendArrr()}> ${translate("walletpage.wchange17")} ARRR` - } else { - return html`` - } - } - - renderAddressbookButton() { - if ( this._selectedWallet === "qort" ) { - return html` this.openQortAddressbook()}> ${translate("walletpage.wchange47")}` - } else if ( this._selectedWallet === "btc" ) { - return html` this.openBtcAddressbook()}> ${translate("walletpage.wchange47")}` - } else if ( this._selectedWallet === "ltc" ) { - return html` this.openLtcAddressbook()}> ${translate("walletpage.wchange47")}` - } else if ( this._selectedWallet === "doge" ) { - return html` this.openDogeAddressbook()}> ${translate("walletpage.wchange47")}` - } else if ( this._selectedWallet === "dgb" ) { - return html` this.openDgbAddressbook()}> ${translate("walletpage.wchange47")}` - } else if ( this._selectedWallet === "rvn" ) { - return html` this.openRvnAddressbook()}> ${translate("walletpage.wchange47")}` - } else if ( this._selectedWallet === "arrr" ) { - return html` this.openArrrAddressbook()}> ${translate("walletpage.wchange47")}` - } else { - return html`` - } - } - - renderExportAddressbookButton() { - if ( this._selectedWallet === "qort" ) { - return html` this.exportQortAddressbook()}> ${translate("walletpage.wchange54")}` - } else if ( this._selectedWallet === "btc" ) { - return html` this.exportBtcAddressbook()}> ${translate("walletpage.wchange54")}` - } else if ( this._selectedWallet === "ltc" ) { - return html` this.exportLtcAddressbook()}> ${translate("walletpage.wchange54")}` - } else if ( this._selectedWallet === "doge" ) { - return html` this.exportDogeAddressbook()}> ${translate("walletpage.wchange54")}` - } else if ( this._selectedWallet === "dgb" ) { - return html` this.exportDgbAddressbook()}> ${translate("walletpage.wchange54")}` - } else if ( this._selectedWallet === "rvn" ) { - return html` this.exportRvnAddressbook()}> ${translate("walletpage.wchange54")}` - } else if ( this._selectedWallet === "arrr" ) { - return html` this.exportArrrAddressbook()}> ${translate("walletpage.wchange54")}` - } else { - return html`` - } - } - - renderImportAddressbookButton() { - if ( this._selectedWallet === "qort" ) { - return html` this.openImportQortAddressbook()}> ${translate("walletpage.wchange53")}` - } else if ( this._selectedWallet === "btc" ) { - return html` this.openImportBtcAddressbook()}> ${translate("walletpage.wchange53")}` - } else if ( this._selectedWallet === "ltc" ) { - return html` this.openImportLtcAddressbook()}> ${translate("walletpage.wchange53")}` - } else if ( this._selectedWallet === "doge" ) { - return html` this.openImportDogeAddressbook()}> ${translate("walletpage.wchange53")}` - } else if ( this._selectedWallet === "dgb" ) { - return html` this.openImportDgbAddressbook()}> ${translate("walletpage.wchange53")}` - } else if ( this._selectedWallet === "rvn" ) { - return html` this.openImportRvnAddressbook()}> ${translate("walletpage.wchange53")}` - } else if ( this._selectedWallet === "arrr" ) { - return html` this.openImportArrrAddressbook()}> ${translate("walletpage.wchange53")}` - } else { - return html`` - } - } - - openSendQort() { - this.shadowRoot.querySelector("#sendQortDialog").show(); - } - - openSendBtc() { - this.shadowRoot.querySelector("#sendBtcDialog").show(); - } - - openSendLtc() { - this.shadowRoot.querySelector("#sendLtcDialog").show(); - } - - openSendDoge() { - this.shadowRoot.querySelector("#sendDogeDialog").show(); - } - - openSendDgb() { - this.shadowRoot.querySelector("#sendDgbDialog").show(); - } - - openSendRvn() { - this.shadowRoot.querySelector("#sendRvnDialog").show(); - } - - openSendArrr() { - this.shadowRoot.querySelector("#sendArrrDialog").show(); - } - - changeTheme() { - const checkTheme = localStorage.getItem('qortalTheme') - if (checkTheme === 'dark') { - this.theme = 'dark'; - } else { - this.theme = 'light'; - } - document.querySelector('html').setAttribute('theme', this.theme); - } - - changeLanguage() { - const checkLanguage = localStorage.getItem('qortalLanguage') - - if (checkLanguage === null || checkLanguage.length === 0) { - localStorage.setItem('qortalLanguage', 'us') - use('us') - } else { - use(checkLanguage) - } - } - - getSelectedWalletAddress() { - switch (this._selectedWallet) { - case "arrr": - // Use address returned by core API - return this.arrrWalletAddress - - default: - // Use locally derived address - return this.wallets.get(this._selectedWallet).wallet.address - } - } - - getSelectedWalletServer() { - switch (this._selectedWallet) { - case "qort": - return this.nodeDomain - - case "btc": - return this.btcServer - - case "ltc": - return this.ltcServer - - case "doge": - return this.dogeServer - - case "dgb": - return this.dgbServer - - case "rvn": - return this.rvnServer - - case "arrr": - return this.arrrServer - - default: - return - } - } - - async fetchWalletServer(coin) { - if (coin == 'qort') { - return - } - let walletServer = '' - try { - const serverInfo = await parentEpml.request('apiCall', { - type: 'api', - /* TODO */ - url: `/crosschain/${coin}/serverinfos`, - // TODO when 'current' parameter is added to 'serverinfos' API call, change above line to: - // url: `/crosschain/${coin}/serverinfos?current=true`, - }) - /* TODO */ - let currentServerFound = false - for (const server of serverInfo.servers) { - if (server.isCurrent === true) { - walletServer = `${server.hostName}:${server.port}` - currentServerFound = true - break - } - } - if (!currentServerFound) { - walletServer = 'Not Connected' - } - // TODO when 'current' parameter is added to 'serverinfos' API call, change above 'let,for,if' sections to: - /*if (serverInfo.servers[0]) { - const currentServerInfo = `${serverInfo.servers[0].hostName}:${serverInfo.servers[0].port}` - walletServer = currentServerInfo - } else { - walletServer = 'Not Connected' - }*/ - } catch (error) { - console.error('Failed to fetch server info:', error) - walletServer = `Error fetching server: ${error}` - } - switch (coin) { - case "btc": - this.btcServer = walletServer - break - case "ltc": - this.ltcServer = walletServer - break - case "doge": - this.dogeServer = walletServer - break - case "dgb": - this.dgbServer = walletServer - break - case "rvn": - this.rvnServer = walletServer - break - case "arrr": - this.arrrServer = walletServer - break - default: - break - } - } - - getNodeConfig() { - this.nodeDomain = "" - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - this.nodeDomain = myNode.domain + ":" + myNode.port - - this.nodeConfig = {} - parentEpml.request("getNodeConfig").then((res) => { - this.nodeConfig = res - }) - } - - async getTransactionGrid(coin) { - this.transactionsGrid = this.shadowRoot.querySelector(`#${coin}TransactionsGrid`) - if (coin === 'qort') { - this.transactionsGrid.addEventListener( - 'click', - (e) => { - let qortItem = this.transactionsGrid.getEventContext(e).item - this.showQortTransactionDetails(qortItem, this.wallets.get(this._selectedWallet).transactions) - }, - { passive: true } - ) - } else if (coin === 'btc') { - this.transactionsGrid.addEventListener( - 'click', - (e) => { - let btcItem = this.transactionsGrid.getEventContext(e).item - this.showBtcTransactionDetails(btcItem, this.wallets.get(this._selectedWallet).transactions) - }, - { passive: true } - ) - } else if (coin === 'ltc') { - this.transactionsGrid.addEventListener( - 'click', - (e) => { - let ltcItem = this.transactionsGrid.getEventContext(e).item - this.showLtcTransactionDetails(ltcItem, this.wallets.get(this._selectedWallet).transactions) - }, - { passive: true } - ) - } else if (coin === 'doge') { - this.transactionsGrid.addEventListener( - 'click', - (e) => { - let dogeItem = this.transactionsGrid.getEventContext(e).item - this.showDogeTransactionDetails(dogeItem, this.wallets.get(this._selectedWallet).transactions) - }, - { passive: true } - ) - } else if (coin === 'dgb') { - this.transactionsGrid.addEventListener( - 'click', - (e) => { - let dgbItem = this.transactionsGrid.getEventContext(e).item - this.showDgbTransactionDetails(dgbItem, this.wallets.get(this._selectedWallet).transactions) - }, - { passive: true } - ) - } else if (coin === 'rvn') { - this.transactionsGrid.addEventListener( - 'click', - (e) => { - let rvnItem = this.transactionsGrid.getEventContext(e).item - this.showRvnTransactionDetails(rvnItem, this.wallets.get(this._selectedWallet).transactions) - }, - { passive: true } - ) - } else if (coin === 'arrr') { - this.transactionsGrid.addEventListener( - 'click', - (e) => { - let arrrItem = this.transactionsGrid.getEventContext(e).item - this.showArrrTransactionDetails(arrrItem, this.wallets.get(this._selectedWallet).transactions) - }, - { passive: true } - ) - } - - this.pagesControl = this.shadowRoot.querySelector('#pages') - this.pages = undefined - } - - async renderTransactions() { - if (this._selectedWallet === 'qort') { - render(this.renderQortTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) - } else if (this._selectedWallet === 'btc') { - render(this.renderBtcTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) - } else if (this._selectedWallet === 'ltc') { - render(this.renderLtcTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) - } else if (this._selectedWallet === 'doge') { - render(this.renderDogeTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) - } else if (this._selectedWallet === 'dgb') { - render(this.renderDgbTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) - } else if (this._selectedWallet === 'rvn') { - render(this.renderRvnTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) - } else if (this._selectedWallet === 'arrr') { - render(this.renderArrrTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) - } - } - - renderQortTransactions(transactions, coin) { - const requiredConfirmations = 3 - const currentBlockHeight = window.parent.reduxStore.getState().app.blockInfo.height - if (Array.isArray(transactions)) { - transactions = transactions.map(tx => { - tx.confirmations = (currentBlockHeight - (tx.blockHeight - 1)) || '' - return tx - }) - } - - return html` -
    ${translate("walletpage.wchange38")}
    - - { - if (!currentBlockHeight) { - return render(html``, root) - } - const confirmed = data.item.confirmations >= requiredConfirmations - const unconfirmed = data.item.confirmations == 0 - if (confirmed) { - render(html`check`, root) - } else if (unconfirmed) { - render(html`schedule`, root) - } else { - render(html`schedule`, root) - } - }} - > - - { - render(html` ${data.item.type} ${data.item.creatorAddress === this.wallets.get('qort').wallet.address ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} `, root) - }} - > - - { - render(html`${data.item.type === 'AT' ? html`${data.item.atAddress}` : html`${data.item.creatorAddress}`}`, root) - }} - > - - { - render(html`${data.item.type === 'DEPLOY_AT' ? html`${data.item.aTAddress}` : html`${data.item.recipient}`}`, root) - }} - > - - - - { - const time = new Date(data.item.timestamp) - render(html` `, root) - }} - > - - -
    - ` - } - - renderBtcTransactions(transactions, coin) { - return html` -
    ${translate("walletpage.wchange38")}
    - - { - render(html`check`, root) - }} - > - - { - render(html` ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} `, root) - }} - > - - { - render(html`${data.item.inputs[0].address}`, root) - }} - > - - { - render(html`${data.item.outputs[0].address}`, root) - }} - > - - - { - const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) - render(html`${amount}`, root) - }} - > - - { - const time = new Date(data.item.timestamp) - render(html` `, root) - }} - > - - -
    - ` - } - - renderLtcTransactions(transactions, coin) { - return html` -
    ${translate("walletpage.wchange38")}
    - - { - render(html`check`, root) - }} - > - - { - render(html` ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} `, root) - }} - > - - { - render(html`${data.item.inputs[0].address}`, root) - }} - > - - { - render(html`${data.item.outputs[0].address}`, root) - }} - > - - - { - const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) - render(html`${amount}`, root) - }} - > - - { - const time = new Date(data.item.timestamp) - render(html` `, root) - }} - > - - -
    - ` - } - - renderDogeTransactions(transactions, coin) { - return html` -
    ${translate("walletpage.wchange38")}
    - - { - render(html`check`, root) - }} - > - - { - render(html` ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} `, root) - }} - > - - { - render(html`${data.item.inputs[0].address}`, root) - }} - > - - { - render(html`${data.item.outputs[0].address}`, root) - }} - > - - - { - const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) - render(html`${amount}`, root) - }} - > - - { - const time = new Date(data.item.timestamp) - render(html` `, root) - }} - > - - -
    - ` - } - - renderDgbTransactions(transactions, coin) { - return html` -
    ${translate("walletpage.wchange38")}
    - - { - render(html`check`, root) - }} - > - - { - render(html` ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} `, root) - }} - > - - { - render(html`${data.item.inputs[0].address}`, root) - }} - > - - { - render(html`${data.item.outputs[0].address}`, root) - }} - > - - - { - const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) - render(html`${amount}`, root) - }} - > - - { - const time = new Date(data.item.timestamp) - render(html` `, root) - }} - > - - -
    - ` - } - - renderRvnTransactions(transactions, coin) { - return html` -
    ${translate("walletpage.wchange38")}
    - - { - render(html`check`, root) - }} - > - - { - render(html` ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} `, root) - }} - > - - { - render(html`${data.item.inputs[0].address}`, root) - }} - > - - { - render(html`${data.item.outputs[0].address}`, root) - }} - > - - - { - const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) - render(html`${amount}`, root) - }} - > - - { - const time = new Date(data.item.timestamp) - render(html` `, root) - }} - > - - -
    - ` - } - - renderArrrTransactions(transactions, coin) { - return html` -
    ${translate("walletpage.wchange38")}
    - - { - render(html`check`, root) - }} - > - - { - render(html` ${translate("walletpage.wchange40")} ${data.item.totalAmount < 0 ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} `, root) - }} - > - - - - { - const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) - render(html`${amount}`, root) - }} - > - - { - const time = new Date(data.item.timestamp) - render(html` `, root) - }} - > - - { - render(html`${data.item.memo}`, root) - }} - > - - -
    - ` - } - - async updateItemsFromPage(page, changeWallet = false) { - if (page === undefined) { - return - } - - changeWallet === true ? (this.pagesControl.innerHTML = '') : null - - if (!this.pages) { - this.pages = Array.apply(null, { length: Math.ceil(this.wallets.get(this._selectedWallet).transactions.length / this.transactionsGrid.pageSize) }).map((item, index) => { - return index + 1 - }) - - const prevBtn = document.createElement('button') - prevBtn.textContent = '<' - prevBtn.addEventListener('click', () => { - const selectedPage = parseInt(this.pagesControl.querySelector('[selected]').textContent) - this.updateItemsFromPage(selectedPage - 1) - }) - this.pagesControl.appendChild(prevBtn) - - this.pages.forEach((pageNumber) => { - const pageBtn = document.createElement('button') - pageBtn.textContent = pageNumber - pageBtn.addEventListener('click', (e) => { - this.updateItemsFromPage(parseInt(e.target.textContent)) - }) - if (pageNumber === page) { - pageBtn.setAttribute('selected', true) - } - this.pagesControl.appendChild(pageBtn) - }) - - const nextBtn = window.document.createElement('button') - nextBtn.textContent = '>' - nextBtn.addEventListener('click', () => { - const selectedPage = parseInt(this.pagesControl.querySelector('[selected]').textContent) - this.updateItemsFromPage(selectedPage + 1) - }) - this.pagesControl.appendChild(nextBtn) - } - - const buttons = Array.from(this.pagesControl.children) - buttons.forEach((btn, index) => { - if (parseInt(btn.textContent) === page) { - btn.setAttribute('selected', true) - } else { - btn.removeAttribute('selected') - } - if (index === 0) { - if (page === 1) { - btn.setAttribute('disabled', '') - } else { - btn.removeAttribute('disabled') - } - } - if (index === buttons.length - 1) { - if (page === this.pages.length) { - btn.setAttribute('disabled', '') - } else { - btn.removeAttribute('disabled') - } - } - }) - let start = (page - 1) * this.transactionsGrid.pageSize - let end = page * this.transactionsGrid.pageSize - - this.transactionsGrid.items = this.wallets.get(this._selectedWallet).transactions.slice(start, end) - } - - getApiKey() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - return myNode.apiKey - } - - transactionItem(transactionObject) { - return ` -
    -
    -

    ${transactionObject.name}

    - ${transactionObject.category} ${transactionObject.ID} - ${transactionObject.date} -
    -
    -

    ${transactionObject.amount}

    -
    -
    - ` - } - - showQortTransactionDetails(myTransaction, allTransactions) { - allTransactions.forEach((transaction) => { - if (myTransaction.signature === transaction.signature) { - let txnFlow = myTransaction.creatorAddress === this.wallets.get('qort').wallet.address ? 'OUT' : 'IN' - this.selectedTransaction = { ...transaction, txnFlow } - if (this.selectedTransaction.signature.length != 0) { - this.shadowRoot.querySelector('#showTransactionDetailsDialog').show() - } - } - }) - } - - showBtcTransactionDetails(myTransaction, allTransactions) { - allTransactions.forEach((transaction) => { - if (myTransaction.txHash === transaction.txHash) { - let btcTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' - let btcSender = myTransaction.inputs[0].address - let btcReceiver = myTransaction.outputs[0].address - this.selectedTransaction = { ...transaction, btcTxnFlow, btcSender, btcReceiver } - if (this.selectedTransaction.txHash.length != 0) { - this.shadowRoot.querySelector('#showBtcTransactionDetailsDialog').show() - } - } - }) - } - - showLtcTransactionDetails(myTransaction, allTransactions) { - allTransactions.forEach((transaction) => { - if (myTransaction.txHash === transaction.txHash) { - let ltcTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' - let ltcSender = myTransaction.inputs[0].address - let ltcReceiver = myTransaction.outputs[0].address - this.selectedTransaction = { ...transaction, ltcTxnFlow, ltcSender, ltcReceiver } - if (this.selectedTransaction.txHash.length != 0) { - this.shadowRoot.querySelector('#showLtcTransactionDetailsDialog').show() - } - } - }) - } - - showDogeTransactionDetails(myTransaction, allTransactions) { - allTransactions.forEach((transaction) => { - if (myTransaction.txHash === transaction.txHash) { - let dogeTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' - let dogeSender = myTransaction.inputs[0].address - let dogeReceiver = myTransaction.outputs[0].address - this.selectedTransaction = { ...transaction, dogeTxnFlow, dogeSender, dogeReceiver } - if (this.selectedTransaction.txHash.length != 0) { - this.shadowRoot.querySelector('#showDogeTransactionDetailsDialog').show() - } - } - }) - } - - showDgbTransactionDetails(myTransaction, allTransactions) { - allTransactions.forEach((transaction) => { - if (myTransaction.txHash === transaction.txHash) { - let dgbTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' - let dgbSender = myTransaction.inputs[0].address - let dgbReceiver = myTransaction.outputs[0].address - this.selectedTransaction = { ...transaction, dgbTxnFlow, dgbSender, dgbReceiver } - if (this.selectedTransaction.txHash.length != 0) { - this.shadowRoot.querySelector('#showDgbTransactionDetailsDialog').show() - } - } - }) - } - - showRvnTransactionDetails(myTransaction, allTransactions) { - allTransactions.forEach((transaction) => { - if (myTransaction.txHash === transaction.txHash) { - let rvnTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' - let rvnSender = myTransaction.inputs[0].address - let rvnReceiver = myTransaction.outputs[0].address - this.selectedTransaction = { ...transaction, rvnTxnFlow, rvnSender, rvnReceiver } - if (this.selectedTransaction.txHash.length != 0) { - this.shadowRoot.querySelector('#showRvnTransactionDetailsDialog').show() - } - } - }) - } - - showArrrTransactionDetails(myTransaction, allTransactions) { - allTransactions.forEach((transaction) => { - if (myTransaction.txHash === transaction.txHash) { - let arrrTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' - let arrrSender = myTransaction.inputs[0].address - let arrrReceiver = myTransaction.outputs[0].address - this.selectedTransaction = { ...transaction, arrrTxnFlow, arrrSender, arrrReceiver } - if (this.selectedTransaction.txHash.length != 0) { - this.shadowRoot.querySelector('#showArrrTransactionDetailsDialog').show() - } - } - }) - } - - async saveFileToDisk(blob, fileName) { - try { - const fileHandle = await self.showSaveFilePicker({ - suggestedName: fileName, - types: [{ - description: "File", - }] - }) - const writeFile = async (fileHandle, contents) => { - const writable = await fileHandle.createWritable() - await writable.write(contents) - await writable.close() - } - writeFile(fileHandle, blob).then(() => console.log("FILE SAVED")) - let snack4string = get("general.save") - parentEpml.request('showSnackBar', `${snack4string} ${fileName} ✅`) - } catch (error) { - if (error.name === 'AbortError') { - return - } - FileSaver.saveAs(blob, fileName) - } - } - - isEmptyArray(arr) { - if (!arr) { - return true - } - return arr.length === 0 - } - - floor(num) { - num = parseFloat(num) - return isNaN(num) ? 0 : this._format(Math.floor(num)) - } - - decimals(num) { - num = parseFloat(num) - return num % 1 > 0 ? (num + '').split('.')[1] : '0' - } - - round(number) { - return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) - } - - subtract(num1, num2) { - return num1 - num2 - } - - getConfirmations(height, lastBlockHeight) { - return lastBlockHeight - height + 1 - } - - _format(num) { - return num.toLocaleString() - } - - _unconfirmedClass(unconfirmed) { - return unconfirmed ? 'unconfirmed' : '' - } + } + + const manageResponse = (response) => { + if (response.length === 64) { + this.shadowRoot.getElementById('rvnAmountInput').value = 0 + this.shadowRoot.getElementById('rvnRecipient').value = '' + this.errorMessage = '' + this.rvnRecipient = '' + this.rvnAmount = 0 + this.successMessage = this.renderSuccessText() + this.sendMoneyLoading = false + this.btnDisable = false + } else if (response === false) { + this.errorMessage = this.renderFailText() + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } else { + this.errorMessage = response.message + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(response) + } + } + const res = await makeRequest() + manageResponse(res) + await this.showWallet() + } + + async sendArrr() { + const arrrAmount = this.shadowRoot.getElementById('arrrAmountInput').value + let arrrRecipient = this.shadowRoot.getElementById('arrrRecipient').value + let arrrMemo = this.shadowRoot.getElementById('arrrMemo').value + const seed58 = this.wallets.get(this._selectedWallet).wallet.seed58 + + this.sendMoneyLoading = true + this.btnDisable = true + + const makeRequest = async () => { + const opts = { + entropy58: seed58, + receivingAddress: arrrRecipient, + arrrAmount: arrrAmount, + memo: arrrMemo + } + return await parentEpml.request('sendArrr', opts) + } + + const manageResponse = (response) => { + if (response.length === 64) { + this.shadowRoot.getElementById('arrrAmountInput').value = 0 + this.shadowRoot.getElementById('arrrRecipient').value = '' + this.shadowRoot.getElementById('arrrMemo').value = '' + this.errorMessage = '' + this.arrrRecipient = '' + this.arrrMemo = '' + this.arrrAmount = 0 + this.successMessage = this.renderSuccessText() + this.sendMoneyLoading = false + this.btnDisable = false + } else if (response === false) { + this.errorMessage = this.renderFailText() + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } else { + this.errorMessage = response.message + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(response) + } + } + const res = await makeRequest() + manageResponse(res) + await this.showWallet() + } + + async showWallet() { + this.transactionsDOM.hidden = true + this.loading = true + + if (this._selectedWallet == 'qort') { + if (!window.parent.reduxStore.getState().app.blockInfo.height) { + await parentEpml.request('apiCall', { url: `/blocks/height`, type: 'api' }) + .then(height => parentEpml.request('updateBlockInfo', { height })) + } + } + const coin = this._selectedWallet + await this.fetchWalletAddress(this._selectedWallet) + await this.fetchWalletServer(this._selectedWallet) + await this.fetchWalletDetails(this._selectedWallet) + await this.fetchWalletServer(this._selectedWallet) + if (this._selectedWallet == coin) { + await this.renderTransactions() + await this.getTransactionGrid(this._selectedWallet) + await this.updateItemsFromPage(1, true) + this.loading = false + this.transactionsDOM.hidden = false + } + } + + async fetchWalletDetails(coin) { + switch (coin) { + case 'qort': + this.balanceString = this.renderFetchText() + parentEpml.request('apiCall', { + url: `/addresses/balance/${this.wallets.get('qort').wallet.address}?apiKey=${this.getApiKey()}` + }).then((res) => { + if (isNaN(Number(res))) { + let snack4string = get("walletpage.wchange32") + parentEpml.request('showSnackBar', `${snack4string}`) + } else { + if (this._selectedWallet == coin) { + this.wallets.get(coin).balance = Number(res).toFixed(8) + this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase() + this.balance = this.wallets.get(this._selectedWallet).balance + } + } + }) + const txsQort = await parentEpml.request('apiCall', { + url: `/transactions/search?address=${this.wallets.get('qort').wallet.address}&confirmationStatus=CONFIRMED&reverse=true&txType=PAYMENT&txType=REGISTER_NAME&txType=UPDATE_NAME&txType=SELL_NAME&txType=CANCEL_SELL_NAME&txType=BUY_NAME&txType=CREATE_POLL&txType=VOTE_ON_POLL&txType=ARBITRARY&txType=ISSUE_ASSET&txType=TRANSFER_ASSET&txType=CREATE_ASSET_ORDER&txType=CANCEL_ASSET_ORDER&txType=MULTI_PAYMENT&txType=DEPLOY_AT&txType=MESSAGE&txType=AIRDROP&txType=AT&txType=CREATE_GROUP&txType=UPDATE_GROUP&txType=ADD_GROUP_ADMIN&txType=REMOVE_GROUP_ADMIN&txType=GROUP_BAN&txType=CANCEL_GROUP_BAN&txType=GROUP_KICK&txType=GROUP_INVITE&txType=CANCEL_GROUP_INVITE&txType=JOIN_GROUP&txType=LEAVE_GROUP&txType=GROUP_APPROVAL&txType=SET_GROUP&txType=UPDATE_ASSET&txType=ACCOUNT_FLAGS&txType=ENABLE_FORGING&txType=REWARD_SHARE&txType=ACCOUNT_LEVEL&txType=TRANSFER_PRIVS&txType=PRESENCE`, + }) + const pendingTxsQort = await parentEpml.request('apiCall', { + url: `/transactions/unconfirmed?creator=${this.wallets.get('qort').wallet.base58PublicKey}&reverse=true&txType=PAYMENT&txType=REGISTER_NAME&txType=UPDATE_NAME&txType=SELL_NAME&txType=CANCEL_SELL_NAME&txType=BUY_NAME&txType=CREATE_POLL&txType=VOTE_ON_POLL&txType=ARBITRARY&txType=ISSUE_ASSET&txType=TRANSFER_ASSET&txType=CREATE_ASSET_ORDER&txType=CANCEL_ASSET_ORDER&txType=MULTI_PAYMENT&txType=DEPLOY_AT&txType=MESSAGE&txType=AIRDROP&txType=AT&txType=CREATE_GROUP&txType=UPDATE_GROUP&txType=ADD_GROUP_ADMIN&txType=REMOVE_GROUP_ADMIN&txType=GROUP_BAN&txType=CANCEL_GROUP_BAN&txType=GROUP_KICK&txType=GROUP_INVITE&txType=CANCEL_GROUP_INVITE&txType=JOIN_GROUP&txType=LEAVE_GROUP&txType=GROUP_APPROVAL&txType=SET_GROUP&txType=UPDATE_ASSET&txType=ACCOUNT_FLAGS&txType=ENABLE_FORGING&txType=REWARD_SHARE&txType=ACCOUNT_LEVEL&txType=TRANSFER_PRIVS&txType=PRESENCE`, + }) + if (this._selectedWallet == coin) { + this.wallets.get(coin).transactions = pendingTxsQort.concat(txsQort) + } + break + case 'btc': + case 'ltc': + case 'doge': + case 'dgb': + case 'rvn': + this.balanceString = this.renderFetchText() + const walletName = `${coin}Wallet` + parentEpml.request('apiCall', { + url: `/crosschain/${coin}/walletbalance?apiKey=${this.getApiKey()}`, + method: 'POST', + body: `${window.parent.reduxStore.getState().app.selectedAddress[walletName].derivedMasterPublicKey}` + }).then((res) => { + if (isNaN(Number(res))) { + let snack5string = get("walletpage.wchange33") + let snack6string = get("walletpage.wchange34") + parentEpml.request('showSnackBar', `${snack5string} ${coin.toLocaleUpperCase()} ${snack6string}!`) + } else { + if (this._selectedWallet == coin) { + this.wallets.get(this._selectedWallet).balance = (Number(res) / 1e8).toFixed(8) + this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase() + this.balance = this.wallets.get(this._selectedWallet).balance + } + } + }) + + const txs = await parentEpml.request('apiCall', { + url: `/crosschain/${coin}/wallettransactions?apiKey=${this.getApiKey()}`, + method: 'POST', + body: `${window.parent.reduxStore.getState().app.selectedAddress[walletName].derivedMasterPublicKey}`, + }) + + const compareFn = (a, b) => { + return b.timestamp - a.timestamp + } + + const sortedTransactions = txs.sort(compareFn) + if (this._selectedWallet == coin) { + this.wallets.get(this._selectedWallet).transactions = sortedTransactions + } + break + case 'arrr': + const arrrWalletName = `${coin}Wallet` + + const res = await parentEpml.request('apiCall', { + url: `/crosschain/${coin}/syncstatus?apiKey=${this.getApiKey()}`, + method: 'POST', + body: `${window.parent.reduxStore.getState().app.selectedAddress[arrrWalletName].seed58}` + }) + + if (coin != this._selectedWallet) { + // We've switched away from this coin + } + + if (res.indexOf('<') > -1) { + this.balanceString = this.renderFetchText() + await new Promise(resolve => setTimeout(resolve, 2000)) + await this.showWallet() + return + } else if (res !== "Synchronized") { + this.balanceString = res + await new Promise(resolve => setTimeout(resolve, 2000)) + await this.showWallet() + return + } + + this.balanceString = this.renderFetchText() + + parentEpml.request('apiCall', { + url: `/crosschain/${coin}/walletbalance?apiKey=${this.getApiKey()}`, + method: 'POST', + body: `${window.parent.reduxStore.getState().app.selectedAddress[arrrWalletName].seed58}`, + }).then((res) => { + if (isNaN(Number(res))) { + let snack5string = get("walletpage.wchange33") + let snack6string = get("walletpage.wchange34") + parentEpml.request('showSnackBar', `${snack5string} ${coin.toLocaleUpperCase()} ${snack6string}!`) + } else { + if (this._selectedWallet == coin) { + this.wallets.get(this._selectedWallet).balance = (Number(res) / 1e8).toFixed(8) + this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase() + this.balance = this.wallets.get(this._selectedWallet).balance + } + } + }) + + const arrrTxs = await parentEpml.request('apiCall', { + url: `/crosschain/${coin}/wallettransactions?apiKey=${this.getApiKey()}`, + method: 'POST', + body: `${window.parent.reduxStore.getState().app.selectedAddress[arrrWalletName].seed58}`, + }) + + const arrrCompareFn = (a, b) => { + return b.timestamp - a.timestamp + } + + const arrrSortedTransactions = arrrTxs.sort(arrrCompareFn) + + if (this._selectedWallet == coin) { + this.wallets.get(this._selectedWallet).transactions = arrrSortedTransactions + } + break + default: + break + } + } + + async fetchWalletAddress(coin) { + switch (coin) { + case 'arrr': + const arrrWalletName = `${coin}Wallet` + let res = await parentEpml.request('apiCall', { + url: `/crosschain/${coin}/walletaddress?apiKey=${this.getApiKey()}`, + method: 'POST', + body: `${window.parent.reduxStore.getState().app.selectedAddress[arrrWalletName].seed58}`, + }) + if (res != null && res.error != 1201 && res.length === 78) { + this.arrrWalletAddress = res + } + break + + default: + // Not used for other coins yet + break + } + } + + renderSendButton() { + if (this._selectedWallet === "qort") { + return html` this.openSendQort()}> ${translate("walletpage.wchange17")} QORT` + } else if (this._selectedWallet === "btc") { + return html` this.openSendBtc()}> ${translate("walletpage.wchange17")} BTC` + } else if (this._selectedWallet === "ltc") { + return html` this.openSendLtc()}> ${translate("walletpage.wchange17")} LTC` + } else if (this._selectedWallet === "doge") { + return html` this.openSendDoge()}> ${translate("walletpage.wchange17")} DOGE` + } else if (this._selectedWallet === "dgb") { + return html` this.openSendDgb()}> ${translate("walletpage.wchange17")} DGB` + } else if (this._selectedWallet === "rvn") { + return html` this.openSendRvn()}> ${translate("walletpage.wchange17")} RVN` + } else if (this._selectedWallet === "arrr") { + return html` this.openSendArrr()}> ${translate("walletpage.wchange17")} ARRR` + } else { + return html`` + } + } + + renderAddressbookButton() { + if (this._selectedWallet === "qort") { + return html` this.openQortAddressbook()}> ${translate("walletpage.wchange47")}` + } else if (this._selectedWallet === "btc") { + return html` this.openBtcAddressbook()}> ${translate("walletpage.wchange47")}` + } else if (this._selectedWallet === "ltc") { + return html` this.openLtcAddressbook()}> ${translate("walletpage.wchange47")}` + } else if (this._selectedWallet === "doge") { + return html` this.openDogeAddressbook()}> ${translate("walletpage.wchange47")}` + } else if (this._selectedWallet === "dgb") { + return html` this.openDgbAddressbook()}> ${translate("walletpage.wchange47")}` + } else if (this._selectedWallet === "rvn") { + return html` this.openRvnAddressbook()}> ${translate("walletpage.wchange47")}` + } else if (this._selectedWallet === "arrr") { + return html` this.openArrrAddressbook()}> ${translate("walletpage.wchange47")}` + } else { + return html`` + } + } + + renderExportAddressbookButton() { + if (this._selectedWallet === "qort") { + return html` this.exportQortAddressbook()}> ${translate("walletpage.wchange54")}` + } else if (this._selectedWallet === "btc") { + return html` this.exportBtcAddressbook()}> ${translate("walletpage.wchange54")}` + } else if (this._selectedWallet === "ltc") { + return html` this.exportLtcAddressbook()}> ${translate("walletpage.wchange54")}` + } else if (this._selectedWallet === "doge") { + return html` this.exportDogeAddressbook()}> ${translate("walletpage.wchange54")}` + } else if (this._selectedWallet === "dgb") { + return html` this.exportDgbAddressbook()}> ${translate("walletpage.wchange54")}` + } else if (this._selectedWallet === "rvn") { + return html` this.exportRvnAddressbook()}> ${translate("walletpage.wchange54")}` + } else if (this._selectedWallet === "arrr") { + return html` this.exportArrrAddressbook()}> ${translate("walletpage.wchange54")}` + } else { + return html`` + } + } + + renderImportAddressbookButton() { + if (this._selectedWallet === "qort") { + return html` this.openImportQortAddressbook()}> ${translate("walletpage.wchange53")}` + } else if (this._selectedWallet === "btc") { + return html` this.openImportBtcAddressbook()}> ${translate("walletpage.wchange53")}` + } else if (this._selectedWallet === "ltc") { + return html` this.openImportLtcAddressbook()}> ${translate("walletpage.wchange53")}` + } else if (this._selectedWallet === "doge") { + return html` this.openImportDogeAddressbook()}> ${translate("walletpage.wchange53")}` + } else if (this._selectedWallet === "dgb") { + return html` this.openImportDgbAddressbook()}> ${translate("walletpage.wchange53")}` + } else if (this._selectedWallet === "rvn") { + return html` this.openImportRvnAddressbook()}> ${translate("walletpage.wchange53")}` + } else if (this._selectedWallet === "arrr") { + return html` this.openImportArrrAddressbook()}> ${translate("walletpage.wchange53")}` + } else { + return html`` + } + } + + openSendQort() { + this.shadowRoot.querySelector("#sendQortDialog").show(); + } + + openSendBtc() { + this.shadowRoot.querySelector("#sendBtcDialog").show(); + } + + openSendLtc() { + this.shadowRoot.querySelector("#sendLtcDialog").show(); + } + + openSendDoge() { + this.shadowRoot.querySelector("#sendDogeDialog").show(); + } + + openSendDgb() { + this.shadowRoot.querySelector("#sendDgbDialog").show(); + } + + openSendRvn() { + this.shadowRoot.querySelector("#sendRvnDialog").show(); + } + + openSendArrr() { + this.shadowRoot.querySelector("#sendArrrDialog").show(); + } + + changeTheme() { + const checkTheme = localStorage.getItem('qortalTheme') + if (checkTheme === 'dark') { + this.theme = 'dark'; + } else { + this.theme = 'light'; + } + document.querySelector('html').setAttribute('theme', this.theme); + } + + changeLanguage() { + const checkLanguage = localStorage.getItem('qortalLanguage') + + if (checkLanguage === null || checkLanguage.length === 0) { + localStorage.setItem('qortalLanguage', 'us') + use('us') + } else { + use(checkLanguage) + } + } + + getSelectedWalletAddress() { + switch (this._selectedWallet) { + case "arrr": + // Use address returned by core API + return this.arrrWalletAddress + + default: + // Use locally derived address + return this.wallets.get(this._selectedWallet).wallet.address + } + } + + getSelectedWalletServer() { + switch (this._selectedWallet) { + case "qort": + return this.nodeDomain + case "btc": + return this.btcServer + case "ltc": + return this.ltcServer + case "doge": + return this.dogeServer + case "dgb": + return this.dgbServer + case "rvn": + return this.rvnServer + case "arrr": + return this.arrrServer + default: + return + } + } + + async fetchWalletServer(coin) { + if (coin == 'qort') { + return + } + let walletServer = '' + try { + const serverInfo = await parentEpml.request('apiCall', { + type: 'api', + /* TODO */ + url: `/crosschain/${coin}/serverinfos`, + // TODO when 'current' parameter is added to 'serverinfos' API call, change above line to: + // url: `/crosschain/${coin}/serverinfos?current=true`, + }) + /* TODO */ + let currentServerFound = false + for (const server of serverInfo.servers) { + if (server.isCurrent === true) { + walletServer = `${server.hostName}:${server.port}` + currentServerFound = true + break + } + } + if (!currentServerFound) { + walletServer = 'Not Connected' + } + // TODO when 'current' parameter is added to 'serverinfos' API call, change above 'let,for,if' sections to: + /*if (serverInfo.servers[0]) { + const currentServerInfo = `${serverInfo.servers[0].hostName}:${serverInfo.servers[0].port}` + walletServer = currentServerInfo + } else { + walletServer = 'Not Connected' + }*/ + } catch (error) { + console.error('Failed to fetch server info:', error) + walletServer = `Error fetching server: ${error}` + } + switch (coin) { + case "btc": + this.btcServer = walletServer + break + case "ltc": + this.ltcServer = walletServer + break + case "doge": + this.dogeServer = walletServer + break + case "dgb": + this.dgbServer = walletServer + break + case "rvn": + this.rvnServer = walletServer + break + case "arrr": + this.arrrServer = walletServer + break + default: + break + } + } + + getNodeConfig() { + this.nodeDomain = "" + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + this.nodeDomain = myNode.domain + ":" + myNode.port + this.nodeConfig = {} + parentEpml.request("getNodeConfig").then((res) => { + this.nodeConfig = res + }) + } + + async getTransactionGrid(coin) { + this.transactionsGrid = this.shadowRoot.querySelector(`#${coin}TransactionsGrid`) + if (coin === 'qort') { + this.transactionsGrid.addEventListener( + 'click', + (e) => { + let qortItem = this.transactionsGrid.getEventContext(e).item + this.showQortTransactionDetails(qortItem, this.wallets.get(this._selectedWallet).transactions) + }, + { passive: true } + ) + } else if (coin === 'btc') { + this.transactionsGrid.addEventListener( + 'click', + (e) => { + let btcItem = this.transactionsGrid.getEventContext(e).item + this.showBtcTransactionDetails(btcItem, this.wallets.get(this._selectedWallet).transactions) + }, + { passive: true } + ) + } else if (coin === 'ltc') { + this.transactionsGrid.addEventListener( + 'click', + (e) => { + let ltcItem = this.transactionsGrid.getEventContext(e).item + this.showLtcTransactionDetails(ltcItem, this.wallets.get(this._selectedWallet).transactions) + }, + { passive: true } + ) + } else if (coin === 'doge') { + this.transactionsGrid.addEventListener( + 'click', + (e) => { + let dogeItem = this.transactionsGrid.getEventContext(e).item + this.showDogeTransactionDetails(dogeItem, this.wallets.get(this._selectedWallet).transactions) + }, + { passive: true } + ) + } else if (coin === 'dgb') { + this.transactionsGrid.addEventListener( + 'click', + (e) => { + let dgbItem = this.transactionsGrid.getEventContext(e).item + this.showDgbTransactionDetails(dgbItem, this.wallets.get(this._selectedWallet).transactions) + }, + { passive: true } + ) + } else if (coin === 'rvn') { + this.transactionsGrid.addEventListener( + 'click', + (e) => { + let rvnItem = this.transactionsGrid.getEventContext(e).item + this.showRvnTransactionDetails(rvnItem, this.wallets.get(this._selectedWallet).transactions) + }, + { passive: true } + ) + } else if (coin === 'arrr') { + this.transactionsGrid.addEventListener( + 'click', + (e) => { + let arrrItem = this.transactionsGrid.getEventContext(e).item + this.showArrrTransactionDetails(arrrItem, this.wallets.get(this._selectedWallet).transactions) + }, + { passive: true } + ) + } + + this.pagesControl = this.shadowRoot.querySelector('#pages') + this.pages = undefined + } + + async renderTransactions() { + if (this._selectedWallet === 'qort') { + render(this.renderQortTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) + } else if (this._selectedWallet === 'btc') { + render(this.renderBtcTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) + } else if (this._selectedWallet === 'ltc') { + render(this.renderLtcTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) + } else if (this._selectedWallet === 'doge') { + render(this.renderDogeTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) + } else if (this._selectedWallet === 'dgb') { + render(this.renderDgbTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) + } else if (this._selectedWallet === 'rvn') { + render(this.renderRvnTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) + } else if (this._selectedWallet === 'arrr') { + render(this.renderArrrTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) + } + } + + renderQortTransactions(transactions, coin) { + const requiredConfirmations = 3 + const currentBlockHeight = window.parent.reduxStore.getState().app.blockInfo.height + if (Array.isArray(transactions)) { + transactions = transactions.map(tx => { + tx.confirmations = (currentBlockHeight - (tx.blockHeight - 1)) || '' + return tx + }) + } + return html` +
    ${translate("walletpage.wchange38")}
    + + { + if (!currentBlockHeight) { + return render(html``, root) + } + const confirmed = data.item.confirmations >= requiredConfirmations + const unconfirmed = data.item.confirmations == 0 + if (confirmed) { + render(html`check`, root) + } else if (unconfirmed) { + render(html`schedule`, root) + } else { + render(html`schedule`, root) + } + }} + > + + { + render(html` + ${data.item.type} ${data.item.creatorAddress === this.wallets.get('qort').wallet.address ? + html` + ${translate("walletpage.wchange7")} + ` : html` + ${translate("walletpage.wchange8")} + ` + } + `, root) + }} + > + + { + render(html`${data.item.type === 'AT' ? html`${data.item.atAddress}` : html`${data.item.creatorAddress}`}`, root) + }} + > + + { + render(html`${data.item.type === 'DEPLOY_AT' ? html`${data.item.aTAddress}` : html`${data.item.recipient}`}`, root) + }} + > + + + + { + const time = new Date(data.item.timestamp) + render(html` + + `, root) + }} + > + + +
    + ` + } + + renderBtcTransactions(transactions, coin) { + return html` +
    ${translate("walletpage.wchange38")}
    + + { + render(html` + check + `, root) + }} + > + + { + render(html` + ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? + html` + ${translate("walletpage.wchange7")} + ` : html` + ${translate("walletpage.wchange8")} + ` + } + `, root) + }} + > + + { + render(html`${data.item.inputs[0].address}`, root) + }} + > + + { + render(html`${data.item.outputs[0].address}`, root) + }} + > + + + { + const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) + render(html`${amount}`, root) + }} + > + + { + const time = new Date(data.item.timestamp) + render(html` + + `, root) + }} + > + + +
    + ` + } + + renderLtcTransactions(transactions, coin) { + return html` +
    ${translate("walletpage.wchange38")}
    + + { + render(html` + check + `, root) + }} + > + + { + render(html` + ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? + html` + ${translate("walletpage.wchange7")} + ` : html` + ${translate("walletpage.wchange8")} + ` + } + `, root) + }} + > + + { + render(html`${data.item.inputs[0].address}`, root) + }} + > + + { + render(html`${data.item.outputs[0].address}`, root) + }} + > + + + { + const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) + render(html`${amount}`, root) + }} + > + + { + const time = new Date(data.item.timestamp) + render(html` + + `, root) + }} + > + + +
    + ` + } + + renderDogeTransactions(transactions, coin) { + return html` +
    +
    ${translate("walletpage.wchange38")}
    + + { + render(html` + check + `, root) + }} + > + + { + render(html` + ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? + html` + ${translate("walletpage.wchange7")} + ` : html` + ${translate("walletpage.wchange8")} + ` + } + `, root) + }} + > + + { + render(html`${data.item.inputs[0].address}`, root) + }} + > + + { + render(html`${data.item.outputs[0].address}`, root) + }} + > + + + { + const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) + render(html`${amount}`, root) + }} + > + + { + const time = new Date(data.item.timestamp) + render(html` + + `, root) + }} + > + + +
    + ` + } + + renderDgbTransactions(transactions, coin) { + return html` +
    ${translate("walletpage.wchange38")}
    + + { + render(html` + check + `, root) + }} + > + + { + render(html` + ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? + html` + ${translate("walletpage.wchange7")} + ` : html` + ${translate("walletpage.wchange8")} + ` + } + `, root) + }} + > + + { + render(html`${data.item.inputs[0].address}`, root) + }} + > + + { + render(html`${data.item.outputs[0].address}`, root) + }} + > + + + { + const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) + render(html`${amount}`, root) + }} + > + + { + const time = new Date(data.item.timestamp) + render(html` + + `, root) + }} + > + + +
    + ` + } + + renderRvnTransactions(transactions, coin) { + return html` +
    ${translate("walletpage.wchange38")}
    + + { + render(html` + check + `, root) + }} + > + + { + render(html` + ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? + html` + ${translate("walletpage.wchange7")} + ` : html` + ${translate("walletpage.wchange8")} + ` + } + `, root) + }} + > + + { + render(html`${data.item.inputs[0].address}`, root) + }} + > + + { + render(html`${data.item.outputs[0].address}`, root) + }} + > + + + { + const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) + render(html`${amount}`, root) + }} + > + + { + const time = new Date(data.item.timestamp) + render(html` + + `, root) + }} + > + + +
    + ` + } + + renderArrrTransactions(transactions, coin) { + return html` +
    ${translate("walletpage.wchange38")}
    + + { + render(html` + check + `, root) + }} + > + + { + render(html` + ${translate("walletpage.wchange40")} ${data.item.totalAmount < 0 ? + html` + ${translate("walletpage.wchange7")} + ` : html` + ${translate("walletpage.wchange8")} + ` + } + `, root) + }} + > + + + { + const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) + render(html`${amount}`, root) + }} + > + + { + const time = new Date(data.item.timestamp) + render(html` + + `, root) + }} + > + + { + render(html`${data.item.memo}`, root) + }} + > + + +
    + ` + } + + async updateItemsFromPage(page, changeWallet = false) { + if (page === undefined) { + return + } + + changeWallet === true ? (this.pagesControl.innerHTML = '') : null + + if (!this.pages) { + this.pages = Array.apply(null, { length: Math.ceil(this.wallets.get(this._selectedWallet).transactions.length / this.transactionsGrid.pageSize) }).map((item, index) => { + return index + 1 + }) + + const prevBtn = document.createElement('button') + prevBtn.textContent = '<' + prevBtn.addEventListener('click', () => { + const selectedPage = parseInt(this.pagesControl.querySelector('[selected]').textContent) + this.updateItemsFromPage(selectedPage - 1) + }) + this.pagesControl.appendChild(prevBtn) + + this.pages.forEach((pageNumber) => { + const pageBtn = document.createElement('button') + pageBtn.textContent = pageNumber + pageBtn.addEventListener('click', (e) => { + this.updateItemsFromPage(parseInt(e.target.textContent)) + }) + if (pageNumber === page) { + pageBtn.setAttribute('selected', true) + } + this.pagesControl.appendChild(pageBtn) + }) + + const nextBtn = window.document.createElement('button') + nextBtn.textContent = '>' + nextBtn.addEventListener('click', () => { + const selectedPage = parseInt(this.pagesControl.querySelector('[selected]').textContent) + this.updateItemsFromPage(selectedPage + 1) + }) + this.pagesControl.appendChild(nextBtn) + } + + const buttons = Array.from(this.pagesControl.children) + buttons.forEach((btn, index) => { + if (parseInt(btn.textContent) === page) { + btn.setAttribute('selected', true) + } else { + btn.removeAttribute('selected') + } + if (index === 0) { + if (page === 1) { + btn.setAttribute('disabled', '') + } else { + btn.removeAttribute('disabled') + } + } + if (index === buttons.length - 1) { + if (page === this.pages.length) { + btn.setAttribute('disabled', '') + } else { + btn.removeAttribute('disabled') + } + } + }) + let start = (page - 1) * this.transactionsGrid.pageSize + let end = page * this.transactionsGrid.pageSize + + this.transactionsGrid.items = this.wallets.get(this._selectedWallet).transactions.slice(start, end) + } + + transactionItem(transactionObject) { + return ` +
    +
    +

    ${transactionObject.name}

    + ${transactionObject.category} ${transactionObject.ID} - ${transactionObject.date} +
    +
    +

    ${transactionObject.amount}

    +
    +
    + ` + } + + showQortTransactionDetails(myTransaction, allTransactions) { + allTransactions.forEach((transaction) => { + if (myTransaction.signature === transaction.signature) { + let txnFlow = myTransaction.creatorAddress === this.wallets.get('qort').wallet.address ? 'OUT' : 'IN' + this.selectedTransaction = { ...transaction, txnFlow } + if (this.selectedTransaction.signature.length != 0) { + this.shadowRoot.querySelector('#showTransactionDetailsDialog').show() + } + } + }) + } + + showBtcTransactionDetails(myTransaction, allTransactions) { + allTransactions.forEach((transaction) => { + if (myTransaction.txHash === transaction.txHash) { + let btcTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' + let btcSender = myTransaction.inputs[0].address + let btcReceiver = myTransaction.outputs[0].address + this.selectedTransaction = { ...transaction, btcTxnFlow, btcSender, btcReceiver } + if (this.selectedTransaction.txHash.length != 0) { + this.shadowRoot.querySelector('#showBtcTransactionDetailsDialog').show() + } + } + }) + } + + showLtcTransactionDetails(myTransaction, allTransactions) { + allTransactions.forEach((transaction) => { + if (myTransaction.txHash === transaction.txHash) { + let ltcTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' + let ltcSender = myTransaction.inputs[0].address + let ltcReceiver = myTransaction.outputs[0].address + this.selectedTransaction = { ...transaction, ltcTxnFlow, ltcSender, ltcReceiver } + if (this.selectedTransaction.txHash.length != 0) { + this.shadowRoot.querySelector('#showLtcTransactionDetailsDialog').show() + } + } + }) + } + + showDogeTransactionDetails(myTransaction, allTransactions) { + allTransactions.forEach((transaction) => { + if (myTransaction.txHash === transaction.txHash) { + let dogeTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' + let dogeSender = myTransaction.inputs[0].address + let dogeReceiver = myTransaction.outputs[0].address + this.selectedTransaction = { ...transaction, dogeTxnFlow, dogeSender, dogeReceiver } + if (this.selectedTransaction.txHash.length != 0) { + this.shadowRoot.querySelector('#showDogeTransactionDetailsDialog').show() + } + } + }) + } + + showDgbTransactionDetails(myTransaction, allTransactions) { + allTransactions.forEach((transaction) => { + if (myTransaction.txHash === transaction.txHash) { + let dgbTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' + let dgbSender = myTransaction.inputs[0].address + let dgbReceiver = myTransaction.outputs[0].address + this.selectedTransaction = { ...transaction, dgbTxnFlow, dgbSender, dgbReceiver } + if (this.selectedTransaction.txHash.length != 0) { + this.shadowRoot.querySelector('#showDgbTransactionDetailsDialog').show() + } + } + }) + } + + showRvnTransactionDetails(myTransaction, allTransactions) { + allTransactions.forEach((transaction) => { + if (myTransaction.txHash === transaction.txHash) { + let rvnTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' + let rvnSender = myTransaction.inputs[0].address + let rvnReceiver = myTransaction.outputs[0].address + this.selectedTransaction = { ...transaction, rvnTxnFlow, rvnSender, rvnReceiver } + if (this.selectedTransaction.txHash.length != 0) { + this.shadowRoot.querySelector('#showRvnTransactionDetailsDialog').show() + } + } + }) + } + + showArrrTransactionDetails(myTransaction, allTransactions) { + allTransactions.forEach((transaction) => { + if (myTransaction.txHash === transaction.txHash) { + let arrrTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' + let arrrSender = myTransaction.inputs[0].address + let arrrReceiver = myTransaction.outputs[0].address + this.selectedTransaction = { ...transaction, arrrTxnFlow, arrrSender, arrrReceiver } + if (this.selectedTransaction.txHash.length != 0) { + this.shadowRoot.querySelector('#showArrrTransactionDetailsDialog').show() + } + } + }) + } + + async saveFileToDisk(blob, fileName) { + try { + const fileHandle = await self.showSaveFilePicker({ + suggestedName: fileName, + types: [{ + description: "File" + }] + }) + const writeFile = async (fileHandle, contents) => { + const writable = await fileHandle.createWritable() + await writable.write(contents) + await writable.close() + } + writeFile(fileHandle, blob).then(() => console.log("FILE SAVED")) + let snack4string = get("general.save") + parentEpml.request('showSnackBar', `${snack4string} ${fileName} ✅`) + } catch (error) { + if (error.name === 'AbortError') { + return + } + FileSaver.saveAs(blob, fileName) + } + } + + getConfirmations(height, lastBlockHeight) { + return lastBlockHeight - height + 1 + } + + _unconfirmedClass(unconfirmed) { + return unconfirmed ? 'unconfirmed' : '' + } + + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } + + floor(num) { + num = parseFloat(num) + return isNaN(num) ? 0 : this.format(Math.floor(num)) + } + + decimals(num) { + num = parseFloat(num) + return num % 1 > 0 ? (num + '').split('.')[1] : '0' + } + + subtract(num1, num2) { + return num1 - num2 + } + + format(num) { + return num.toLocaleString() + } } window.customElements.define('multi-wallet', MultiWallet) \ No newline at end of file diff --git a/plugins/plugins/utils/blocks-needed.js b/plugins/plugins/utils/blocks-needed.js deleted file mode 100644 index ee5dc6ce..00000000 --- a/plugins/plugins/utils/blocks-needed.js +++ /dev/null @@ -1,23 +0,0 @@ -export const blocksNeed = (level) => { - if (level === 0) { - return '7200'; - } else if (level === 1) { - return '72000'; - } else if (level === 2) { - return '201600'; - } else if (level === 3) { - return '374400'; - } else if (level === 4) { - return '618400'; - } else if (level === 5) { - return '964000'; - } else if (level === 6) { - return '1482400'; - } else if (level === 7) { - return '2173600'; - } else if (level === 8) { - return '3037600'; - } else if (level === 9) { - return '4074400'; - } -}; \ No newline at end of file diff --git a/plugins/plugins/utils/bytesToMegabytes.js b/plugins/plugins/utils/bytesToMegabytes.js deleted file mode 100644 index 9b271e4f..00000000 --- a/plugins/plugins/utils/bytesToMegabytes.js +++ /dev/null @@ -1,3 +0,0 @@ -export function bytesToMegabytes(bytes) { - return bytes / (1024 * 1024); -} \ No newline at end of file diff --git a/plugins/plugins/utils/classes.js b/plugins/plugins/utils/classes.js new file mode 100644 index 00000000..c16b4bcf --- /dev/null +++ b/plugins/plugins/utils/classes.js @@ -0,0 +1,926 @@ +import { get } from '../../../core/translate' + +const getApiKey = () => { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey +} + +export class RequestQueue { + constructor(maxConcurrent = 5) { + this.queue = [] + this.maxConcurrent = maxConcurrent + this.currentConcurrent = 0 + } + + push(request) { + return new Promise((resolve, reject) => { + this.queue.push({ request, resolve, reject }) + this.checkQueue() + }) + } + + checkQueue() { + if (this.queue.length === 0 || this.currentConcurrent >= this.maxConcurrent) { + return + } + + const { request, resolve, reject } = this.queue.shift() + + this.currentConcurrent++ + + request().then(resolve).catch(reject).finally(() => { + this.currentConcurrent-- + this.checkQueue() + }) + } +} + +export class RequestQueueWithPromise { + constructor(maxConcurrent = 5) { + this.queue = [] + this.maxConcurrent = maxConcurrent + this.currentlyProcessing = 0 + } + + // Add a request to the queue and return a promise + enqueue(request) { + return new Promise((resolve, reject) => { + // Push the request and its resolve and reject callbacks to the queue + this.queue.push({ request, resolve, reject }) + this.process() + }) + } + + // Process requests in the queue + async process() { + while (this.queue.length > 0 && this.currentlyProcessing < this.maxConcurrent) { + this.currentlyProcessing++ + + const { request, resolve, reject } = this.queue.shift() + + try { + const response = await request() + resolve(response) + } catch (error) { + reject(error) + } finally { + this.currentlyProcessing-- + await this.process() + } + } + } +} + +export class Loader { + constructor() { + this.loader = document.createElement("div") + this.loader.className = "loader" + this.loader.innerHTML = `
    ` + this.styles = document.createElement("style") + this.styles.innerHTML = ` + .loader { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000001; + } + + .loader-spinner { + border: 4px solid #f3f3f3; + border-top: 4px solid #3498db; + border-radius: 50%; + width: 32px; + height: 32px; + animation: spin 1s linear infinite; + } + + @keyframes spin { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } + } + ` + } + + show() { + document.head.appendChild(this.styles) + document.body.appendChild(this.loader) + } + + hide() { + if (this.loader.parentNode) { + this.loader.parentNode.removeChild(this.loader) + } + if (this.styles.parentNode) { + this.styles.parentNode.removeChild(this.styles) + } + } +} + +export class ModalHelper { + constructor() { + this.initializeStyles() + } + + async getArbitraryFee() { + const timestamp = Date.now() + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = `${myNode.protocol}://${myNode.domain}:${myNode.port}` + const url = `${nodeUrl}/transactions/unitfee?txType=ARBITRARY×tamp=${timestamp}` + const response = await fetch(url) + + if (!response.ok) { + throw new Error('Error when fetching arbitrary fee') + } + + const data = await response.json() + const arbitraryFee = (Number(data) / 1e8).toFixed(8) + + return { + timestamp, + fee: Number(data), + feeToShow: arbitraryFee + } + } + + async showModalAndWaitPublish(data) { + return new Promise((resolve) => { + const modal = this.createModal(data) + document.body.appendChild(modal) + this.addModalEventListeners(modal, resolve) + }) + } + + createModal(data) { + const modal = document.createElement('div') + modal.id = "backdrop" + modal.classList.add("backdrop") + + modal.innerHTML = ` + + ` + + return modal + } + + addModalEventListeners(modal, resolve) { + // Event listener for the 'OK' button + const okButton = modal.querySelector('#ok-button') + okButton.addEventListener('click', () => { + const userData = { isWithFee: true } + if (modal.parentNode === document.body) { + document.body.removeChild(modal) + } + + resolve({ action: 'accept', userData }) + }) + + // Prevent modal content from closing the modal + const modalContent = modal.querySelector('.modal-content') + modalContent.addEventListener('click', e => { + e.stopPropagation() + }) + + // Event listener for 'Backdrop' button + const backdropClick = document.getElementById('backdrop') + backdropClick.addEventListener('click', () => { + if (modal.parentNode === document.body) { + document.body.removeChild(modal) + } + + resolve({ action: 'reject' }) + }) + + // Event listener for 'Cancel' button + const cancelButton = modal.querySelector('#cancel-button') + cancelButton.addEventListener('click', () => { + if (modal.parentNode === document.body) { + document.body.removeChild(modal) + } + + resolve({ action: 'reject' }) + }) + } + + initializeStyles() { + const styles = ` + * { + --mdc-theme-primary: rgb(3, 169, 244); + --mdc-theme-secondary: var(--mdc-theme-primary); + --paper-input-container-focus-color: var(--mdc-theme-primary); + --mdc-checkbox-unchecked-color: var(--black); + --mdc-theme-on-surface: var(--black); + --mdc-checkbox-disabled-color: var(--black); + --mdc-checkbox-ink-color: var(--black); + } + + .backdrop { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgb(186 186 186 / 26%); + overflow: hidden; + animation: backdrop_blur cubic-bezier(0.22, 1, 0.36, 1) 0.1s forwards; + z-index: 1000000; + } + + @keyframes backdrop_blur { + 0% { + backdrop-filter: blur(0px); + background: transparent; + } + + 100% { + backdrop-filter: blur(5px); + background: rgb(186 186 186 / 26%); + } + } + + @keyframes modal_transition { + 0% { + visibility: hidden; + opacity: 0; + } + + 100% { + visibility: visible; + opacity: 1; + } + } + + .modal { + position: relative; + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + animation: 0.1s cubic-bezier(0.22, 1, 0.36, 1) 0s 1 normal forwards running modal_transition; + z-index: 1000001; + } + + @keyframes modal_transition { + 0% { + visibility: hidden; + opacity: 0; + } + + 100% { + visibility: visible; + opacity: 1; + } + } + + .modal-content { + background-color: var(--white); + border-radius: 10px; + padding: 20px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); + max-width: 80%; + min-width: 300px; + display: flex; + flex-direction: column; + justify-content: space-between; + } + + .modal-body { + padding: 25px; + } + + .modal-subcontainer { + color: var(--black); + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 15px; + } + + .modal-subcontainer-error { + color: var(--black); + display: flex; + flex-direction: column; + align-items: center; + gap: 15px; + } + + .modal-paragraph-error { + font-family: Roboto, sans-serif; + font-size: 20px; + letter-spacing: 0.3px; + font-weight: 700; + color: var(--black); + margin: 0; + } + + .modal-paragraph { + font-family: Roboto, sans-serif; + font-size: 18px; + letter-spacing: 0.3px; + font-weight: 300; + color: var(--black); + margin: 0; + word-wrap: break-word; + overflow-wrap: break-word; + } + + .capitalize-first { + text-transform: capitalize; + } + + .checkbox-row { + display: flex; + align-items: center; + font-family: Montserrat, sans-serif; + font-weight: 600; + color: var(--black); + } + + .modal-buttons { + display: flex; + justify-content: space-between; + margin-top: 20px; + } + + .modal-buttons button { + background-color: #4caf50; + border: none; + color: #fff; + padding: 10px 20px; + border-radius: 5px; + cursor: pointer; + transition: background-color 0.2s; + } + + .modal-buttons button:hover { + background-color: #3e8e41; + } + + #cancel-button { + background-color: #f44336; + } + + #cancel-button:hover { + background-color: #d32f2f; + } + ` + + const styleSheet = new CSSStyleSheet() + + styleSheet.replaceSync(styles) + + document.adoptedStyleSheets = [styleSheet] + } + + static getInstance() { + if (!ModalHelper.instance) { + ModalHelper.instance = new ModalHelper() + } + + return ModalHelper.instance + } +} + +export class WarningModal { + constructor() { + this.initializeStyles() + } + + async showModalAndWaitPublish(data) { + return new Promise((resolve) => { + const modal = this.createModal(data) + document.body.appendChild(modal) + this.addModalEventListeners(modal, resolve) + }) + } + + createModal(data) { + const modal = document.createElement('div') + + modal.id = "backdrop" + modal.classList.add("backdrop") + + modal.innerHTML = ` + + ` + + return modal + } + + addModalEventListeners(modal, resolve) { + // Event listener for the 'OK' button + const okButton = modal.querySelector('#ok-button') + okButton.addEventListener('click', () => { + const userData = { isWithFee: true } + + if (modal.parentNode === document.body) { + document.body.removeChild(modal) + } + + resolve({ action: 'accept', userData }) + }) + + // Prevent modal content from closing the modal + const modalContent = modal.querySelector('.modal-content') + modalContent.addEventListener('click', e => { + e.stopPropagation() + }) + + // Event listener for 'Backdrop' button + const backdropClick = document.getElementById('backdrop') + backdropClick.addEventListener('click', () => { + if (modal.parentNode === document.body) { + document.body.removeChild(modal) + } + + resolve({ action: 'reject' }) + }) + + // Event listener for 'Cancel' button + const cancelButton = modal.querySelector('#cancel-button') + cancelButton.addEventListener('click', () => { + if (modal.parentNode === document.body) { + document.body.removeChild(modal) + } + + resolve({ action: 'reject' }) + }) + } + + initializeStyles() { + const styles = ` + * { + --mdc-theme-primary: rgb(3, 169, 244); + --mdc-theme-secondary: var(--mdc-theme-primary); + --paper-input-container-focus-color: var(--mdc-theme-primary); + --mdc-checkbox-unchecked-color: var(--black); + --mdc-theme-on-surface: var(--black); + --mdc-checkbox-disabled-color: var(--black); + --mdc-checkbox-ink-color: var(--black); + } + + .backdrop { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgb(186 186 186 / 26%); + overflow: hidden; + animation: backdrop_blur cubic-bezier(0.22, 1, 0.36, 1) 0.1s forwards; + z-index: 1000000; + } + + @keyframes backdrop_blur { + 0% { + backdrop-filter: blur(0px); + background: transparent; + } + + 100% { + backdrop-filter: blur(5px); + background: rgb(186 186 186 / 26%); + } + } + + @keyframes modal_transition { + 0% { + visibility: hidden; + opacity: 0; + } + + 100% { + visibility: visible; + opacity: 1; + } + } + + .modal { + position: relative; + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + animation: 0.1s cubic-bezier(0.22, 1, 0.36, 1) 0s 1 normal forwards running modal_transition; + z-index: 1000001; + } + + @keyframes modal_transition { + 0% { + visibility: hidden; + opacity: 0; + } + + 100% { + visibility: visible; + opacity: 1; + } + } + + .modal-content { + background-color: var(--white); + border-radius: 10px; + padding: 20px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); + max-width: 650px; + min-width: 300px; + display: flex; + flex-direction: column; + justify-content: space-between; + } + + .modal-body { + padding: 25px; + } + + .modal-subcontainer { + color: var(--black); + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 15px; + } + + .modal-subcontainer-error { + color: var(--black); + display: flex; + flex-direction: column; + align-items: center; + gap: 15px; + } + + .modal-paragraph-error { + font-family: Roboto, sans-serif; + font-size: 20px; + letter-spacing: 0.3px; + font-weight: 700; + color: var(--black); + margin: 0; + } + + .modal-paragraph { + font-family: Roboto, sans-serif; + font-size: 18px; + letter-spacing: 0.3px; + font-weight: 300; + color: var(--black); + margin: 0; + word-wrap: break-word; + overflow-wrap: break-word; + } + + .capitalize-first { + text-transform: capitalize; + } + + .checkbox-row { + display: flex; + align-items: center; + font-family: Montserrat, sans-serif; + font-weight: 600; + color: var(--black); + } + + .modal-buttons { + display: flex; + justify-content: space-between; + margin-top: 20px; + } + + .modal-buttons button { + background-color: #4caf50; + border: none; + color: #fff; + padding: 10px 20px; + border-radius: 5px; + cursor: pointer; + transition: background-color 0.2s; + } + + .modal-buttons button:hover { + background-color: #3e8e41; + } + + #cancel-button { + background-color: #f44336; + } + + #cancel-button:hover { + background-color: #d32f2f; + } + ` + + const styleSheet = new CSSStyleSheet() + + styleSheet.replaceSync(styles) + + document.adoptedStyleSheets = [styleSheet] + } + + static getInstance() { + if (!WarningModal.instance) { + WarningModal.instance = new WarningModal() + } + + return WarningModal.instance + } +} + +export const modalHelper = ModalHelper.getInstance() +export const warningModal = WarningModal.getInstance() + +export const publishData = async ({ + registeredName, + path, + file, + service, + identifier, + parentEpml, + uploadType, + selectedAddress, + worker, + isBase64, + filename, + apiVersion, + withFee, + title, + description, + category, + tag1, + tag2, + tag3, + tag4, + tag5, + feeAmount +}) => { + const validateName = async (receiverName) => { + return await parentEpml.request('apiCall', { + type: 'api', + url: `/names/${receiverName}` + }) + } + + const convertBytesForSigning = async (transactionBytesBase58) => { + return await parentEpml.request('apiCall', { + type: 'api', + method: 'POST', + url: `/transactions/convert`, + body: `${transactionBytesBase58}` + }) + } + + const getArbitraryFee = async () => { + const timestamp = Date.now() + + let fee = await parentEpml.request('apiCall', { + url: `/transactions/unitfee?txType=ARBITRARY×tamp=${timestamp}` + }) + + return { + timestamp, + fee: Number(fee), + feeToShow: (Number(fee) / 1e8).toFixed(8) + } + } + + const signAndProcess = async (transactionBytesBase58) => { + let convertedBytesBase58 = await convertBytesForSigning( + transactionBytesBase58 + ) + + if (convertedBytesBase58.error) { + throw new Error('Error when signing') + } + + const convertedBytes = window.parent.Base58.decode(convertedBytesBase58) + + let nonce = null + + const computPath = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full' + + await new Promise((res, rej) => { + worker.postMessage({ convertedBytes, path: computPath }) + + worker.onmessage = e => { + worker.terminate() + nonce = e.data.nonce + res() + } + }) + + let response = await parentEpml.request('sign_arbitrary', { + nonce: selectedAddress.nonce, + arbitraryBytesBase58: transactionBytesBase58, + arbitraryBytesForSigningBase58: convertedBytesBase58, + arbitraryNonce: nonce, + apiVersion: apiVersion ? apiVersion : null + }) + + let myResponse = { error: '' } + + if (response === false) { + throw new Error('Error when signing') + } else { + myResponse = response + } + + return myResponse + } + + const signAndProcessWithFee = async (transactionBytesBase58) => { + let convertedBytesBase58 = await convertBytesForSigning( + transactionBytesBase58 + ) + + if (convertedBytesBase58.error) { + throw new Error('Error when signing') + } + + let response = await parentEpml.request('sign_arbitrary_with_fee', { + nonce: selectedAddress.nonce, + arbitraryBytesBase58: transactionBytesBase58, + arbitraryBytesForSigningBase58: convertedBytesBase58, + apiVersion: apiVersion ? apiVersion : null + }) + + let myResponse = { error: '' } + + if (response === false) { + throw new Error('Error when signing') + } else { + myResponse = response + } + + return myResponse + } + + const validate = async () => { + let validNameRes = await validateName(registeredName) + + if (validNameRes.error) { + throw new Error('Name not found') + } + + let fee = null + + if (withFee && feeAmount) { + fee = feeAmount + } else if (withFee) { + const res = await getArbitraryFee() + + if (res.fee) { + fee = res.fee + } else { + throw new Error('unable to get fee') + } + } + + let transactionBytes = await uploadData(registeredName, path, file, fee) + + if (transactionBytes.error) { + throw new Error(transactionBytes.message || 'Error when uploading') + } else if (transactionBytes.includes('Error 500 Internal Server Error')) { + throw new Error('Error when uploading') + } + + let signAndProcessRes + + if (withFee) { + signAndProcessRes = await signAndProcessWithFee(transactionBytes) + } + + if (!withFee) { + signAndProcessRes = await signAndProcess(transactionBytes) + } + + if (signAndProcessRes.error) { + throw new Error('Error when signing') + } + + return signAndProcessRes + } + + const uploadData = async (registeredName, path, file, fee) => { + if (identifier != null && identifier.trim().length > 0) { + let postBody = path + let urlSuffix = '' + + if (file != null) { + // If we're sending zipped data, make sure to use the /zip version of the POST /arbitrary/* API + if (uploadType === 'zip') { + urlSuffix = '/zip' + } + + // If we're sending file data, use the /base64 version of the POST /arbitrary/* API + else if (uploadType === 'file') { + urlSuffix = '/base64' + } + + // Base64 encode the file to work around compatibility issues between javascript and java byte arrays + if (isBase64) { + postBody = file + } + + if (!isBase64) { + let fileBuffer = new Uint8Array(await file.arrayBuffer()) + postBody = Buffer.from(fileBuffer).toString("base64") + } + + } + + let uploadDataUrl = `/arbitrary/${service}/${registeredName}${urlSuffix}?apiKey=${getApiKey()}` + + if (identifier.trim().length > 0) { + uploadDataUrl = `/arbitrary/${service}/${registeredName}/${identifier}${urlSuffix}?apiKey=${getApiKey()}` + } + + if (withFee) { + uploadDataUrl = uploadDataUrl + `&fee=${fee}` + } + + if (filename != null && filename != 'undefined') { + uploadDataUrl = uploadDataUrl + '&filename=' + encodeURIComponent(filename) + } + + if (title != null && title != 'undefined') { + uploadDataUrl = uploadDataUrl + '&title=' + encodeURIComponent(title) + } + + if (description != null && description != 'undefined') { + uploadDataUrl = uploadDataUrl + '&description=' + encodeURIComponent(description) + } + + if (category != null && category != 'undefined') { + uploadDataUrl = uploadDataUrl + '&category=' + encodeURIComponent(category) + } + + if (tag1 != null && tag1 != 'undefined') { + uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag1) + } + + if (tag2 != null && tag2 != 'undefined') { + uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag2) + } + + if (tag3 != null && tag3 != 'undefined') { + uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag3) + } + + if (tag4 != null && tag4 != 'undefined') { + uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag4) + } + + if (tag5 != null && tag5 != 'undefined') { + uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag5) + } + + return await parentEpml.request('apiCall', { + type: 'api', + method: 'POST', + url: `${uploadDataUrl}`, + body: `${postBody}` + }) + } + } + + try { + return await validate() + } catch (error) { + throw new Error(error.message) + } +} \ No newline at end of file diff --git a/plugins/plugins/utils/cropAddress.js b/plugins/plugins/utils/cropAddress.js deleted file mode 100644 index 8c0c3f1b..00000000 --- a/plugins/plugins/utils/cropAddress.js +++ /dev/null @@ -1,8 +0,0 @@ -export function cropAddress(string = "", range = 5) { - const [start, end] = [ - string?.substring(0, range), - string?.substring(string?.length - range, string?.length), - // - ]; - return start + "..." + end; -} diff --git a/plugins/plugins/utils/functions.js b/plugins/plugins/utils/functions.js new file mode 100644 index 00000000..138a7b7b --- /dev/null +++ b/plugins/plugins/utils/functions.js @@ -0,0 +1,208 @@ +import { Epml } from '../../epml' + +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + +export const inputKeyCodes = [ + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 160, 161, 162, 163, 164, 165, 170, 171, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 219, 220, 221, + 222, 223, 226 +] + +export const blocksNeed = (level) => { + if (level === 0) { + return '7200' + } else if (level === 1) { + return '72000' + } else if (level === 2) { + return '201600' + } else if (level === 3) { + return '374400' + } else if (level === 4) { + return '618400' + } else if (level === 5) { + return '964000' + } else if (level === 6) { + return '1482400' + } else if (level === 7) { + return '2173600' + } else if (level === 8) { + return '3037600' + } else if (level === 9) { + return '4074400' + } +} + +export const getUserNameFromAddress = async (address) => { + try { + const getNames = await parentEpml.request("apiCall", { + type: "api", + url: `/names/address/${address}` + }) + + if (Array.isArray(getNames) && getNames.length > 0 ) { + return getNames[0].name + } else { + return address + } + } catch (error) { + console.error(error) + } +} + +export const replaceMessagesEdited = async ({ decodedMessages, parentEpml, isReceipient, decodeMessageFunc, _publicKey, addToUpdateMessageHashmap }) => { + const MAX_CONCURRENT_REQUESTS = 5 // Maximum number of concurrent requests + + const executeWithConcurrencyLimit = async (array, asyncFn) => { + const results = [] + const concurrencyPool = [] + + for (const item of array) { + const promise = asyncFn(item) + concurrencyPool.push(promise) + + if (concurrencyPool.length >= MAX_CONCURRENT_REQUESTS) { + results.push(...await Promise.all(concurrencyPool)) + concurrencyPool.length = 0 // Clear the concurrency pool + } + } + + if (concurrencyPool.length > 0) { + results.push(...await Promise.all(concurrencyPool)) + } + + return results + } + + const findUpdatedMessage = async (msg) => { + let msgItem = { ...msg } + + try { + let msgQuery = `&involving=${msg.recipient}&involving=${msg.sender}` + if (!isReceipient) { + msgQuery = `&txGroupId=${msg.txGroupId}` + } + + // Find new messages first + const newMsgResponse = await parentEpml.request("apiCall", { + type: "api", + url: `/chat/messages?chatreference=${msg.signature}&reverse=true${msgQuery}&limit=1&sender=${msg.sender}&encoding=BASE64` + }) + + if (Array.isArray(newMsgResponse) && newMsgResponse.length > 0) { + const decodeResponseItem = decodeMessageFunc(newMsgResponse[0], isReceipient, _publicKey) + + delete decodeResponseItem.timestamp + + msgItem = { + ...msgItem, + ...decodeResponseItem, + senderName: msg.senderName, + sender: msg.sender, + editedTimestamp: newMsgResponse[0].timestamp, + originalSignature: msg.signature + } + } + + // Then check and find replies in the same iteration + let parsedMessageObj + + try { + parsedMessageObj = JSON.parse(msg.decodedMessage) + } catch (error) { + // If parsing fails, return the msgItem as is + return msgItem + } + + if (parsedMessageObj.repliedTo) { + let originalReply + + if (+parsedMessageObj.version > 2) { + originalReply = await parentEpml.request("apiCall", { + type: "api", + url: `/chat/message/${parsedMessageObj.repliedTo}?encoding=BASE64` + }) + } else { + originalReply = await parentEpml.request("apiCall", { + type: "api", + url: `/chat/messages?reference=${parsedMessageObj.repliedTo}&reverse=true${msgQuery}&encoding=BASE64` + }) + } + + const originalReplyMessage = originalReply.timestamp ? originalReply : originalReply.length > 0 ? originalReply[0] : null + + const replyResponse = await parentEpml.request("apiCall", { + type: "api", + url: `/chat/messages?chatreference=${parsedMessageObj.repliedTo}&reverse=true${msgQuery}&limit=1&sender=${originalReplyMessage.sender}&encoding=BASE64` + }) + + if (originalReplyMessage && Array.isArray(replyResponse) && replyResponse.length !== 0) { + const decodeOriginalReply = decodeMessageFunc(originalReplyMessage, isReceipient, _publicKey) + const decodeUpdatedReply = decodeMessageFunc(replyResponse[0], isReceipient, _publicKey) + + msgItem.repliedToData = { + ...decodeUpdatedReply, + senderName: decodeOriginalReply.senderName, + sender: decodeOriginalReply.sender + } + } else if (originalReplyMessage) { + msgItem.repliedToData = decodeMessageFunc(originalReplyMessage, isReceipient, _publicKey) + } + } + + } catch (error) { + // Handle or log the error gracefully + console.error(error) + } + + return msgItem + } + + const sortedMessages = decodedMessages.sort((a, b) => b.timestamp - a.timestamp) + + // Execute the functions with concurrency limit + const updatedMessages = await executeWithConcurrencyLimit(sortedMessages, findUpdatedMessage) + addToUpdateMessageHashmap(updatedMessages) + + return updatedMessages +} + +export function bytesToMegabytes(bytes) { + return bytes / (1024 * 1024) +} + +export function cropAddress(string = '', range = 5) { + const [start, end] = [ + string?.substring(0, range), + string?.substring(string?.length - range, string?.length) + ] + + return start + '...' + end +} + +export function roundToNearestDecimal(num) { + const mb = num / 1000000 + return Math.round(mb * 10) / 10 +} + +export function simpleHash(str) { + let hash = 0 + + for (let i = 0; i < str.length; i++) { + hash = (hash << 5) - hash + str.charCodeAt(i) + hash = hash & hash // Convert to 32bit integer + } + + return hash.toString() +} + +export function generateIdFromAddresses(address1, address2) { + // Sort addresses lexicographically and concatenate + const sortedAddresses = [address1, address2].sort().join('') + + return simpleHash(sortedAddresses) +} \ No newline at end of file diff --git a/plugins/plugins/utils/getUserNameFromAddress.js b/plugins/plugins/utils/getUserNameFromAddress.js deleted file mode 100644 index be8a3d69..00000000 --- a/plugins/plugins/utils/getUserNameFromAddress.js +++ /dev/null @@ -1,20 +0,0 @@ -import {Epml} from '../../epml.js'; - -const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) - -export const getUserNameFromAddress = async (address) => { - try { - const getNames = await parentEpml.request("apiCall", { - type: "api", - url: `/names/address/${address}`, - }); - - if (Array.isArray(getNames) && getNames.length > 0 ) { - return getNames[0].name; - } else { - return address; - } - } catch (error) { - console.error(error); - } -} diff --git a/plugins/plugins/utils/id-generation.js b/plugins/plugins/utils/id-generation.js deleted file mode 100644 index 88323156..00000000 --- a/plugins/plugins/utils/id-generation.js +++ /dev/null @@ -1,14 +0,0 @@ -export function simpleHash(str) { - let hash = 0; - for (let i = 0; i < str.length; i++) { - hash = (hash << 5) - hash + str.charCodeAt(i); - hash = hash & hash; // Convert to 32bit integer - } - return hash.toString(); -} - -export function generateIdFromAddresses(address1, address2) { - // Sort addresses lexicographically and concatenate - const sortedAddresses = [address1, address2].sort().join(''); - return simpleHash(sortedAddresses); -} \ No newline at end of file diff --git a/plugins/plugins/utils/keyCodes.js b/plugins/plugins/utils/keyCodes.js deleted file mode 100644 index d4d6ca50..00000000 --- a/plugins/plugins/utils/keyCodes.js +++ /dev/null @@ -1 +0,0 @@ -export const inputKeyCodes = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 160, 161, 162, 163, 164, 165, 170, 171, 186, 187, 188, 189, 190, 191, 192, 193, 194, 219, 220, 221, 222, 223, 226]; diff --git a/plugins/plugins/utils/loader.js b/plugins/plugins/utils/loader.js deleted file mode 100644 index 18123c3d..00000000 --- a/plugins/plugins/utils/loader.js +++ /dev/null @@ -1,52 +0,0 @@ -export class Loader { - constructor() { - this.loader = document.createElement("div"); - this.loader.className = "loader"; - this.loader.innerHTML = ` -
    - `; - this.styles = document.createElement("style"); - this.styles.innerHTML = ` - .loader { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: rgba(0, 0, 0, 0.5); - display: flex; - justify-content: center; - align-items: center; - z-index: 1000001 - } - - .loader-spinner { - border: 4px solid #f3f3f3; - border-top: 4px solid #3498db; - border-radius: 50%; - width: 32px; - height: 32px; - animation: spin 1s linear infinite; - } - - @keyframes spin { - from { transform: rotate(0deg); } - to { transform: rotate(360deg); } - } - `; - } - - show() { - document.head.appendChild(this.styles); - document.body.appendChild(this.loader); - } - - hide() { - if (this.loader.parentNode) { - this.loader.parentNode.removeChild(this.loader); - } - if (this.styles.parentNode) { - this.styles.parentNode.removeChild(this.styles); - } - } - } \ No newline at end of file diff --git a/plugins/plugins/utils/publish-image.js b/plugins/plugins/utils/publish-image.js deleted file mode 100644 index cc408a32..00000000 --- a/plugins/plugins/utils/publish-image.js +++ /dev/null @@ -1,248 +0,0 @@ -const getApiKey = () => { - const myNode = - window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] - return myNode.apiKey -} - -export const publishData = async ({ - registeredName, - path, - file, - service, - identifier, - parentEpml, - uploadType, - selectedAddress, - worker, - isBase64, - filename, - apiVersion, - withFee, - title, - description, - category, - tag1, - tag2, - tag3, - tag4, - tag5, - feeAmount -}) => { - const validateName = async (receiverName) => { - return await parentEpml.request("apiCall", { - type: "api", - url: `/names/${receiverName}`, - }) - } - - const convertBytesForSigning = async (transactionBytesBase58) => { - return await parentEpml.request("apiCall", { - type: "api", - method: "POST", - url: `/transactions/convert`, - body: `${transactionBytesBase58}`, - }) - } - const getArbitraryFee = async () => { - const timestamp = Date.now() - let fee = await parentEpml.request('apiCall', { - url: `/transactions/unitfee?txType=ARBITRARY×tamp=${timestamp}` - }) - return { - timestamp, - fee : Number(fee), - feeToShow: (Number(fee) / 1e8).toFixed(8) - } - } - - const signAndProcess = async (transactionBytesBase58) => { - let convertedBytesBase58 = await convertBytesForSigning( - transactionBytesBase58 - ) - if (convertedBytesBase58.error) { - throw new Error('Error when signing'); - } - - const convertedBytes = - window.parent.Base58.decode(convertedBytesBase58) - let nonce = null - const computPath =window.parent.location.origin + '/memory-pow/memory-pow.wasm.full' - await new Promise((res, rej) => { - - worker.postMessage({convertedBytes, path: computPath}); - - worker.onmessage = e => { - - worker.terminate() - - nonce = e.data.nonce - res() - - } - }) - - - let response = await parentEpml.request("sign_arbitrary", { - nonce: selectedAddress.nonce, - arbitraryBytesBase58: transactionBytesBase58, - arbitraryBytesForSigningBase58: convertedBytesBase58, - arbitraryNonce: nonce, - apiVersion: apiVersion ? apiVersion : null - }) - let myResponse = { error: "" } - if (response === false) { - throw new Error('Error when signing'); - } else { - myResponse = response - } - - return myResponse - } - - const signAndProcessWithFee = async (transactionBytesBase58) => { - let convertedBytesBase58 = await convertBytesForSigning( - transactionBytesBase58 - ) - if (convertedBytesBase58.error) { - throw new Error('Error when signing'); - } - - - - - let response = await parentEpml.request("sign_arbitrary_with_fee", { - nonce: selectedAddress.nonce, - arbitraryBytesBase58: transactionBytesBase58, - arbitraryBytesForSigningBase58: convertedBytesBase58, - apiVersion: apiVersion ? apiVersion : null - }) - let myResponse = { error: "" } - if (response === false) { - throw new Error('Error when signing'); - } else { - myResponse = response - } - - return myResponse - } - - const validate = async () => { - let validNameRes = await validateName(registeredName) - if (validNameRes.error) { - throw new Error('Name not found'); - } - let fee = null - if(withFee && feeAmount){ - fee= feeAmount - } else if(withFee){ - const res = await getArbitraryFee() - if(res.fee){ - fee= res.fee - } else { - throw new Error('unable to get fee') - } - } - let transactionBytes = await uploadData(registeredName, path, file, fee) - if (transactionBytes.error) { - throw new Error(transactionBytes.message || 'Error when uploading'); - } else if ( - transactionBytes.includes("Error 500 Internal Server Error") - ) { - throw new Error('Error when uploading'); - } - - let signAndProcessRes - if(withFee){ - signAndProcessRes = await signAndProcessWithFee(transactionBytes) - - } - if(!withFee){ - signAndProcessRes = await signAndProcess(transactionBytes) - - } - if (signAndProcessRes.error) { - throw new Error('Error when signing'); - } - return signAndProcessRes - } - - const uploadData = async (registeredName, path, file, fee) => { - if (identifier != null && identifier.trim().length > 0) { - let postBody = path - let urlSuffix = "" - if (file != null) { - // If we're sending zipped data, make sure to use the /zip version of the POST /arbitrary/* API - if (uploadType === "zip") { - urlSuffix = "/zip" - } - // If we're sending file data, use the /base64 version of the POST /arbitrary/* API - else if (uploadType === "file") { - urlSuffix = "/base64" - } - - // Base64 encode the file to work around compatibility issues between javascript and java byte arrays - if(isBase64){ - postBody = file - } - if(!isBase64){ - let fileBuffer = new Uint8Array(await file.arrayBuffer()) - postBody = Buffer.from(fileBuffer).toString("base64") - } - - } - - let uploadDataUrl = `/arbitrary/${service}/${registeredName}${urlSuffix}?apiKey=${getApiKey()}` - if (identifier.trim().length > 0) { - uploadDataUrl = `/arbitrary/${service}/${registeredName}/${identifier}${urlSuffix}?apiKey=${getApiKey()}` - - } - - if(withFee){ - uploadDataUrl = uploadDataUrl + `&fee=${fee}` - } - - if(filename != null && filename != "undefined"){ - uploadDataUrl = uploadDataUrl + '&filename=' + encodeURIComponent(filename) - } - if(title != null && title != "undefined"){ - uploadDataUrl = uploadDataUrl + '&title=' + encodeURIComponent(title) - } - if(description != null && description != "undefined"){ - uploadDataUrl = uploadDataUrl + '&description=' + encodeURIComponent(description) - } - if(category != null && category != "undefined"){ - uploadDataUrl = uploadDataUrl + '&category=' + encodeURIComponent(category) - } - if(tag1 != null && tag1 != "undefined"){ - uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag1) - } - if(tag2 != null && tag2 != "undefined"){ - uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag2) - } - if(tag3 != null && tag3 != "undefined"){ - uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag3) - } - if(tag4 != null && tag4 != "undefined"){ - uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag4) - } - if(tag5 != null && tag5 != "undefined"){ - uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag5) - } - - return await parentEpml.request("apiCall", { - type: "api", - method: "POST", - url: `${uploadDataUrl}`, - body: `${postBody}`, - }) - } - } - try { - return await validate() - } catch (error) { - throw new Error(error.message) - } - -} diff --git a/plugins/plugins/utils/publish-modal.css b/plugins/plugins/utils/publish-modal.css deleted file mode 100644 index f5ded060..00000000 --- a/plugins/plugins/utils/publish-modal.css +++ /dev/null @@ -1,147 +0,0 @@ -.backdrop { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgb(186 186 186 / 26%); - overflow: hidden; - animation: backdrop_blur cubic-bezier(0.22, 1, 0.36, 1) 1s forwards; - z-index: 1000000; -} - -@keyframes backdrop_blur { - 0% { - backdrop-filter: blur(0px); - background: transparent; - } - 100% { - backdrop-filter: blur(5px); - background: rgb(186 186 186 / 26%); - } -} - -@keyframes modal_transition { - 0% { - visibility: hidden; - opacity: 0; -} - 100% { - visibility: visible; - opacity: 1; - } -} - -.modal { - position: relative; - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; - animation: 1s cubic-bezier(0.22, 1, 0.36, 1) 0s 1 normal forwards running modal_transition; - z-index: 1000001; -} - -@keyframes modal_transition { - 0% { - visibility: hidden; - opacity: 0; - } - 100% { - visibility: visible; - opacity: 1; - } -} - -.modal-content { - background-color: var(--white); - border-radius: 10px; - padding: 20px; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); - max-width: 80%; - min-width: 300px; - display: flex; - flex-direction: column; - justify-content: space-between; -} - -.modal-body { - padding: 25px; -} - -.modal-subcontainer { - color: var(--black); - display: flex; - flex-direction: column; - align-items: flex-start; - gap: 15px; -} - -.modal-subcontainer-error { - color: var(--black); - display: flex; - flex-direction: column; - align-items: center; - gap: 15px; -} - -.modal-paragraph-error { - font-family: Roboto, sans-serif; - font-size: 20px; - letter-spacing: 0.3px; - font-weight: 700; - color: var(--black); - margin: 0; -} - -.modal-paragraph { - font-family: Roboto, sans-serif; - font-size: 18px; - letter-spacing: 0.3px; - font-weight: 300; - color: var(--black); - margin: 0; - word-wrap: break-word; - overflow-wrap: break-word; -} - -.capitalize-first { - text-transform: capitalize; -} - -.checkbox-row { - display: flex; - align-items: center; - font-family: Montserrat, sans-serif; - font-weight: 600; - color: var(--black); -} - -.modal-buttons { - display: flex; - justify-content: space-between; - margin-top: 20px; -} - -.modal-buttons button { - background-color: #4caf50; - border: none; - color: #fff; - padding: 10px 20px; - border-radius: 5px; - cursor: pointer; - transition: background-color 0.2s; -} - -.modal-buttons button:hover { - background-color: #3e8e41; -} - -#cancel-button { - background-color: #f44336; -} - -#cancel-button:hover { - background-color: #d32f2f; -} \ No newline at end of file diff --git a/plugins/plugins/utils/publish-modal.js b/plugins/plugins/utils/publish-modal.js deleted file mode 100644 index 76c60f67..00000000 --- a/plugins/plugins/utils/publish-modal.js +++ /dev/null @@ -1,270 +0,0 @@ -import {get} from '../../../core/translate' - -export class ModalHelper { - constructor() { - this.initializeStyles(); - } - - async getArbitraryFee() { - const timestamp = Date.now(); - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; - const nodeUrl = `${myNode.protocol}://${myNode.domain}:${myNode.port}`; - const url = `${nodeUrl}/transactions/unitfee?txType=ARBITRARY×tamp=${timestamp}`; - const response = await fetch(url); - - if (!response.ok) { - throw new Error('Error when fetching arbitrary fee'); - } - - const data = await response.json(); - const arbitraryFee = (Number(data) / 1e8).toFixed(8); - return { - timestamp, - fee: Number(data), - feeToShow: arbitraryFee - }; - } - - async showModalAndWaitPublish(data) { - return new Promise((resolve) => { - const modal = this.createModal(data); - document.body.appendChild(modal); - this.addModalEventListeners(modal, resolve); - }); - } - - createModal(data) { - const modal = document.createElement('div'); - modal.id = "backdrop"; - modal.classList.add("backdrop"); - modal.innerHTML = ` - - `; - return modal; - } - - addModalEventListeners(modal, resolve) { - // Event listener for the 'OK' button - const okButton = modal.querySelector('#ok-button'); - okButton.addEventListener('click', () => { - const userData = { isWithFee: true }; - if (modal.parentNode === document.body) { - document.body.removeChild(modal); - } - resolve({ action: 'accept', userData }); - }); - - // Prevent modal content from closing the modal - const modalContent = modal.querySelector('.modal-content'); - modalContent.addEventListener('click', e => { - e.stopPropagation(); - }); - - // Event listeners for backdrop and 'Cancel' button - const backdropClick = document.getElementById('backdrop'); - backdropClick.addEventListener('click', () => { - if (modal.parentNode === document.body) { - document.body.removeChild(modal); - } - resolve({ action: 'reject' }); - }); - - const cancelButton = modal.querySelector('#cancel-button'); - cancelButton.addEventListener('click', () => { - if (modal.parentNode === document.body) { - document.body.removeChild(modal); - } - resolve({ action: 'reject' }); - }); - } - - initializeStyles() { - const styles = ` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --paper-input-container-focus-color: var(--mdc-theme-primary); - --mdc-checkbox-unchecked-color: var(--black); - --mdc-theme-on-surface: var(--black); - --mdc-checkbox-disabled-color: var(--black); - --mdc-checkbox-ink-color: var(--black); - } - - .backdrop { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgb(186 186 186 / 26%); - overflow: hidden; - animation: backdrop_blur cubic-bezier(0.22, 1, 0.36, 1) 0.1s forwards; - z-index: 1000000; - } - - @keyframes backdrop_blur { - 0% { - backdrop-filter: blur(0px); - background: transparent; - } - 100% { - backdrop-filter: blur(5px); - background: rgb(186 186 186 / 26%); - } - } - - @keyframes modal_transition { - 0% { - visibility: hidden; - opacity: 0; - } - 100% { - visibility: visible; - opacity: 1; - } - } - - .modal { - position: relative; - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; - animation: 0.1s cubic-bezier(0.22, 1, 0.36, 1) 0s 1 normal forwards running modal_transition; - z-index: 1000001; - } - - @keyframes modal_transition { - 0% { - visibility: hidden; - opacity: 0; - } - 100% { - visibility: visible; - opacity: 1; - } - } - - .modal-content { - background-color: var(--white); - border-radius: 10px; - padding: 20px; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); - max-width: 80%; - min-width: 300px; - display: flex; - flex-direction: column; - justify-content: space-between; - } - - .modal-body { - padding: 25px; - } - - .modal-subcontainer { - color: var(--black); - display: flex; - flex-direction: column; - align-items: flex-start; - gap: 15px; - } - - .modal-subcontainer-error { - color: var(--black); - display: flex; - flex-direction: column; - align-items: center; - gap: 15px; - } - - .modal-paragraph-error { - font-family: Roboto, sans-serif; - font-size: 20px; - letter-spacing: 0.3px; - font-weight: 700; - color: var(--black); - margin: 0; - } - - .modal-paragraph { - font-family: Roboto, sans-serif; - font-size: 18px; - letter-spacing: 0.3px; - font-weight: 300; - color: var(--black); - margin: 0; - word-wrap: break-word; - overflow-wrap: break-word; - } - - .capitalize-first { - text-transform: capitalize; - } - - .checkbox-row { - display: flex; - align-items: center; - font-family: Montserrat, sans-serif; - font-weight: 600; - color: var(--black); - } - - .modal-buttons { - display: flex; - justify-content: space-between; - margin-top: 20px; - } - - .modal-buttons button { - background-color: #4caf50; - border: none; - color: #fff; - padding: 10px 20px; - border-radius: 5px; - cursor: pointer; - transition: background-color 0.2s; - } - - .modal-buttons button:hover { - background-color: #3e8e41; - } - - #cancel-button { - background-color: #f44336; - } - - #cancel-button:hover { - background-color: #d32f2f; - } - `; - - const styleSheet = new CSSStyleSheet(); - styleSheet.replaceSync(styles); - - document.adoptedStyleSheets = [styleSheet]; - } - - static getInstance() { - if (!ModalHelper.instance) { - ModalHelper.instance = new ModalHelper(); - } - return ModalHelper.instance; - } -} - -export const modalHelper = ModalHelper.getInstance(); diff --git a/plugins/plugins/utils/queue.js b/plugins/plugins/utils/queue.js deleted file mode 100644 index f4b9ff62..00000000 --- a/plugins/plugins/utils/queue.js +++ /dev/null @@ -1,71 +0,0 @@ -export class RequestQueue { - constructor(maxConcurrent = 5) { - this.queue = []; - this.maxConcurrent = maxConcurrent; - this.currentConcurrent = 0; - } - - push(request) { - return new Promise((resolve, reject) => { - this.queue.push({ - request, - resolve, - reject, - }); - this.checkQueue(); - }); - } - - checkQueue() { - if (this.queue.length === 0 || this.currentConcurrent >= this.maxConcurrent) return; - - const { request, resolve, reject } = this.queue.shift(); - this.currentConcurrent++; - - request() - .then(resolve) - .catch(reject) - .finally(() => { - this.currentConcurrent--; - this.checkQueue(); - }); - } -} - -export class RequestQueueWithPromise { - constructor(maxConcurrent = 5) { - this.queue = []; - this.maxConcurrent = maxConcurrent; - this.currentlyProcessing = 0; - } - - // Add a request to the queue and return a promise - enqueue(request) { - return new Promise((resolve, reject) => { - // Push the request and its resolve and reject callbacks to the queue - this.queue.push({ request, resolve, reject }); - this.process(); - }); - } - - // Process requests in the queue - async process() { - while (this.queue.length > 0 && this.currentlyProcessing < this.maxConcurrent) { - this.currentlyProcessing++; - const { request, resolve, reject } = this.queue.shift(); - try { - const response = await request(); - resolve(response); - } catch (error) { - reject(error); - } finally { - this.currentlyProcessing--; - await this.process(); - } - } - } - } - - - - diff --git a/plugins/plugins/utils/replace-messages-edited.js b/plugins/plugins/utils/replace-messages-edited.js deleted file mode 100644 index 129a4a8b..00000000 --- a/plugins/plugins/utils/replace-messages-edited.js +++ /dev/null @@ -1,251 +0,0 @@ -// export const replaceMessagesEdited = async ({ -// decodedMessages, -// parentEpml, -// isReceipient, -// decodeMessageFunc, -// _publicKey, -// addToUpdateMessageHashmap -// }) => { -// const findNewMessages = decodedMessages.map(async (msg) => { -// let msgItem = null -// try { -// let msgQuery = `&involving=${msg.recipient}&involving=${msg.sender}` -// if (!isReceipient) { -// msgQuery = `&txGroupId=${msg.txGroupId}` -// } -// const response = await parentEpml.request("apiCall", { -// type: "api", -// url: `/chat/messages?chatreference=${msg.signature}&reverse=true${msgQuery}&limit=1&sender=${msg.sender}&encoding=BASE64`, -// }) - -// if (response && Array.isArray(response) && response.length !== 0) { -// let responseItem = { ...response[0] } -// const decodeResponseItem = decodeMessageFunc(responseItem, isReceipient, _publicKey) -// delete decodeResponseItem.timestamp - -// msgItem = { -// ...msg, -// ...decodeResponseItem, -// senderName: msg.senderName, -// sender: msg.sender, -// editedTimestamp: response[0].timestamp, -// originalSignature: msg.signature -// } -// } -// } catch (error) { -// } - -// return msgItem -// }) -// const updateMessages = await Promise.all(findNewMessages) -// const filterOutNull = updateMessages.filter((item)=> item !== 'null' && item !== null) - -// const findNewMessages2 = filterOutNull.map(async (msg) => { -// let parsedMessageObj = msg -// try { -// parsedMessageObj = JSON.parse(msg.decodedMessage) -// } catch (error) { -// return msg -// } -// let msgItem = msg -// try { -// let msgQuery = `&involving=${msg.recipient}&involving=${msg.sender}` -// if (!isReceipient) { -// msgQuery = `&txGroupId=${msg.txGroupId}` -// } -// if (parsedMessageObj.repliedTo) { -// let originalReply -// if(+parsedMessageObj.version > 2){ -// originalReply = await parentEpml.request("apiCall", { -// type: "api", -// url: `/chat/message/${parsedMessageObj.repliedTo}?encoding=BASE64`, -// }) -// } -// if(+parsedMessageObj.version < 3){ -// originalReply = await parentEpml.request("apiCall", { -// type: "api", -// url: `/chat/messages?reference=${parsedMessageObj.repliedTo}&reverse=true${msgQuery}&encoding=BASE64`, -// }) -// } - - - - -// const originalReplyMessage = originalReply.timestamp ? originalReply : originalReply.length !== 0 ? originalReply[0] : null - -// const response = await parentEpml.request("apiCall", { -// type: "api", -// url: `/chat/messages?chatreference=${parsedMessageObj.repliedTo}&reverse=true${msgQuery}&limit=1&sender=${originalReplyMessage.sender}&encoding=BASE64`, -// }) - -// if ( -// originalReplyMessage && -// response && -// Array.isArray(response) && -// response.length !== 0 -// ) { -// const decodeOriginalReply = decodeMessageFunc(originalReplyMessage, isReceipient, _publicKey) - -// const decodeUpdatedReply = decodeMessageFunc(response[0], isReceipient, _publicKey) -// const formattedRepliedToData = { -// ...decodeUpdatedReply, -// senderName: decodeOriginalReply.senderName, -// sender: decodeOriginalReply.sender, -// } -// msgItem = { -// ...msg, -// repliedToData: formattedRepliedToData, -// } -// } else { - - -// if ( -// originalReplyMessage -// ) { - -// msgItem = { -// ...msg, -// repliedToData: decodeMessageFunc(originalReplyMessage, isReceipient, _publicKey), -// } -// } -// } -// } -// } catch (error) { -// } - -// return msgItem -// }) -// const updateMessages2 = await Promise.all(findNewMessages2) -// console.log({updateMessages2}) -// updateMessages2.forEach((item)=> { -// addToUpdateMessageHashmap(item.originalSignature, item) -// }) -// return updateMessages2 -// } - - -export const replaceMessagesEdited = async ({ - decodedMessages, - parentEpml, - isReceipient, - decodeMessageFunc, - _publicKey, - addToUpdateMessageHashmap -}) => { - const MAX_CONCURRENT_REQUESTS = 5; // Maximum number of concurrent requests - - const executeWithConcurrencyLimit = async (array, asyncFn) => { - const results = []; - const concurrencyPool = []; - - for (const item of array) { - const promise = asyncFn(item); - concurrencyPool.push(promise); - - if (concurrencyPool.length >= MAX_CONCURRENT_REQUESTS) { - results.push(...await Promise.all(concurrencyPool)); - concurrencyPool.length = 0; // Clear the concurrency pool - } - } - - if (concurrencyPool.length > 0) { - results.push(...await Promise.all(concurrencyPool)); - } - - return results; - }; - - const findUpdatedMessage = async (msg) => { - let msgItem = { ...msg }; - - try { - let msgQuery = `&involving=${msg.recipient}&involving=${msg.sender}`; - if (!isReceipient) { - msgQuery = `&txGroupId=${msg.txGroupId}`; - } - - // Find new messages first - const newMsgResponse = await parentEpml.request("apiCall", { - type: "api", - url: `/chat/messages?chatreference=${msg.signature}&reverse=true${msgQuery}&limit=1&sender=${msg.sender}&encoding=BASE64`, - }); - - if (Array.isArray(newMsgResponse) && newMsgResponse.length > 0) { - const decodeResponseItem = decodeMessageFunc(newMsgResponse[0], isReceipient, _publicKey); - delete decodeResponseItem.timestamp; - - msgItem = { - ...msgItem, - ...decodeResponseItem, - senderName: msg.senderName, - sender: msg.sender, - editedTimestamp: newMsgResponse[0].timestamp, - originalSignature: msg.signature - }; - } - - // Then check and find replies in the same iteration - let parsedMessageObj; - try { - parsedMessageObj = JSON.parse(msg.decodedMessage); - } catch (error) { - // If parsing fails, return the msgItem as is - return msgItem; - } - - if (parsedMessageObj.repliedTo) { - let originalReply; - if(+parsedMessageObj.version > 2){ - originalReply = await parentEpml.request("apiCall", { - type: "api", - url: `/chat/message/${parsedMessageObj.repliedTo}?encoding=BASE64`, - }); - } else { - originalReply = await parentEpml.request("apiCall", { - type: "api", - url: `/chat/messages?reference=${parsedMessageObj.repliedTo}&reverse=true${msgQuery}&encoding=BASE64`, - }); - } - - const originalReplyMessage = originalReply.timestamp ? originalReply : originalReply.length > 0 ? originalReply[0] : null; - - const replyResponse = await parentEpml.request("apiCall", { - type: "api", - url: `/chat/messages?chatreference=${parsedMessageObj.repliedTo}&reverse=true${msgQuery}&limit=1&sender=${originalReplyMessage.sender}&encoding=BASE64`, - }); - - if ( - originalReplyMessage && - Array.isArray(replyResponse) && - replyResponse.length !== 0 - ) { - const decodeOriginalReply = decodeMessageFunc(originalReplyMessage, isReceipient, _publicKey); - const decodeUpdatedReply = decodeMessageFunc(replyResponse[0], isReceipient, _publicKey); - - msgItem.repliedToData = { - ...decodeUpdatedReply, - senderName: decodeOriginalReply.senderName, - sender: decodeOriginalReply.sender, - }; - } else if (originalReplyMessage) { - msgItem.repliedToData = decodeMessageFunc(originalReplyMessage, isReceipient, _publicKey); - } - } - - } catch (error) { - // Handle or log the error gracefully - console.error(error); - } - - return msgItem; - }; - - const sortedMessages = decodedMessages.sort((a, b) => b.timestamp - a.timestamp); - - // Execute the functions with concurrency limit - const updatedMessages = await executeWithConcurrencyLimit(sortedMessages, findUpdatedMessage); - addToUpdateMessageHashmap(updatedMessages); - - return updatedMessages; - -}; diff --git a/plugins/plugins/utils/roundToNearestDecimal.js b/plugins/plugins/utils/roundToNearestDecimal.js deleted file mode 100644 index 5e3fe0aa..00000000 --- a/plugins/plugins/utils/roundToNearestDecimal.js +++ /dev/null @@ -1,4 +0,0 @@ -export function roundToNearestDecimal(num) { - const mb = num / 1000000; - return Math.round(mb * 10) / 10; -} \ No newline at end of file diff --git a/plugins/plugins/utils/warning-modal.js b/plugins/plugins/utils/warning-modal.js deleted file mode 100644 index 0399591f..00000000 --- a/plugins/plugins/utils/warning-modal.js +++ /dev/null @@ -1,252 +0,0 @@ -import {get} from '../../../core/translate' - -export class WarningModal { - constructor() { - this.initializeStyles(); - } - - - async showModalAndWaitPublish(data) { - return new Promise((resolve) => { - const modal = this.createModal(data); - document.body.appendChild(modal); - this.addModalEventListeners(modal, resolve); - }); - } - - createModal(data) { - const modal = document.createElement('div'); - modal.id = "backdrop"; - modal.classList.add("backdrop"); - modal.innerHTML = ` - - `; - return modal; - } - - addModalEventListeners(modal, resolve) { - // Event listener for the 'OK' button - const okButton = modal.querySelector('#ok-button'); - okButton.addEventListener('click', () => { - const userData = { isWithFee: true }; - if (modal.parentNode === document.body) { - document.body.removeChild(modal); - } - resolve({ action: 'accept', userData }); - }); - - // Prevent modal content from closing the modal - const modalContent = modal.querySelector('.modal-content'); - modalContent.addEventListener('click', e => { - e.stopPropagation(); - }); - - // Event listeners for backdrop and 'Cancel' button - const backdropClick = document.getElementById('backdrop'); - backdropClick.addEventListener('click', () => { - if (modal.parentNode === document.body) { - document.body.removeChild(modal); - } - resolve({ action: 'reject' }); - }); - - const cancelButton = modal.querySelector('#cancel-button'); - cancelButton.addEventListener('click', () => { - if (modal.parentNode === document.body) { - document.body.removeChild(modal); - } - resolve({ action: 'reject' }); - }); - } - - initializeStyles() { - const styles = ` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --paper-input-container-focus-color: var(--mdc-theme-primary); - --mdc-checkbox-unchecked-color: var(--black); - --mdc-theme-on-surface: var(--black); - --mdc-checkbox-disabled-color: var(--black); - --mdc-checkbox-ink-color: var(--black); - } - - .backdrop { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgb(186 186 186 / 26%); - overflow: hidden; - animation: backdrop_blur cubic-bezier(0.22, 1, 0.36, 1) 0.1s forwards; - z-index: 1000000; - } - - @keyframes backdrop_blur { - 0% { - backdrop-filter: blur(0px); - background: transparent; - } - 100% { - backdrop-filter: blur(5px); - background: rgb(186 186 186 / 26%); - } - } - - @keyframes modal_transition { - 0% { - visibility: hidden; - opacity: 0; - } - 100% { - visibility: visible; - opacity: 1; - } - } - - .modal { - position: relative; - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; - animation: 0.1s cubic-bezier(0.22, 1, 0.36, 1) 0s 1 normal forwards running modal_transition; - z-index: 1000001; - } - - @keyframes modal_transition { - 0% { - visibility: hidden; - opacity: 0; - } - 100% { - visibility: visible; - opacity: 1; - } - } - - .modal-content { - background-color: var(--white); - border-radius: 10px; - padding: 20px; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); - max-width: 650px; - min-width: 300px; - display: flex; - flex-direction: column; - justify-content: space-between; - } - - .modal-body { - padding: 25px; - } - - .modal-subcontainer { - color: var(--black); - display: flex; - flex-direction: column; - align-items: flex-start; - gap: 15px; - } - - .modal-subcontainer-error { - color: var(--black); - display: flex; - flex-direction: column; - align-items: center; - gap: 15px; - } - - .modal-paragraph-error { - font-family: Roboto, sans-serif; - font-size: 20px; - letter-spacing: 0.3px; - font-weight: 700; - color: var(--black); - margin: 0; - } - - .modal-paragraph { - font-family: Roboto, sans-serif; - font-size: 18px; - letter-spacing: 0.3px; - font-weight: 300; - color: var(--black); - margin: 0; - word-wrap: break-word; - overflow-wrap: break-word; - } - - .capitalize-first { - text-transform: capitalize; - } - - .checkbox-row { - display: flex; - align-items: center; - font-family: Montserrat, sans-serif; - font-weight: 600; - color: var(--black); - } - - .modal-buttons { - display: flex; - justify-content: space-between; - margin-top: 20px; - } - - .modal-buttons button { - background-color: #4caf50; - border: none; - color: #fff; - padding: 10px 20px; - border-radius: 5px; - cursor: pointer; - transition: background-color 0.2s; - } - - .modal-buttons button:hover { - background-color: #3e8e41; - } - - #cancel-button { - background-color: #f44336; - } - - #cancel-button:hover { - background-color: #d32f2f; - } - `; - - const styleSheet = new CSSStyleSheet(); - styleSheet.replaceSync(styles); - - document.adoptedStyleSheets = [styleSheet]; - } - - - static getInstance() { - if (!WarningModal.instance) { - WarningModal.instance = new WarningModal(); - } - return WarningModal.instance; - } -} - -export const warningModal = WarningModal.getInstance(); diff --git a/plugins/watch.js b/plugins/watch.js index e42b9195..f6bb3998 100644 --- a/plugins/watch.js +++ b/plugins/watch.js @@ -1,5 +1,4 @@ const rollup = require('rollup') - const configs = require('./build-config.js')() const watch = () => { @@ -19,4 +18,4 @@ const watch = () => { console.log('WATCH PLUGINS ==> Write Bundle : Done 🎉') } -module.exports = watch +module.exports = watch \ No newline at end of file diff --git a/scripts/afterPack.js b/scripts/afterPack.js index 73bda2a0..f7084bd8 100644 --- a/scripts/afterPack.js +++ b/scripts/afterPack.js @@ -1,45 +1,39 @@ const path = require('path') -const shell = require("shelljs"); +const shell = require("shelljs") const runShellCommand = (appOutDir) => { + shell.exec( + `chmod 4755 ${path.join(appOutDir, "chrome-sandbox")}`, - shell.exec( - `chmod 4755 ${path.join(appOutDir, "chrome-sandbox")}`, - - function (code, stdout, stderr) { - console.log('runShellCommand ==> Exit code:', code); - if (stderr) { - console.log('runShellCommand ==> Program stderr:', stderr); - } - }); + function (code, stdout, stderr) { + console.log('runShellCommand ==> Exit code:', code) + if (stderr) { + console.log('runShellCommand ==> Program stderr:', stderr) + } + } + ) } async function doLinux(context) { + console.log("Running doLinux ==> ") - console.log("Running doLinux ==> "); + const { targets, appOutDir } = context - const { targets, appOutDir } = context - - targets.forEach(async target => { - - if (!["appimage", "snap"].includes(target.name.toLowerCase())) { - - await runShellCommand(appOutDir) - } - }); + targets.forEach(async target => { + if (!["appimage", "snap"].includes(target.name.toLowerCase())) { + await runShellCommand(appOutDir) + } + }) } async function afterPack(context) { + console.log("Running AfterPack") - console.log("Running AfterPack"); - - const electronPlatformName = context.electronPlatformName.toLowerCase(); - - if (electronPlatformName.includes("linux")) { - await doLinux(context); - - } + const electronPlatformName = context.electronPlatformName.toLowerCase() + if (electronPlatformName.includes("linux")) { + await doLinux(context) + } } -module.exports = afterPack +module.exports = afterPack \ No newline at end of file diff --git a/scripts/notarize.js b/scripts/notarize.js index f4541f5c..81a8f6c2 100644 --- a/scripts/notarize.js +++ b/scripts/notarize.js @@ -1,20 +1,21 @@ -require('dotenv').config(); -const { notarize } = require('@electron/notarize'); +require('dotenv').config() +const { notarize } = require('@electron/notarize') exports.default = async function notarizing(context) { - const { electronPlatformName, appOutDir } = context; - if (electronPlatformName !== 'darwin') { - return; - } + const { electronPlatformName, appOutDir } = context - const appName = context.packager.appInfo.productFilename; + if (electronPlatformName !== 'darwin') { + return + } - return await notarize({ - appBundleId: 'org.qortal.QortalUI', - appPath: `${appOutDir}/${appName}.app`, - tool: "notarytool", - teamId: process.env.APPLETEAMID, - appleId: process.env.APPLEID, - appleIdPassword: process.env.APPLEIDPASS, - }); -}; + const appName = context.packager.appInfo.productFilename + + return await notarize({ + appBundleId: 'org.qortal.QortalUI', + appPath: `${appOutDir}/${appName}.app`, + tool: "notarytool", + teamId: process.env.APPLETEAMID, + appleId: process.env.APPLEID, + appleIdPassword: process.env.APPLEIDPASS + }) +} \ No newline at end of file diff --git a/server.js b/server.js index c53090f3..fad65218 100644 --- a/server.js +++ b/server.js @@ -1,30 +1,24 @@ const path = require("path") - const uiCore = require('./core/ui-core.js') const createServer = uiCore('server') - const config = require('./config/config.js') - const pluginsController = require('./plugins/default-plugins.js') + const qortalPlugins = pluginsController('plugins') - -const plugins = [ - ...qortalPlugins -] - +const plugins = [...qortalPlugins] const rootDir = process.env.NODE_ENV === 'production' ? __dirname : __dirname - const conf = { - ...config, - build: { - ...config.build, - options: { - ...config.build.options, - outputDir: path.join(rootDir, '/builtWWW') - } - } + ...config, + build: { + ...config.build, + options: { + ...config.build.options, + outputDir: path.join(rootDir, '/builtWWW') + } + } } const server = createServer(conf, plugins) -server.start() + +server.start() \ No newline at end of file diff --git a/watch-inline.js b/watch-inline.js index e14bbe91..8a870f84 100644 --- a/watch-inline.js +++ b/watch-inline.js @@ -1,25 +1,24 @@ const path = require('path') const uiCore = require('./core/ui-core.js') +const config = require('./config/config.js') +const pluginsController = require('./plugins/default-plugins.js') + const generateBuildConfig = uiCore('generate_build_config') const watchInlines = uiCore('watch_inline') -const config = require('./config/config.js') - -const pluginsController = require('./plugins/default-plugins.js') const watchDefaultPlugins = pluginsController('watch') - let srcConfig = { - ...config.build, - options: { - ...config.build.options, - outputDir: path.join(__dirname, '/builtWWW'), - sassOutputDir: path.join(__dirname, '/builtWWW/styles.bundle.css'), - } + ...config.build, + options: { + ...config.build.options, + outputDir: path.join(__dirname, '/builtWWW'), + sassOutputDir: path.join(__dirname, '/builtWWW/styles.bundle.css') + } } const { inlineConfigs } = generateBuildConfig(srcConfig) module.exports = () => { - watchInlines(inlineConfigs) - watchDefaultPlugins() -} + watchInlines(inlineConfigs) + watchDefaultPlugins() +} \ No newline at end of file diff --git a/watch.js b/watch.js index 3116d7ea..dfd8a096 100644 --- a/watch.js +++ b/watch.js @@ -3,23 +3,22 @@ const uiCore = require('./core/ui-core.js') const generateBuildConfig = uiCore('generate_build_config') const watch = uiCore('watch') const config = require('./config/config.js') - const pluginsController = require('./plugins/default-plugins.js') -const watchPlugins = pluginsController('watch') - const watchInline = require('./watch-inline.js') +const watchPlugins = pluginsController('watch') + let srcConfig = { - ...config.build, - options: { - ...config.build.options, - outputDir: path.join(__dirname, '/builtWWW'), - sassOutputDir: path.join(__dirname, '/builtWWW/styles.bundle.css'), - } + ...config.build, + options: { + ...config.build.options, + outputDir: path.join(__dirname, '/builtWWW'), + sassOutputDir: path.join(__dirname, '/builtWWW/styles.bundle.css') + } } const { buildConfig, inlineConfigs } = generateBuildConfig(srcConfig) watch(buildConfig.options, buildConfig.outputs, buildConfig.outputOptions, buildConfig.inputOptions) watchInline() -watchPlugins() +watchPlugins() \ No newline at end of file