From 332952a8a0b9cb0061d1bb8bf11aa0eda740b0b5 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Fri, 17 Feb 2023 16:48:35 +0100 Subject: [PATCH] Rework Name functions --- qortal-ui-core/src/components/app-view.js | 12 +- qortal-ui-plugins/build-config.js | 4 + qortal-ui-plugins/plugins/core/main.src.js | 9 + .../name-registration.src.js | 584 ++++---- .../plugins/core/names-market/index.html | 55 + .../core/names-market/names-market.src.js | 1211 +++++++++++++++++ 6 files changed, 1517 insertions(+), 358 deletions(-) create mode 100644 qortal-ui-plugins/plugins/core/names-market/index.html create mode 100644 qortal-ui-plugins/plugins/core/names-market/names-market.src.js diff --git a/qortal-ui-core/src/components/app-view.js b/qortal-ui-core/src/components/app-view.js index 2acd1f14..db343f78 100644 --- a/qortal-ui-core/src/components/app-view.js +++ b/qortal-ui-core/src/components/app-view.js @@ -1516,8 +1516,16 @@ class AppView extends connect(store)(LitElement) { - - + + + + + + + + + + diff --git a/qortal-ui-plugins/build-config.js b/qortal-ui-plugins/build-config.js index fc0a8538..ef988e54 100644 --- a/qortal-ui-plugins/build-config.js +++ b/qortal-ui-plugins/build-config.js @@ -96,6 +96,10 @@ const generateForPlugins = () => { in: 'plugins/core/name-registration/name-registration.src.js', out: 'plugins/core/name-registration/name-registration.js', }, + { + in: 'plugins/core/names-market/names-market.src.js', + out: 'plugins/core/names-market/names-market.js', + }, { in: 'plugins/core/qdn/websites.src.js', out: 'plugins/core/qdn/websites.js', diff --git a/qortal-ui-plugins/plugins/core/main.src.js b/qortal-ui-plugins/plugins/core/main.src.js index 377a1fa6..68de819a 100644 --- a/qortal-ui-plugins/plugins/core/main.src.js +++ b/qortal-ui-plugins/plugins/core/main.src.js @@ -79,6 +79,15 @@ parentEpml.ready().then(() => { menus: [], parent: false, }, + { + url: 'names-market', + domain: 'core', + page: 'names-market/index.html', + title: 'Names Market', + icon: 'vaadin:user-check', + menus: [], + parent: false, + }, { url: 'websites', domain: 'core', diff --git a/qortal-ui-plugins/plugins/core/name-registration/name-registration.src.js b/qortal-ui-plugins/plugins/core/name-registration/name-registration.src.js index 1157a73a..007a66b5 100644 --- a/qortal-ui-plugins/plugins/core/name-registration/name-registration.src.js +++ b/qortal-ui-plugins/plugins/core/name-registration/name-registration.src.js @@ -31,8 +31,6 @@ class NameRegistration extends LitElement { loading: { type: Boolean }, names: { type: Array }, marketSellNames: { type: Array }, - filteredItems: { type: Array }, - searchSellNames: { type: Array }, recipientPublicKey: { type: String }, selectedAddress: { type: Object }, btnDisable: { type: Boolean }, @@ -43,15 +41,13 @@ class NameRegistration extends LitElement { removeError: { type: Boolean }, removeMessage: { type: String }, fee: { type: Number }, + updateFee: { type: Number }, sellFee: { type: Number }, cancelSellFee: { type: Number }, - buyFee: { type: Number }, toSellName: { type: String }, toSellPrice: { type: String }, toCancelSellName: { type: String }, - toBuyName: { type: String }, - toBuyPrice: { type: String }, - toBuySeller: { type: String }, + toUpdateName: { type: String }, errorMessage: { type: String }, successMessage: { type: String } } @@ -126,6 +122,10 @@ class NameRegistration extends LitElement { --mdc-theme-primary: #198754; } + .warning { + --mdc-theme-primary: #f0ad4e; + } + .buttons { text-align: right; } @@ -229,22 +229,18 @@ class NameRegistration extends LitElement { this.selectedAddress = {} this.names = [] this.marketSellNames = [] - this.filteredItems = [] - this.searchSellNames = [] this.recipientPublicKey = '' this.btnDisable = false this.isLoading = false this.registerNameLoading = false this.fee = 0.001 + this.updateFee = 0.001 this.sellFee = 0.001 this.cancelSellFee = 0.001 - this.buyFee = 0.001 this.toSellName = '' + this.toUpdateName = '' this.toSellPrice = '' this.toCancelSellName = '' - this.toBuyName = '' - this.toBuyPrice = '' - this.toBuySeller = '' this.errorMessage = '' this.successMessage = '' } @@ -253,7 +249,7 @@ class NameRegistration extends LitElement { return html`
-

${translate("registernamepage.nchange1")}

+

${translate("sidemenu.sm2")}

this.shadowRoot.querySelector('#registerNameDialog').show()}>add${translate("registernamepage.nchange2")}
@@ -268,6 +264,9 @@ class NameRegistration extends LitElement { { render(html`${this.renderAvatarButton(data.item)}`, root) }}> + { + render(html`${this.renderUpdateNameButton(data.item)}`, root) + }}> { if (this.marketSellNames.some(e => e.owner === this.selectedAddress.address)) { render(html`${this.renderCancelSellNameButton(data.item)}`, root) @@ -280,56 +279,37 @@ class NameRegistration extends LitElement { ${translate("registernamepage.nchange8")} `: ''}
-

-
-

${translate("registernamepage.nchange22")}

- - -
- - - - - { - if (data.item.owner === this.selectedAddress.address) { - render(html`${this.renderCancelSellNameButton(data.item)}`, root) - } else { - render(html`${this.renderBuyNameButton(data.item)}`, root) - } - }}> - -
- ${this.isEmptyArray(this.marketSellNames) ? html` - ${translate("registernamepage.nchange24")} - `: ''} -
-
${translate("registernamepage.nchange9")}
-
- -

- +

+

${translate("registernamepage.nchange9")}

+

+
+

+ + +

+

+ +

- ${translate("registernamepage.nchange11")}   ${translate("registernamepage.nchange13")} ${this.fee} QORT.
-
+ +
+

${translate("publishpage.pchange2")} ${translate("login.name")}

+

+
+

+ + +

+

+ + +

+

+ + +

+
+ + ${this.message} +
+ + ${translate("walletpage.wchange21")} ${this.updateFee} QORT. + +
+ + ${translate("publishpage.pchange2")} ${translate("login.name")} + + + ${translate("general.close")} + +
+
@@ -461,74 +502,6 @@ class NameRegistration extends LitElement { - -
-
-

${translate("registernamepage.nchange21")}

-
-
-
-

- - -

-

- - -

-

- - -

-
-

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

-
-
- ${this.renderClearSuccess()} - ${this.renderClearError()} - ${this.isLoading ? html`` : ''} -
-
- this.openCheckFunds()}> - - ${translate("registernamepage.nchange21")} - -
-
-
- - ${translate("general.close")} - -
-
warning @@ -567,9 +540,9 @@ class NameRegistration extends LitElement { this.changeTheme() this.changeLanguage() this.unitFee() + this.unitUpdateFee() this.unitSellFee() this.unitCancelSellFee() - this.unitBuyFee() const fetchNames = () => { parentEpml.request('apiCall', { @@ -586,7 +559,6 @@ class NameRegistration extends LitElement { }).then(res => { this.marketSellNames = res }) - this.updatePageSize() setTimeout(fetchMarketSellNames, 180000) } @@ -666,103 +638,6 @@ class NameRegistration extends LitElement { } } - async updatePageSize() { - this.filteredItems = [] - this.marketSellNames.sort((a, b) => parseFloat(a.salePrice) - parseFloat(b.salePrice)) - this.filteredItems = this.marketSellNames - await this.setPages() - await this.updateItemsFromPage(1, true) - } - - async setPages() { - this.namesGrid = this.shadowRoot.querySelector(`#marketSellNames`) - this.pagesControl = this.shadowRoot.querySelector('#pages') - this.pages = undefined - } - - async updatePageSizeSearch() { - this.filteredItems = [] - this.searchSellNames.sort((a, b) => parseFloat(a.salePrice) - parseFloat(b.salePrice)) - this.filteredItems = this.searchSellNames - await this.setPagesSearch() - await this.updateItemsFromPage(1, true) - } - - async setPagesSearch() { - this.namesGrid = this.shadowRoot.querySelector(`#marketSellNames`) - this.pagesControl = this.shadowRoot.querySelector('#pages') - this.pages = undefined - } - - async updateItemsFromPage(page, changeNames = false) { - if (page === undefined) { - return - } - - changeNames === true ? (this.pagesControl.innerHTML = '') : null - - if (!this.pages) { - this.pages = Array.apply(null, { length: Math.ceil(this.filteredItems.length / this.namesGrid.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.namesGrid.pageSize - let end = page * this.namesGrid.pageSize - - this.namesGrid.items = this.filteredItems.slice(start, end) - } - async updateQortWalletBalance() { let qortAddress = window.parent.reduxStore.getState().app.selectedAddress.address @@ -815,6 +690,10 @@ class NameRegistration extends LitElement { return html`${translate("registernamepage.nchange18")}` } + renderSuccessUpdateText() { + return html`${translate("registernamepage.nchange47")}` + } + renderSellSuccessText() { return html`${translate("registernamepage.nchange32")}` } @@ -870,6 +749,27 @@ class NameRegistration extends LitElement { this.shadowRoot.getElementById("toSellPrice").value = '' } + renderUpdateNameButton(nameObj) { + return html` this.openUpdateNameDialog(nameObj)}>update ${translate("publishpage.pchange2")} ${translate("login.name")}` + } + + openUpdateNameDialog(nameObj) { + this.toUpdateName = '' + this.shadowRoot.getElementById("oldNameInput").value = '' + this.shadowRoot.getElementById("newNameInput").value = '' + this.shadowRoot.getElementById("newDescInput").value = '' + this.toUpdateName = nameObj.name + this.shadowRoot.querySelector('#updateNameDialog').show() + } + + closeUpdateNameDialog() { + this.shadowRoot.querySelector('#updateNameDialog').close() + this.toUpdateName = '' + this.shadowRoot.getElementById("oldNameInput").value = '' + this.shadowRoot.getElementById("newNameInput").value = '' + this.shadowRoot.getElementById("newDescInput").value = '' + } + renderCancelSellNameButton(nameObj) { return html` this.openCancelSellNameDialog(nameObj)}>cancel ${translate("registernamepage.nchange20")}` } @@ -887,44 +787,6 @@ class NameRegistration extends LitElement { this.shadowRoot.getElementById("toCancelSellName").value = '' } - renderBuyNameButton(nameObj) { - return html` this.openCheck(nameObj)}>shop ${translate("registernamepage.nchange21")}` - } - - openCheck(nameObj) { - const _name = nameObj.name - const _seller = nameObj.owner - const _price = nameObj.salePrice - if (this.isEmptyArray(this.names) === true) { - this.openBuyNameDialog(_name, _seller, _price) - } else { - this.shadowRoot.querySelector('#buyErrorNameDialog').show() - } - } - - openBuyNameDialog(_name, _seller, _price) { - this.toBuyName = '' - this.toBuyPrice = '' - this.toBuySeller = '' - this.shadowRoot.getElementById("toBuyName").value = '' - this.shadowRoot.getElementById("toBuyPrice").value = '' - this.shadowRoot.getElementById("toBuySeller").value = '' - this.toBuyName = _name - this.toBuyPrice = _price - this.toBuySeller = _seller - this.shadowRoot.querySelector('#buyNameDialog').show() - } - - closeBuyNameDialog() { - this.toBuyName = '' - this.toBuyPrice = '' - this.toBuySeller = '' - this.shadowRoot.getElementById("toBuyName").value = '' - this.shadowRoot.getElementById("toBuyPrice").value = '' - this.shadowRoot.getElementById("toBuySeller").value = '' - this.shadowRoot.querySelector('#buyNameDialog').close() - } - async openCheckFunds() { await this.updateQortWalletBalance() @@ -960,6 +822,20 @@ class NameRegistration extends LitElement { }) } + async unitUpdateFee() { + 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=UPDATE_NAME` + await fetch(url).then((response) => { + if (response.ok) { + return response.json() + } + return Promise.reject(response) + }).then((json) => { + this.updateFee = (Number(json) / 1e8).toFixed(8) + }) + } + async unitSellFee() { const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port @@ -988,20 +864,6 @@ class NameRegistration extends LitElement { }) } - async unitBuyFee() { - 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=BUY_NAME` - await fetch(url).then((response) => { - if (response.ok) { - return response.json() - } - return Promise.reject(response) - }).then((json) => { - this.buyFee = (Number(json) / 1e8).toFixed(8) - }) - } - getApiKey() { const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] let apiKey = myNode.apiKey @@ -1042,8 +904,8 @@ class NameRegistration extends LitElement { }; const validateReceiver = async () => { - let nameInfo = await validateName(); - let lastRef = await getLastRef(); + let nameInfo = await validateName() + let lastRef = await getLastRef() if (nameInfo.error === 401) { this.error = false @@ -1095,6 +957,92 @@ class NameRegistration extends LitElement { this.registerNameLoading = false } + async updateName() { + this.error = false + this.message = '' + const updateFeeInput = this.updateFee + const oldNameInput = this.shadowRoot.getElementById("oldNameInput").value + const newNameInput = this.shadowRoot.getElementById("newNameInput").value + const newDescInput = this.shadowRoot.getElementById("newDescInput").value + + // Get Last Ref + const getLastRef = async () => { + let myRef = await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/lastreference/${this.selectedAddress.address}` + }) + return myRef + } + + // Get Account Details + const validateName = async () => { + let isValid = await parentEpml.request('apiCall', { + type: 'api', + url: `/names/${newNameInput}` + }) + return isValid + } + + const validateReceiver = async () => { + let nameInfo = await validateName() + let lastRef = await getLastRef() + + if (nameInfo.error === 401) { + this.error = false + this.message = '' + let myTransaction = await makeTransactionRequest(lastRef) + getTxnRequestResponse(myTransaction) + } else { + this.error = true + this.message = this.renderFailText() + } + } + + // Make Transaction Request + const makeTransactionRequest = async (lastRef) => { + const myOldName = oldNameInput + const myNewName = newNameInput + const myNewDesc = newDescInput + const myLastRef = lastRef + const myFee = updateFeeInput + let dialogUpdateName1 = get("registernamepage.nchange43") + let dialogUpdateName2 = get("registernamepage.nchange44") + let dialogUpdateName3 = get("registernamepage.nchange45") + let myTxnrequest = await parentEpml.request('transaction', { + type: 4, + nonce: this.selectedAddress.nonce, + params: { + fee: myFee, + name: myOldName, + newName: myNewName, + newData: myNewDesc, + lastReference: myLastRef, + dialogUpdateName1: dialogUpdateName1, + dialogUpdateName2: dialogUpdateName2, + dialogUpdateName3: dialogUpdateName3 + } + }) + return myTxnrequest + } + + const getTxnRequestResponse = (txnResponse) => { + if (txnResponse.success === false && txnResponse.message) { + this.error = true + this.message = txnResponse.message + throw new Error(txnResponse) + } else if (txnResponse.success === true && !txnResponse.data.error) { + this.message = this.renderSuccessUpdateText() + this.error = false + } else { + this.error = true + this.message = txnResponse.data.message + throw new Error(txnResponse) + } + } + + validateReceiver() + } + async createSellName() { const name = this.shadowRoot.getElementById("toSellName").value const price = this.shadowRoot.getElementById("toSellPrice").value @@ -1230,82 +1178,6 @@ class NameRegistration extends LitElement { validateReceiver() } - createBuyName() { - const name = this.shadowRoot.getElementById("toBuyName").value - const price = this.shadowRoot.getElementById("toBuyPrice").value - const seller = this.shadowRoot.getElementById("toBuySeller").value - const buyFeeInput = this.buyFee - this.isLoading = true - this.btnDisable = true - - const getLastRef = async () => { - let myRef = await parentEpml.request('apiCall', { - type: 'api', - url: `/addresses/lastreference/${this.selectedAddress.address}` - }) - return myRef - } - - const validateReceiver = async () => { - let lastRef = await getLastRef() - let myTransaction = await makeTransactionRequest(lastRef) - getTxnRequestResponse(myTransaction) - } - - const makeTransactionRequest = async (lastRef) => { - const myName = name - const myPrice = price - const mySeller = seller - const myLastRef = lastRef - const myFee = buyFeeInput - const myBuyNameDialog1 = get("registernamepage.nchange39") - const myBuyNameDialog2 = get("registernamepage.nchange27") - const myBuyNameDialog3 = get("registernamepage.nchange40") - - let myTxnrequest = await parentEpml.request('transaction', { - type: 7, - nonce: this.selectedAddress.nonce, - params: { - fee: myFee, - name: myName, - sellPrice: myPrice, - recipient: mySeller, - lastReference: myLastRef, - buyNameDialog1: myBuyNameDialog1, - buyNameDialog2: myBuyNameDialog2, - buyNameDialog3: myBuyNameDialog3 - } - }) - return myTxnrequest - } - - const getTxnRequestResponse = (txnResponse) => { - if (txnResponse.success === false && txnResponse.message) { - this.errorMessage = txnResponse.message - this.isLoading = false - this.btnDisable = false - throw new Error(txnResponse) - } else if (txnResponse.success === true && !txnResponse.data.error) { - this.shadowRoot.getElementById("toBuyName").value = '' - this.shadowRoot.getElementById("toBuyPrice").value = '' - this.shadowRoot.getElementById("toBuySeller").value = '' - this.toBuyName = '' - this.toBuyPrice = '' - this.toBuySeller = '' - this.errorMessage = '' - this.successMessage = this.renderBuySuccessText() - this.isLoading = false - this.btnDisable = false - } else { - this.errorMessage = txnResponse.data.message - this.isLoading = false - this.btnDisable = false - throw new Error(txnResponse) - } - } - validateReceiver() - } - _textMenu(event) { const getSelectedText = () => { diff --git a/qortal-ui-plugins/plugins/core/names-market/index.html b/qortal-ui-plugins/plugins/core/names-market/index.html new file mode 100644 index 00000000..a248d03a --- /dev/null +++ b/qortal-ui-plugins/plugins/core/names-market/index.html @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/qortal-ui-plugins/plugins/core/names-market/names-market.src.js b/qortal-ui-plugins/plugins/core/names-market/names-market.src.js new file mode 100644 index 00000000..c06534f5 --- /dev/null +++ b/qortal-ui-plugins/plugins/core/names-market/names-market.src.js @@ -0,0 +1,1211 @@ +import { LitElement, html, css } from 'lit' +import { render } from 'lit/html.js' +import { Epml } from '../../../epml.js' +import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate' +import '../components/qortal-info-view.js' +registerTranslateConfig({ + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) +}) + +import '@material/mwc-button' +import '@material/mwc-dialog' +import '@material/mwc-formfield' +import '@material/mwc-icon' +import '@material/mwc-icon-button' +import '@material/mwc-tab-bar' +import '@material/mwc-textfield' +import '@polymer/paper-spinner/paper-spinner-lite.js' +import '@polymer/paper-progress/paper-progress.js' +import '@vaadin/button' +import '@vaadin/icon' +import '@vaadin/icons' +import '@vaadin/grid' +import '@vaadin/text-field' + +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + +class NamesMarket extends LitElement { + static get properties() { + return { + theme: { type: String, reflect: true }, + qortWalletBalance: { type: Number }, + loading: { type: Boolean }, + marketSellNames: { type: Array }, + marketSoldNames: { type: Array }, + filteredItems: { type: Array }, + filteredSoldItems: { type: Array }, + searchSellNames: { type: Array }, + recipientPublicKey: { type: String }, + selectedAddress: { type: Object }, + btnDisable: { type: Boolean }, + isLoading: { type: Boolean }, + error: { type: Boolean }, + message: { type: String }, + removeError: { type: Boolean }, + removeMessage: { type: String }, + cancelSellFee: { type: Number }, + buyFee: { type: Number }, + toCancelSellName: { type: String }, + toBuyName: { type: String }, + toBuyPrice: { type: String }, + toBuySeller: { type: String }, + errorMessage: { type: String }, + successMessage: { type: String } + } + } + + static get styles() { + return css` + * { + --mdc-theme-primary: rgb(3, 169, 244); + --paper-input-container-focus-color: var(--mdc-theme-primary); + --mdc-theme-surface: var(--white); + --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-dialog-content-ink-color: var(--black); + --mdc-dialog-min-width: 400px; + --mdc-dialog-max-width: 1024px; + --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); + } + + [hidden] { + display: hidden !important; + visibility: none !important; + } + + #name-registration-page { + background: var(--white); + padding: 12px 24px; + } + + .divCard { + border: 1px solid var(--border); + padding: 1em; + box-shadow: 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.20); + margin-bottom: 10px; + margin-top: 10px; + } + + h2 { + margin:0; + } + + h2, h3, h4, h5 { + color: var(--black); + font-weight: 400; + } + + img { + border-radius: 25%; + max-width: 42px; + height: 100%; + max-height: 42px; + } + + #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-progress { + --paper-progress-active-color: var(--mdc-theme-primary); + } + + .red { + --mdc-theme-primary: #F44336; + } + + .green { + --mdc-theme-primary: #198754; + } + + .warning { + --mdc-theme-primary: #f0ad4e; + } + + .sellerAddress { + color: var(--mdc-theme-primary); + cursor: pointer; + } + + .buyerAddress { + color: #198754; + cursor: pointer; + } + + .sold { + color: #F44336; + --mdc-icon-size: 16px; + padding-top: 10px; + } + + .buttons { + text-align: right; + } + + #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; + } + + #pagesSold { + display: flex; + flex-wrap: wrap; + padding: 10px 5px 5px 5px; + margin: 0px 20px 20px 20px; + } + + #pagesSold > 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); + } + + #pagesSold > button:not([disabled]):hover, + #pagesSold > button:focus { + color: #ccc; + background-color: #eee; + } + + #pagesSold > button[selected] { + font-weight: bold; + color: var(--white); + background-color: #ccc; + } + + #pagesSold > button[disabled] { + opacity: 0.5; + cursor: default; + } + + .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; + } + + .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; + } + + .manage-group-dialog { + min-height: 300px; + min-width: 350px; + 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; + } + + .error-icon { + font-size: 48px; + color: red; + } + ` + } + + constructor() { + super() + this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' + this.qortWalletBalance = 0 + this.selectedAddress = {} + this.marketSellNames = [] + this.marketSoldNames = [] + this.filteredItems = [] + this.filteredSoldItems = [] + this.searchSellNames = [] + this.recipientPublicKey = '' + this.btnDisable = false + this.isLoading = false + this.cancelSellFee = 0.001 + this.buyFee = 0.001 + this.toCancelSellName = '' + this.toBuyName = '' + this.toBuyPrice = '' + this.toBuySeller = '' + this.errorMessage = '' + this.successMessage = '' + } + + render() { + return html` +
+ + + + + +
+
+
+ + +
+ + + { + render(html` this.openSellerInfo(data.item.owner)}>${data.item.owner}`, root) + }}> + + { + if (data.item.owner === this.selectedAddress.address) { + render(html`${this.renderCancelSellNameButton(data.item)}`, root) + } else { + render(html`${this.renderBuyNameButton(data.item)}`, root) + } + }}> + +
+ ${this.isEmptyArray(this.marketSellNames) ? html` + ${translate("registernamepage.nchange24")} + `: ''} +
+
+
+
+ + + { + render(html` this.openSellerInfo(data.item.seller)}>${data.item.seller}`, root) + }}> + { + render(html` this.openSellerInfo(data.item.creatorAddress)}>${data.item.creatorAddress}`, root) + }}> + + { + render(html`sell ${translate("tradepage.tchange31")}`, root) + }}> + +
+ ${this.isEmptyArray(this.marketSoldNames) ? html` + ${translate("registernamepage.nchange24")} + `: ''} +
+
+
+ + +
+
+

${translate("registernamepage.nchange20")} ${translate("registernamepage.nchange5")}

+
+
+
+

+ + +

+
+

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

+
+
+ ${this.renderClearSuccess()} + ${this.renderClearError()} + ${this.isLoading ? html`` : ''} +
+
+ this.createCancelSellName()}> + + ${translate("registernamepage.nchange20")} ${translate("registernamepage.nchange5")} + +
+
+
+ + ${translate("general.close")} + +
+ + +
+
+

${translate("registernamepage.nchange21")}

+
+
+
+

+ + +

+

+ + +

+

+ + +

+
+

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

+
+
+ ${this.renderClearSuccess()} + ${this.renderClearError()} + ${this.isLoading ? html`` : ''} +
+
+ this.openCheckFunds()}> + + ${translate("registernamepage.nchange21")} + +
+
+
+ + ${translate("general.close")} + +
+ + +
+ warning +

${translate("registernamepage.nchange35")}

+

${translate("registernamepage.nchange36")}

+
+ this.closeBuyErrorNameDialog()} + class="red" + > + ${translate("general.close")} + +
+ + +
+ warning +

${translate("registernamepage.nchange37")}

+

${translate("registernamepage.nchange38")}

+
+ this.closeBuyErrorPriceDialog()} + class="red" + > + ${translate("general.close")} + +
+
+ + ` + } + + firstUpdated() { + + this.changeTheme() + this.changeLanguage() + this.unitCancelSellFee() + this.unitBuyFee() + + setTimeout(() => { + this.displayTabContent('sell') + }, 0) + + const fetchMarketSellNames = async () => { + await parentEpml.request('apiCall', { + url: `/names/forsale?limit=0&reverse=true` + }).then(res => { + this.marketSellNames = res + }) + this.updatePageSize() + setTimeout(fetchMarketSellNames, 180000) + } + + const fetchMarketSoldNames = async () => { + await parentEpml.request('apiCall', { + url: `/transactions/search?txType=BUY_NAME&confirmationStatus=BOTH&limit=0&reverse=true` + }).then(res => { + this.marketSoldNames = res + }) + this.updatePageSoldSize() + setTimeout(fetchMarketSoldNames, 300000) + } + + window.addEventListener("contextmenu", (event) => { + event.preventDefault() + this._textMenu(event) + }) + + window.addEventListener("click", () => { + parentEpml.request('closeCopyTextMenu', null) + }) + + 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) + }) + + window.onkeyup = (e) => { + if (e.keyCode === 27) { + parentEpml.request('closeCopyTextMenu', null) + } + } + + 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(fetchMarketSellNames, 1) + setTimeout(fetchMarketSoldNames, 1) + configLoaded = true + } + this.config = JSON.parse(c) + }) + parentEpml.subscribe('copy_menu_switch', async value => { + if (value === 'false' && window.getSelection().toString().length !== 0) { + this.clearSelection() + } + }) + }) + parentEpml.imReady() + } + + displayTabContent(tab) { + const tabSellContent = this.shadowRoot.getElementById('tab-sell-content') + const tabSoldContent = this.shadowRoot.getElementById('tab-sold-content') + tabSellContent.style.display = (tab === 'sell') ? 'block' : 'none' + tabSoldContent.style.display = (tab === 'sold') ? 'block' : 'none' + } + + 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) + } + } + + async updatePageSize() { + this.filteredItems = [] + this.marketSellNames.sort((a, b) => parseFloat(a.salePrice) - parseFloat(b.salePrice)) + this.filteredItems = this.marketSellNames + await this.setPages() + await this.updateItemsFromPage(1, true) + } + + async setPages() { + this.namesGrid = this.shadowRoot.querySelector(`#marketSellNames`) + this.pagesControl = this.shadowRoot.querySelector('#pages') + this.pages = undefined + } + + async updatePageSizeSearch() { + this.filteredItems = [] + this.searchSellNames.sort((a, b) => parseFloat(a.salePrice) - parseFloat(b.salePrice)) + this.filteredItems = this.searchSellNames + await this.setPagesSearch() + await this.updateItemsFromPage(1, true) + } + + async setPagesSearch() { + this.namesGrid = this.shadowRoot.querySelector(`#marketSellNames`) + this.pagesControl = this.shadowRoot.querySelector('#pages') + this.pages = undefined + } + + async updatePageSoldSize() { + this.filteredSoldItems = [] + this.marketSoldNames.sort((a, b) => parseFloat(a.amount) - parseFloat(b.amount)) + this.filteredSoldItems = this.marketSoldNames + await this.setSoldPages() + await this.updateItemsSoldFromPage(1, true) + } + + async setSoldPages() { + this.namesSoldGrid = this.shadowRoot.querySelector(`#marketSoldNames`) + this.pagesSoldControl = this.shadowRoot.querySelector('#pagesSold') + this.soldPages = undefined + } + + async updateItemsFromPage(page, changeNames = false) { + if (page === undefined) { + return + } + + changeNames === true ? (this.pagesControl.innerHTML = '') : null + + if (!this.pages) { + this.pages = Array.apply(null, { length: Math.ceil(this.filteredItems.length / this.namesGrid.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.namesGrid.pageSize + let end = page * this.namesGrid.pageSize + + this.namesGrid.items = this.filteredItems.slice(start, end) + } + + async updateItemsSoldFromPage(pageSold, changeSoldNames = false) { + if (pageSold === undefined) { + return + } + + changeSoldNames === true ? (this.pagesSoldControl.innerHTML = '') : null + + if (!this.soldPages) { + this.soldPages = Array.apply(null, { length: Math.ceil(this.filteredSoldItems.length / this.namesSoldGrid.pageSize) }).map((item, index) => { + return index + 1 + }) + + const prevBtn = document.createElement('button') + prevBtn.textContent = '<' + prevBtn.addEventListener('click', () => { + const selectedPage = parseInt(this.pagesSoldControl.querySelector('[selected]').textContent) + this.updateItemsSoldFromPage(selectedPage - 1) + }) + this.pagesSoldControl.appendChild(prevBtn) + + this.soldPages.forEach((pageNumber) => { + const pageBtn = document.createElement('button') + pageBtn.textContent = pageNumber + pageBtn.addEventListener('click', (e) => { + this.updateItemsSoldFromPage(parseInt(e.target.textContent)) + }) + if (pageNumber === pageSold) { + pageBtn.setAttribute('selected', true) + } + this.pagesSoldControl.appendChild(pageBtn) + }) + + const nextBtn = window.document.createElement('button') + nextBtn.textContent = '>' + nextBtn.addEventListener('click', () => { + const selectedPage = parseInt(this.pagesSoldControl.querySelector('[selected]').textContent) + this.updateItemsSoldFromPage(selectedPage + 1) + }) + this.pagesSoldControl.appendChild(nextBtn) + } + + const buttons = Array.from(this.pagesSoldControl.children) + + buttons.forEach((btn, index) => { + if (parseInt(btn.textContent) === pageSold) { + btn.setAttribute('selected', true) + } else { + btn.removeAttribute('selected') + } + if (index === 0) { + if (pageSold === 1) { + btn.setAttribute('disabled', '') + } else { + btn.removeAttribute('disabled') + } + } + if (index === buttons.length - 1) { + if (pageSold === this.soldPages.length) { + btn.setAttribute('disabled', '') + } else { + btn.removeAttribute('disabled') + } + } + }) + let start = (pageSold - 1) * this.namesSoldGrid.pageSize + let end = pageSold * this.namesSoldGrid.pageSize + + this.namesSoldGrid.items = this.filteredSoldItems.slice(start, end) + } + + async updateQortWalletBalance() { + let qortAddress = window.parent.reduxStore.getState().app.selectedAddress.address + + await parentEpml.request('apiCall', { + url: `/addresses/balance/${qortAddress}`, + }).then((res) => { + this.qortWalletBalance = res + }) + } + + 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")}

+
+ ` + } + } + + renderCoreText() { + return html`${translate("registernamepage.nchange16")}` + } + + renderSuccessText() { + return html`${translate("registernamepage.nchange18")}` + } + + renderSuccessUpdateText() { + return html`${translate("registernamepage.nchange47")}` + } + + renderSellSuccessText() { + return html`${translate("registernamepage.nchange32")}` + } + + renderCancelSuccessText() { + return html`${translate("registernamepage.nchange33")}` + } + + renderBuySuccessText() { + return html`${translate("registernamepage.nchange34")}` + } + + renderFailText() { + return html`${translate("registernamepage.nchange17")}` + } + + renderAvatar(nameObj) { + let name = nameObj.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&apiKey=${this.getApiKey()}` + return html`` + } + + renderCancelSellNameButton(nameObj) { + return html` this.openCancelSellNameDialog(nameObj)}>cancel ${translate("registernamepage.nchange20")}` + } + + openCancelSellNameDialog(nameObj) { + this.toCancelSellName = '' + this.shadowRoot.getElementById("toCancelSellName").value = '' + this.toCancelSellName = nameObj.name + this.shadowRoot.querySelector('#cancelSellNameDialog').show() + } + + closeCancelSellNameDialog() { + this.shadowRoot.querySelector('#cancelSellNameDialog').close() + this.toCancelSellName = '' + this.shadowRoot.getElementById("toCancelSellName").value = '' + } + + renderBuyNameButton(nameObj) { + return html` this.openCheck(nameObj)}>shop ${translate("registernamepage.nchange21")}` + } + + openCheck(nameObj) { + const _name = nameObj.name + const _seller = nameObj.owner + const _price = nameObj.salePrice + if (this.isEmptyArray(this.names) === true) { + this.openBuyNameDialog(_name, _seller, _price) + } else { + this.shadowRoot.querySelector('#buyErrorNameDialog').show() + } + } + + openBuyNameDialog(_name, _seller, _price) { + this.toBuyName = '' + this.toBuyPrice = '' + this.toBuySeller = '' + this.shadowRoot.getElementById("toBuyName").value = '' + this.shadowRoot.getElementById("toBuyPrice").value = '' + this.shadowRoot.getElementById("toBuySeller").value = '' + this.toBuyName = _name + this.toBuyPrice = _price + this.toBuySeller = _seller + this.shadowRoot.querySelector('#buyNameDialog').show() + } + + closeBuyNameDialog() { + this.toBuyName = '' + this.toBuyPrice = '' + this.toBuySeller = '' + this.shadowRoot.getElementById("toBuyName").value = '' + this.shadowRoot.getElementById("toBuyPrice").value = '' + this.shadowRoot.getElementById("toBuySeller").value = '' + this.shadowRoot.querySelector('#buyNameDialog').close() + } + + async openCheckFunds() { + await this.updateQortWalletBalance() + + const myFunds = this.round(parseFloat(this.qortWalletBalance)) + const myBuyPrice = this.round(parseFloat(this.toBuyPrice)) + + if (Number(myFunds) < Number(myBuyPrice)) { + this.shadowRoot.querySelector('#buyErrorPriceDialog').show() + } else { + this.createBuyName() + } + } + + openSellerInfo(address) { + let sendInfoAddress = address + const infoDialog = this.shadowRoot.querySelector('qortal-info-view') + infoDialog.openUserInfo(sendInfoAddress) + } + + closeBuyErrorNameDialog() { + this.shadowRoot.querySelector('#buyErrorNameDialog').close() + } + + closeBuyErrorPriceDialog() { + this.shadowRoot.querySelector('#buyErrorPriceDialog').close() + } + + async unitCancelSellFee() { + 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=CANCEL_SELL_NAME` + await fetch(url).then((response) => { + if (response.ok) { + return response.json() + } + return Promise.reject(response) + }).then((json) => { + this.cancelSellFee = (Number(json) / 1e8).toFixed(8) + }) + } + + async unitBuyFee() { + 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=BUY_NAME` + await fetch(url).then((response) => { + if (response.ok) { + return response.json() + } + return Promise.reject(response) + }).then((json) => { + this.buyFee = (Number(json) / 1e8).toFixed(8) + }) + } + + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + let apiKey = myNode.apiKey + return apiKey + } + + clearSelection() { + window.getSelection().removeAllRanges() + window.parent.getSelection().removeAllRanges() + } + + async createCancelSellName() { + const name = this.shadowRoot.getElementById("toCancelSellName").value + const cancelSellFeeInput = this.cancelSellFee + this.isLoading = true + this.btnDisable = true + + const getLastRef = async () => { + let myRef = await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/lastreference/${this.selectedAddress.address}` + }) + return myRef + } + + const validateReceiver = async () => { + let lastRef = await getLastRef() + let myTransaction = await makeTransactionRequest(lastRef) + getTxnRequestResponse(myTransaction) + } + + const makeTransactionRequest = async (lastRef) => { + const myName = name + const myLastRef = lastRef + const myFee = cancelSellFeeInput + const myCancelSellNameDialog1 = get("registernamepage.nchange30") + const myCancelSellNameDialog2 = get("registernamepage.nchange31") + + let myTxnrequest = await parentEpml.request('transaction', { + type: 6, + nonce: this.selectedAddress.nonce, + params: { + fee: myFee, + name: myName, + lastReference: myLastRef, + cancelSellNameDialog1: myCancelSellNameDialog1, + cancelSellNameDialog2: myCancelSellNameDialog2 + } + }) + return myTxnrequest + } + + const getTxnRequestResponse = (txnResponse) => { + if (txnResponse.success === false && txnResponse.message) { + this.errorMessage = txnResponse.message + this.isLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } else if (txnResponse.success === true && !txnResponse.data.error) { + this.shadowRoot.getElementById("toCancelSellName").value = '' + this.toCancelSellName = '' + this.errorMessage = '' + this.successMessage = this.renderCancelSuccessText() + this.isLoading = false + this.btnDisable = false + } else { + this.errorMessage = txnResponse.data.message + this.isLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } + } + validateReceiver() + } + + createBuyName() { + const name = this.shadowRoot.getElementById("toBuyName").value + const price = this.shadowRoot.getElementById("toBuyPrice").value + const seller = this.shadowRoot.getElementById("toBuySeller").value + const buyFeeInput = this.buyFee + this.isLoading = true + this.btnDisable = true + + const getLastRef = async () => { + let myRef = await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/lastreference/${this.selectedAddress.address}` + }) + return myRef + } + + const validateReceiver = async () => { + let lastRef = await getLastRef() + let myTransaction = await makeTransactionRequest(lastRef) + getTxnRequestResponse(myTransaction) + } + + const makeTransactionRequest = async (lastRef) => { + const myName = name + const myPrice = price + const mySeller = seller + const myLastRef = lastRef + const myFee = buyFeeInput + const myBuyNameDialog1 = get("registernamepage.nchange39") + const myBuyNameDialog2 = get("registernamepage.nchange27") + const myBuyNameDialog3 = get("registernamepage.nchange40") + + let myTxnrequest = await parentEpml.request('transaction', { + type: 7, + nonce: this.selectedAddress.nonce, + params: { + fee: myFee, + name: myName, + sellPrice: myPrice, + recipient: mySeller, + lastReference: myLastRef, + buyNameDialog1: myBuyNameDialog1, + buyNameDialog2: myBuyNameDialog2, + buyNameDialog3: myBuyNameDialog3 + } + }) + return myTxnrequest + } + + const getTxnRequestResponse = (txnResponse) => { + if (txnResponse.success === false && txnResponse.message) { + this.errorMessage = txnResponse.message + this.isLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } else if (txnResponse.success === true && !txnResponse.data.error) { + this.shadowRoot.getElementById("toBuyName").value = '' + this.shadowRoot.getElementById("toBuyPrice").value = '' + this.shadowRoot.getElementById("toBuySeller").value = '' + this.toBuyName = '' + this.toBuyPrice = '' + this.toBuySeller = '' + this.errorMessage = '' + this.successMessage = this.renderBuySuccessText() + this.isLoading = false + this.btnDisable = false + } else { + this.errorMessage = txnResponse.data.message + this.isLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } + } + validateReceiver() + } + + _textMenu(event) { + + const getSelectedText = () => { + var text = "" + if (typeof window.getSelection != "undefined") { + text = window.getSelection().toString() + } else if (typeof this.shadowRoot.selection != "undefined" && this.shadowRoot.selection.type == "Text") { + text = this.shadowRoot.selection.createRange().text + } + return text + } + + const checkSelectedTextAndShowMenu = () => { + let selectedText = getSelectedText(); + if (selectedText && typeof selectedText === 'string') { + + let _eve = { pageX: event.pageX, pageY: event.pageY, clientX: event.clientX, clientY: event.clientY } + + let textMenuObject = { selectedText: selectedText, eventObject: _eve, isFrame: true } + + parentEpml.request('openCopyTextMenu', textMenuObject) + } + } + checkSelectedTextAndShowMenu() + } + + round(number) { + let result = (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + return result + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } +} + +window.customElements.define('names-market', NamesMarket) \ No newline at end of file