Add trade information

This commit is contained in:
AlphaX-Projects 2023-12-10 11:18:17 +01:00
parent 42135ea79a
commit 2996f7122d
3 changed files with 1476 additions and 462 deletions

View File

@ -0,0 +1,629 @@
import {css} from 'lit'
export const tradeInfoViewStyle = 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;
}
p {
margin-top: 0;
margin-bottom: 1rem;
color: var(--black);
}
p {
margin: 0;
padding: 0;
color: var(--black);
}
.card {
position: relative;
display: flex;
flex-direction: column;
min-width: 0;
height: calc(100% - 1rem);
word-wrap: break-word;
background-color: var(--white);
background-clip: border-box;
margin-bottom: 1rem;
}
.card-header {
padding: 0.5rem 1rem;
margin-bottom: 0;
background-color: rgba(0, 0, 0, 0.03);
border-bottom: 2px solid rgba(0, 0, 0, 0.125);
}
.card-header {
background: none;
border-width: 0;
padding: 10px;
padding-bottom: 0rem;
}
.card-title {
font-size: 1.2rem;
color: var(--black);
margin-bottom: 0.5rem;
}
.card-body {
flex: 1 1 auto;
padding: 1rem 1rem;
}
.card-body {
padding: 20px;
}
.d-sm-flex {
display: flex !important;
}
.align-items-center {
align-items: center !important;
}
.justify-content-between {
justify-content: space-between !important;
}
.d-flex {
display: flex !important;
}
.mb-3 {
margin-bottom: 1rem !important;
}
.cwh-64 {
width: 64px !important;
height: 64px !important;
}
.cwh-80 {
width: 80px !important;
height: 80px !important;
}
.rounded {
border-radius: 25% !important;
}
.ms-3 {
margin-left: 1rem !important;
}
.cfs-12 {
font-size: 12px !important;
}
.cfs-14 {
font-size: 14px !important;
}
.cfs-16 {
font-size: 16px !important;
}
.cfs-18 {
font-size: 18px !important;
}
.me-sm-3 {
margin-right: 1rem !important;
}
.ms-sm-0 {
margin-left: 0 !important;
}
.text-sm-end {
text-align: right !important;
}
.order-0 {
order: 0 !important;
}
.order-1 {
order: 1 !important;
}
.order-sm-0 {
order: 0 !important;
}
.order-sm-1 {
order: 1 !important;
}
.decline {
--mdc-theme-primary: var(--mdc-theme-error)
}
.warning {
--mdc-theme-primary: #f0ad4e;
}
.red {
color: #F44336;
}
.green {
color: #198754;
}
.buttons {
display: inline;
float: right;
margin-bottom: 5px;
}
.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;
}
@-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);
}
}
table {
caption-side: bottom;
border-collapse: collapse;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #6c757d;
text-align: left;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
.table {
--bs-table-bg: transparent;
--bs-table-striped-color: #212529;
--bs-table-striped-bg: rgba(255, 255, 255, 0.2);
--bs-table-active-color: #212529;
--bs-table-active-bg: rgba(0, 0, 0, 0.1);
--bs-table-hover-color: #212529;
--bs-table-hover-bg: rgba(0, 0, 0, 0.075);
width: 100%;
margin-bottom: 1rem;
color: var(--black);
vertical-align: top;
border-color: #edeff4;
}
.table> :not(caption)>*>* {
padding: 0.75rem 0.75rem;
background-color: var(--bs-table-bg);
background-image: linear-gradient(var(--bs-table-accent-bg), var(--bs-table-accent-bg));
border-bottom-width: 2px;
}
.table>tbody {
vertical-align: inherit;
}
.table>thead {
vertical-align: bottom;
}
.table> :not(:last-child)> :last-child>* {
border-bottom-color: currentColor;
}
.caption-top {
caption-side: top;
}
.table-sm> :not(caption)>*>* {
padding: 0.5rem 0.5rem;
}
.table-bordered> :not(caption)>* {
border-width: 2px 0;
}
.table-bordered> :not(caption)>*>* {
border-width: 0 2px;
}
.table-borderless> :not(caption)>*>* {
border-bottom-width: 0;
}
.table-striped>tbody>tr:nth-of-type(odd) {
--bs-table-accent-bg: var(--bs-table-striped-bg);
color: var(--black);
}
.table-active {
--bs-table-accent-bg: var(--bs-table-active-bg);
color: var(--bs-table-active-color);
}
.table-hover>tbody>tr:hover {
--bs-table-accent-bg: var(--bs-table-hover-bg);
color: var(--bs-table-hover-color);
}
.table-primary {
--bs-table-bg: #cfe2ff;
--bs-table-striped-bg: #c5d7f2;
--bs-table-striped-color: #000;
--bs-table-active-bg: #bacbe6;
--bs-table-active-color: #000;
--bs-table-hover-bg: #bfd1ec;
--bs-table-hover-color: #000;
color: #000;
border-color: #bacbe6;
}
.table-secondary {
--bs-table-bg: #e2e3e5;
--bs-table-striped-bg: #d7d8da;
--bs-table-striped-color: #000;
--bs-table-active-bg: #cbccce;
--bs-table-active-color: #000;
--bs-table-hover-bg: #d1d2d4;
--bs-table-hover-color: #000;
color: #000;
border-color: #cbccce;
}
.table-success {
--bs-table-bg: #e1f5d4;
--bs-table-striped-bg: #d6e9c9;
--bs-table-striped-color: #000;
--bs-table-active-bg: #cbddbf;
--bs-table-active-color: #000;
--bs-table-hover-bg: #d0e3c4;
--bs-table-hover-color: #000;
color: #000;
border-color: #cbddbf;
}
.table-info {
--bs-table-bg: #cff4fc;
--bs-table-striped-bg: #c5e8ef;
--bs-table-striped-color: #000;
--bs-table-active-bg: #badce3;
--bs-table-active-color: #000;
--bs-table-hover-bg: #bfe2e9;
--bs-table-hover-color: #000;
color: #000;
border-color: #badce3;
}
.table-warning {
--bs-table-bg: #fff3cd;
--bs-table-striped-bg: #f2e7c3;
--bs-table-striped-color: #000;
--bs-table-active-bg: #e6dbb9;
--bs-table-active-color: #000;
--bs-table-hover-bg: #ece1be;
--bs-table-hover-color: #000;
color: #000;
border-color: #e6dbb9;
}
.table-danger {
--bs-table-bg: #f8d7da;
--bs-table-striped-bg: #eccccf;
--bs-table-striped-color: #000;
--bs-table-active-bg: #dfc2c4;
--bs-table-active-color: #000;
--bs-table-hover-bg: #e5c7ca;
--bs-table-hover-color: #000;
color: #000;
border-color: #dfc2c4;
}
.table-light {
--bs-table-bg: #f8f9fa;
--bs-table-striped-bg: #ecedee;
--bs-table-striped-color: #000;
--bs-table-active-bg: #dfe0e1;
--bs-table-active-color: #000;
--bs-table-hover-bg: #e5e6e7;
--bs-table-hover-color: #000;
color: #000;
border-color: #dfe0e1;
}
.table-dark {
--bs-table-bg: #212529;
--bs-table-striped-bg: #2c3034;
--bs-table-striped-color: #fff;
--bs-table-active-bg: #373b3e;
--bs-table-active-color: #fff;
--bs-table-hover-bg: #323539;
--bs-table-hover-color: #fff;
color: #fff;
border-color: #373b3e;
}
.table-responsive {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
@media (max-width: 359.98px) {
.table-responsive-xxs {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
}
@media (max-width: 499.98px) {
.table-responsive-xsm {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
}
@media (max-width: 575.98px) {
.table-responsive-sm {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
}
@media (max-width: 767.98px) {
.table-responsive-md {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
}
@media (max-width: 991.98px) {
.table-responsive-lg {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
}
@media (max-width: 1199.98px) {
.table-responsive-xl {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
}
@media (max-width: 1399.98px) {
.table-responsive-xxl {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
}
th {
font-weight: 500;
}
tbody::-webkit-scrollbar,
tbody::-webkit-scrollbar-thumb,
tbody::-webkit-scrollbar-track {
opacity: 0;
width: 5px;
border-radius: 6px;
position: absolute;
right: 0;
top: 0;
}
tbody:hover::-webkit-scrollbar,
tbody:hover::-webkit-scrollbar-thumb,
tbody:hover::-webkit-scrollbar-track {
opacity: 0.9;
width: 5px;
border-radius: 6px;
right: 2px;
position: absolute;
transition: background-color 0.2s linear, width 0.2s ease-in-out;
}
tbody:hover::-webkit-scrollbar-thumb {
background-color: #eee;
}
.mt-0 {
margin-top: 0 !important;
}
.mt-1 {
margin-top: 0.25rem !important;
}
.mt-2 {
margin-top: 0.5rem !important;
}
.mt-3 {
margin-top: 1rem !important;
}
.mt-4 {
margin-top: 1.5rem !important;
}
.mt-5 {
margin-top: 3rem !important;
}
.mt-auto {
margin-top: auto !important;
}
.w-25 {
width: 25% !important;
}
.w-50 {
width: 50% !important;
}
.w-75 {
width: 75% !important;
}
.w-100 {
width: 100% !important;
}
.w-auto {
width: auto !important;
}
.cmw-30 {
min-width: 30rem;
}
.fst-normal {
font-style: normal !important;
}
.fw-light {
font-weight: 300 !important;
}
.fw-lighter {
font-weight: lighter !important;
}
.fw-normal {
font-weight: 400 !important;
}
.fw-bold {
font-weight: 500 !important;
}
.fw-bolder {
font-weight: bolder !important;
}
.text-lowercase {
text-transform: lowercase !important;
}
.text-uppercase {
text-transform: uppercase !important;
}
.text-capitalize {
text-transform: capitalize !important;
}
.text-start {
text-align: left !important;
}
.text-end {
text-align: right !important;
}
.text-center {
text-align: center !important;
}
.text-primary {
color: #0e6eff !important;
}
.text-secondary {
color: #6c757d !important;
}
.text-success {
color: #68cf29 !important;
}
.text-info {
color: #03a9f4 !important;
}
.text-warning {
color: #ffc107 !important;
}
.text-danger {
color: #dc3545 !important;
}
.text-light {
color: #f8f9fa !important;
}
.text-dark {
color: #212529 !important;
}
.text-white {
color: #fff !important;
}
`

View File

@ -0,0 +1,285 @@
import {css, html, LitElement} from 'lit'
import {render} from 'lit/html.js'
import {Epml} from '../../../epml.js'
import {get, translate} from '../../../../core/translate/index.js'
import {tradeInfoViewStyle} from './TradeInfoView-css.js'
import '@polymer/paper-dialog/paper-dialog.js'
import '@material/mwc-button'
import '@material/mwc-icon'
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
class TradeInfoView extends LitElement {
static get properties() {
return {
sellerAddress: { type: String },
buyerAddress: { type: String },
sellqortAmount: { type: Number },
buyforeignAmount: { type: Number },
tradeTime: { type: String },
coinCode: { type: String },
addressSellerResult: { type: Array },
addressBuyerResult: { type: Array },
sellerImage: { type: String },
infoSellerName: { type: String },
buyerImage: { type: String },
infoBuyerName: { type: String },
priceEach: { type: Number },
atAddress: { type: String },
isLoadingCompleteInfo: { type: Boolean },
theme: { type: String, reflect: true }
}
}
static styles = [tradeInfoViewStyle]
constructor() {
super()
this.sellerAddress = ''
this.buyerAddress = ''
this.sellqortAmount = 0
this.buyforeignAmount = 0
this.tradeTime = ''
this.coinCode = ''
this.addressSellerResult = []
this.addressBuyerResult = []
this.sellerImage = ''
this.infoSellerName = ''
this.buyerImage = ''
this.infoBuyerName = ''
this.priceEach = 0
this.atAddress = ''
this.isLoadingCompleteInfo = false
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
render() {
return html`
<paper-dialog style="background: var(--white); border: 1px solid var(--black); border-radius: 5px;" id="tradeInfoDialog" modal>
<div class="card">
<div class="card-header">
<h4 class="card-title">${translate("info.inf19")}</h4>
</div>
<div class="card-body">
<div class="d-sm-flex align-items-center justify-content-between">
<div class="d-flex mb-3">
${this.avatarSellerImage()}
<div class="ms-3">
<p class="fw-bold cfs-18 red">${translate("tradepage.tchange13")}</p>
<p class="fw-bold cfs-18">${this.infoSellerName}</p>
<p class="cfs-12">${this.sellerAddress}&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p class="cfs-12">${translate("explorerpage.exp6")}:&nbsp;${this.founderSellerStatus()}</p>
</div>
</div>
<div class="d-flex mb-3">
<div class="me-sm-3 ms-3 ms-sm-0 text-sm-end order-1 order-sm-0">
<p class="fw-bold cfs-18 green">${translate("info.inf20")}</p>
<p class="fw-bold cfs-18">${this.infoBuyerName}</p>
<p class="cfs-14">&nbsp;&nbsp;&nbsp;&nbsp;${this.buyerAddress}</p>
<p class="cfs-14">${translate("explorerpage.exp6")}:&nbsp;${this.founderBuyerStatus()}</p>
</div>
${this.avatarBuyerImage()}
</div>
</div>
<div class="table-responsive mt-4">
<table class="table w-100 table-borderless cmw-30">
<tbody>
<tr class="text-primary fw-bold cfs-16">
<td>${translate("tradepage.tchange8")} ( QORT )</td>
<td class="text-end">${this.sellqortAmount} QORT</td>
</tr>
<tr class="fw-bold cfs-16">
<td>${translate("tradepage.tchange9")} ( ${this.coinCode} )</td>
<td class="text-end">${this.priceEach} ${this.coinCode}</td>
</tr>
<tr class="fw-bold cfs-16">
<td>${translate("tradepage.tchange10")} ( ${this.coinCode} )</td>
<td class="text-end">${this.buyforeignAmount} ${this.coinCode}</td>
</tr>
<tr class="fw-bold cfs-16">
<td>AT ${translate("settings.address")}</td>
<td class="text-end">${this.atAddress}</td>
</tr>
<tr class="fw-bold cfs-16">
<td>${translate("tradepage.tchange11")}</td>
<td class="text-end">${this.tradeTime}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="buttons">
<mwc-button class='decline' @click=${() => this.closeTradeInfo()} dialog-dismiss>${translate("general.close")}</mwc-button>
</div>
</paper-dialog>
`
}
async openTradeInfo(seller, buyer, qortAmount, foreignAmount, ata, time, coin) {
this.sellerAddress = ''
this.buyerAddress = ''
this.sellqortAmount = 0
this.buyforeignAmount = 0
this.tradeTime = ''
this.coinCode = ''
this.priceEach = 0
this.atAddress = ''
this.shadowRoot.getElementById('tradeInfoDialog').open()
this.isLoadingCompleteInfo = true
this.sellerAddress = seller
this.buyerAddress = buyer
this.sellqortAmount = qortAmount
this.buyforeignAmount = foreignAmount
this.tradeTime = new Date(time).toLocaleString()
this.coinCode = coin
this.priceEach = this.round(parseFloat(foreignAmount) / parseFloat(qortAmount))
this.atAddress = ata
await this.getAddressSellerInfo(seller)
await this.getAddressBuyerInfo(buyer)
await this.getAddressSellerAvatar(seller)
await this.getAddressBuyerAvatar(buyer)
this.isLoadingCompleteInfo = false
}
closeTradeInfo() {
this.shadowRoot.getElementById('tradeInfoDialog').close()
}
async getAddressSellerInfo(seller) {
this.addressSellerResult = []
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 infoSellerAddressUrl = `${nodeUrl}/addresses/${seller}`
const qortalSellerAddressInfo = await fetch(infoSellerAddressUrl).then(response => {
return response.json()
})
this.addressSellerResult = qortalSellerAddressInfo
}
async getAddressBuyerInfo(buyer) {
this.addressBuyerResult = []
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 infoBuyerAddressUrl = `${nodeUrl}/addresses/${buyer}`
const qortalBuyerAddressInfo = await fetch(infoBuyerAddressUrl).then(response => {
return response.json()
})
this.addressBuyerResult = qortalBuyerAddressInfo
}
async getAddressSellerAvatar(seller) {
this.sellerImage = ''
this.infoSellerName = ''
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 sellerNameUrl = `${nodeUrl}/names/address/${seller}?limit=0&reverse=true`
await fetch(sellerNameUrl).then(res => {
return res.json()
}).then(jsonRes => {
if(jsonRes.length) {
jsonRes.map (item => {
this.infoSellerName = item.name
this.sellerImageName = item.name
})
} else {
this.infoSellerName = get("chatpage.cchange15")
this.sellerImageName = seller
}
})
const sellerImageUrl = `${nodeUrl}/arbitrary/THUMBNAIL/${this.sellerImageName}/qortal_avatar?async=true&apiKey=${this.getApiKey()}`
this.sellerImage = sellerImageUrl
}
async getAddressBuyerAvatar(buyer) {
this.buyerImage = ''
this.infoBuyerName = ''
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 buyerNameUrl = `${nodeUrl}/names/address/${buyer}?limit=0&reverse=true`
await fetch(buyerNameUrl).then(res => {
return res.json()
}).then(jsonRes => {
if(jsonRes.length) {
jsonRes.map (item => {
this.infoBuyerName = item.name
this.buyerImageName = item.name
})
} else {
this.infoBuyerName = get("chatpage.cchange15")
this.buyerImageName = seller
}
})
const buyerImageUrl = `${nodeUrl}/arbitrary/THUMBNAIL/${this.buyerImageName}/qortal_avatar?async=true&apiKey=${this.getApiKey()}`
this.buyerImage = buyerImageUrl
}
avatarSellerImage() {
return html`<img class="cwh-80 rounded" src="${this.sellerImage}" onerror="this.src='/img/incognito.png';" />`
}
avatarBuyerImage() {
return html`<img class="cwh-80 rounded order-0 order-sm-1" src="${this.buyerImage}" onerror="this.src='/img/incognito.png';" />`
}
founderSellerBadge() {
if (this.addressSellerResult.flags === 1) {
return html`<span class="founder">${translate("explorerpage.exp6")}</span>`
} else {
return html``
}
}
founderBuyerBadge() {
if (this.addressBuyerResult.flags === 1) {
return html`<span class="founder">${translate("explorerpage.exp6")}</span>`
} else {
return html``
}
}
founderSellerStatus() {
if (this.addressSellerResult.flags === 1) {
return html`<span class="green">${translate("general.yes")}</span>`
} else {
return html`<span class="red">${translate("general.no")}</span>`
}
}
founderBuyerStatus() {
if (this.addressBuyerResult.flags === 1) {
return html`<span class="green">${translate("general.yes")}</span>`
} else {
return html`<span class="red">${translate("general.no")}</span>`
}
}
getApiKey() {
const apiNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
let apiKey = apiNode.apiKey;
return apiKey;
}
isEmptyArray(arr) {
if (!arr) {
return true
}
return arr.length === 0
}
round(number) {
let result = (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8)
return result
}
}
window.customElements.define('trade-info-view', TradeInfoView)

View File

@ -5,6 +5,7 @@ import isElectron from 'is-electron'
import {get, registerTranslateConfig, translate, use} from '../../../../core/translate/index.js' import {get, registerTranslateConfig, translate, use} from '../../../../core/translate/index.js'
import Base58 from '../../../../crypto/api/deps/Base58.js' import Base58 from '../../../../crypto/api/deps/Base58.js'
import {decryptData, encryptData} from '../../../../core/src/lockScreen.js' import {decryptData, encryptData} from '../../../../core/src/lockScreen.js'
import {tradeStyles} from './trade-portal-css.js'
import '@material/mwc-button' import '@material/mwc-button'
import '@material/mwc-textfield' import '@material/mwc-textfield'
import '@material/mwc-icon' import '@material/mwc-icon'
@ -29,6 +30,7 @@ import chartsdgb from './charts/dgb-charts.js'
import chartsrvn from './charts/rvn-charts.js' import chartsrvn from './charts/rvn-charts.js'
import chartsarrr from './charts/arrr-charts.js' import chartsarrr from './charts/arrr-charts.js'
import '../components/TraderInfoView.js' import '../components/TraderInfoView.js'
import '../components/TradeInfoView.js'
registerTranslateConfig({ registerTranslateConfig({
loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) loader: lang => fetch(`/language/${lang}.json`).then(res => res.json())
@ -129,36 +131,44 @@ class TradePortal extends LitElement {
.myhover vaadin-grid-cell-content { .myhover vaadin-grid-cell-content {
cursor: pointer; cursor: pointer;
} }
.myhover vaadin-grid::part(selected-row) { .myhover vaadin-grid::part(selected-row) {
color: green; color: green;
cursor: pointer; cursor: pointer;
} }
.myhover vaadin-grid::part(focused-selected-row) { .myhover vaadin-grid::part(focused-selected-row) {
color: green; color: green;
cursor: pointer; cursor: pointer;
} }
.myhover vaadin-grid::part(cell):hover { .myhover vaadin-grid::part(cell):hover {
cursor: pointer; cursor: pointer;
} }
.myhover vaadin-grid::part(row):hover { .myhover vaadin-grid::part(row):hover {
color: green; color: green;
cursor: pointer; cursor: pointer;
} }
.myhover vaadin-grid::part(selected-row-cell) { .myhover vaadin-grid::part(selected-row-cell) {
color: green; color: green;
cursor: pointer; cursor: pointer;
} }
paper-spinner-lite { paper-spinner-lite {
height: 30px; height: 30px;
width: 30px; width: 30px;
--paper-spinner-color: var(--mdc-theme-primary); --paper-spinner-color: var(--mdc-theme-primary);
--paper-spinner-stroke-width: 3px; --paper-spinner-stroke-width: 3px;
} }
mwc-tab-bar { mwc-tab-bar {
--mdc-text-transform: none; --mdc-text-transform: none;
--mdc-tab-color-default: var(--black); --mdc-tab-color-default: var(--black);
--mdc-tab-text-label-color-default: var(--black); --mdc-tab-text-label-color-default: var(--black);
} }
#tabs-1 { #tabs-1 {
--mdc-tab-height: 42px; --mdc-tab-height: 42px;
border-left: 1px solid var(--tradeborder); border-left: 1px solid var(--tradeborder);
@ -166,46 +176,57 @@ class TradePortal extends LitElement {
border-right: 1px solid var(--tradeborder); border-right: 1px solid var(--tradeborder);
color: var(--black); color: var(--black);
} }
#tab-buy[active] { #tab-buy[active] {
--mdc-theme-primary: rgba(55, 160, 51, 0.9); --mdc-theme-primary: rgba(55, 160, 51, 0.9);
} }
#tabs-1-content { #tabs-1-content {
height: 100%; height: 100%;
padding-bottom: 10px; padding-bottom: 10px;
} }
#tabs-1-content > div {
#tabs-1-content>div {
height: 100%; height: 100%;
border: 1px solid var(--tradeborder); border: 1px solid var(--tradeborder);
} }
#tabs-1-content .card { #tabs-1-content .card {
border: none; border: none;
} }
#tabs-1-content .btn-clear { #tabs-1-content .btn-clear {
--mdc-icon-button-size: 32px; --mdc-icon-button-size: 32px;
color: var(--black); color: var(--black);
} }
.btn-clear-bot { .btn-clear-bot {
--mdc-icon-button-size: 32px; --mdc-icon-button-size: 32px;
color: var(--black); color: var(--black);
float: right; float: right;
} }
.btn-info { .btn-info {
color: #03a9f4; color: #03a9f4;
--mdc-icon-size: 16px; --mdc-icon-size: 16px;
padding-top: 3px; padding-top: 3px;
} }
#tab-sell[active] { #tab-sell[active] {
--mdc-theme-primary: rgb(255, 89, 89); --mdc-theme-primary: rgb(255, 89, 89);
} }
#trade-portal-page { #trade-portal-page {
background: var(--white); background: var(--white);
padding: 12px 24px; padding: 12px 24px;
} }
.divCard { .divCard {
border: 1px solid var(--black); border: 1px solid var(--black);
padding: 1em; 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); 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 { h2 {
margin: 10px 0; margin: 10px 0;
} }
@ -309,6 +330,7 @@ class TradePortal extends LitElement {
color: var(--black); color: var(--black);
font-weight: 400; font-weight: 400;
} }
header { header {
display: flex; display: flex;
flex: 0 1 auto; flex: 0 1 auto;
@ -323,14 +345,17 @@ class TradePortal extends LitElement {
border-right: 1px solid var(--tradeborder); border-right: 1px solid var(--tradeborder);
min-height: 40px; min-height: 40px;
} }
p { p {
margin-bottom: 12px; margin-bottom: 12px;
} }
#trade-portal { #trade-portal {
max-width: 100vw; max-width: 100vw;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
} }
.box { .box {
margin: 0; margin: 0;
padding: 0; padding: 0;
@ -338,6 +363,7 @@ class TradePortal extends LitElement {
flex-flow: column; flex-flow: column;
height: 100%; height: 100%;
} }
.box-bot { .box-bot {
margin: 0; margin: 0;
padding: 0; padding: 0;
@ -345,35 +371,43 @@ class TradePortal extends LitElement {
flex-flow: column; flex-flow: column;
height: 150px; height: 150px;
} }
#first-trade-section { #first-trade-section {
margin-bottom: 10px; margin-bottom: 10px;
} }
#first-trade-section > div {
} #first-trade-section>div {}
#second-trade-section { #second-trade-section {
margin-bottom: 10px; margin-bottom: 10px;
} }
#second-trade-section > div {
} #second-trade-section>div {}
#third-trade-section { #third-trade-section {
margin-bottom: 10px; margin-bottom: 10px;
} }
#third-trade-section > div {
} #third-trade-section>div {}
.trade-chart { .trade-chart {
background-color: var(--white); background-color: var(--white);
border: 2px #ddd solid; border: 2px #ddd solid;
text-align: center; text-align: center;
} }
.open-trades { .open-trades {
text-align: center; text-align: center;
} }
.open-market-container { .open-market-container {
text-align: center; text-align: center;
} }
.trade-bot-container { .trade-bot-container {
text-align: center; text-align: center;
} }
.no-last-seen { .no-last-seen {
background: rgb(255, 89, 89); background: rgb(255, 89, 89);
padding: 9px 1.3px; padding: 9px 1.3px;
@ -381,6 +415,7 @@ class TradePortal extends LitElement {
width: 1rem; width: 1rem;
margin: 0 auto; margin: 0 auto;
} }
.card { .card {
padding: 1em; padding: 1em;
border: 1px var(--tradeborder) solid; border: 1px var(--tradeborder) solid;
@ -390,6 +425,7 @@ class TradePortal extends LitElement {
justify-content: space-evenly; justify-content: space-evenly;
min-height: inherit; min-height: inherit;
} }
.card-bot { .card-bot {
padding: 1em; padding: 1em;
flex: 1 1 auto; flex: 1 1 auto;
@ -399,19 +435,23 @@ class TradePortal extends LitElement {
width: 350px; width: 350px;
min-height: inherit; min-height: inherit;
} }
.cancel { .cancel {
--mdc-theme-primary: rgb(255, 89, 89); --mdc-theme-primary: rgb(255, 89, 89);
} }
.border-wrapper { .border-wrapper {
border: 1px var(--tradeborder) solid; border: 1px var(--tradeborder) solid;
overflow: hidden; overflow: hidden;
} }
.amt-text { .amt-text {
color: var(--tradehave); color: var(--tradehave);
font-size: 15px; font-size: 15px;
margin-top: 5px; margin-top: 5px;
margin-bottom: 12px; margin-bottom: 12px;
} }
.exchange { .exchange {
color: var(--black); color: var(--black);
font-size: 18px; font-size: 18px;
@ -419,26 +459,31 @@ class TradePortal extends LitElement {
margin-top: 5px; margin-top: 5px;
margin-bottom: 10px; margin-bottom: 10px;
} }
.clear-button { .clear-button {
display: inline; display: inline;
float: right; float: right;
margin-bottom: 5px; margin-bottom: 5px;
} }
.exhcnage-text { .exhcnage-text {
display: inline; display: inline;
float: left; float: left;
margin-bottom: 5px; margin-bottom: 5px;
} }
.balance-text { .balance-text {
display: inline; display: inline;
float: right; float: right;
margin-bottom: 5px; margin-bottom: 5px;
} }
.fee-text { .fee-text {
display: inline; display: inline;
float: left; float: left;
margin-bottom: 5px; margin-bottom: 5px;
} }
.tab-text { .tab-text {
color: var(--tradehave); color: var(--tradehave);
font-size: 12px; font-size: 12px;
@ -446,51 +491,64 @@ class TradePortal extends LitElement {
margin-top: 2px; margin-top: 2px;
margin-bottom: -12px; margin-bottom: -12px;
} }
.historic-trades { .historic-trades {
text-align: center; text-align: center;
} }
.my-open-orders { .my-open-orders {
text-align: center; text-align: center;
} }
.my-historic-trades { .my-historic-trades {
text-align: center; text-align: center;
} }
.buttons { .buttons {
width: auto !important; width: auto !important;
} }
.buy-button { .buy-button {
--mdc-theme-primary: rgba(55, 160, 51, 0.9); --mdc-theme-primary: rgba(55, 160, 51, 0.9);
} }
.sell-button { .sell-button {
--mdc-theme-primary: rgb(255, 89, 89); --mdc-theme-primary: rgb(255, 89, 89);
} }
.trade-bot-button { .trade-bot-button {
margin-top: 20px; margin-top: 20px;
margin-bottom: 20px; margin-bottom: 20px;
--mdc-theme-primary: rgba(55, 160, 51, 0.9); --mdc-theme-primary: rgba(55, 160, 51, 0.9);
} }
.full-width { .full-width {
background-color: var(--white); background-color: var(--white);
border: 2px var(--black); border: 2px var(--black);
height: 200px; height: 200px;
text-align: center; text-align: center;
} }
vaading-grid { vaading-grid {
font-size: .8em; font-size: .8em;
} }
vaadin-grid-column { vaadin-grid-column {
flex-grow: 1; flex-grow: 1;
} }
.loadingContainer { .loadingContainer {
height: 100%; height: 100%;
width: 100%; width: 100%;
} }
.loading, .loading,
.loading:after { .loading:after {
border-radius: 50%; border-radius: 50%;
width: 5em; width: 5em;
height: 5em; height: 5em;
} }
.loading { .loading {
margin: 10px auto; margin: 10px auto;
border-width: .6em; border-width: .6em;
@ -502,13 +560,16 @@ class TradePortal extends LitElement {
transform: translateZ(0px); transform: translateZ(0px);
animation: 1.1s linear 0s infinite normal none running loadingAnimation; animation: 1.1s linear 0s infinite normal none running loadingAnimation;
} }
mwc-select#coinSelectionMenu { mwc-select#coinSelectionMenu {
font-size: 24px; font-size: 24px;
width:220px; width: 220px;
} }
mwc-select#coinSelectionMenu mwc-list-item { mwc-select#coinSelectionMenu mwc-list-item {
line-height: 30px; line-height: 30px;
} }
.coinName::before { .coinName::before {
content: ""; content: "";
display: inline-block; display: inline-block;
@ -520,29 +581,37 @@ class TradePortal extends LitElement {
left: 10px; left: 10px;
top: 10px; top: 10px;
} }
.btc.coinName:before { .btc.coinName:before {
background-image: url('/img/qortbtc.png'); background-image: url('/img/qortbtc.png');
} }
.ltc.coinName:before { .ltc.coinName:before {
background-image: url('/img/qortltc.png'); background-image: url('/img/qortltc.png');
} }
.doge.coinName:before { .doge.coinName:before {
background-image: url('/img/qortdoge.png'); background-image: url('/img/qortdoge.png');
} }
.dgb.coinName:before { .dgb.coinName:before {
background-image: url('/img/qortdgb.png'); background-image: url('/img/qortdgb.png');
} }
.rvn.coinName:before { .rvn.coinName:before {
background-image: url('/img/qortrvn.png'); background-image: url('/img/qortrvn.png');
} }
.arrr.coinName:before { .arrr.coinName:before {
background-image: url('/img/qortarrr.png'); background-image: url('/img/qortarrr.png');
} }
.coinName { .coinName {
display: inline-block; display: inline-block;
height: 26px; height: 26px;
padding-left: 45px; padding-left: 45px;
} }
.warning-text { .warning-text {
animation: blinker 1.5s linear infinite; animation: blinker 1.5s linear infinite;
display: inline; display: inline;
@ -550,40 +619,48 @@ class TradePortal extends LitElement {
margin-bottom: 5px; margin-bottom: 5px;
color: rgb(255, 89, 89); color: rgb(255, 89, 89);
} }
.warning-bot-text { .warning-bot-text {
animation: blinker 1.5s linear infinite; animation: blinker 1.5s linear infinite;
display: inline; display: inline;
text-align: center; text-align: center;
color: rgb(255, 89, 89); color: rgb(255, 89, 89);
} }
.red { .red {
--mdc-theme-primary: #F44336; --mdc-theme-primary: #F44336;
} }
@-webkit-keyframes loadingAnimation { @-webkit-keyframes loadingAnimation {
0% { 0% {
-webkit-transform: rotate(0deg); -webkit-transform: rotate(0deg);
transform: rotate(0deg); transform: rotate(0deg);
} }
100% { 100% {
-webkit-transform: rotate(360deg); -webkit-transform: rotate(360deg);
transform: rotate(360deg); transform: rotate(360deg);
} }
} }
@keyframes loadingAnimation { @keyframes loadingAnimation {
0% { 0% {
-webkit-transform: rotate(0deg); -webkit-transform: rotate(0deg);
transform: rotate(0deg); transform: rotate(0deg);
} }
100% { 100% {
-webkit-transform: rotate(360deg); -webkit-transform: rotate(360deg);
transform: rotate(360deg); transform: rotate(360deg);
} }
} }
@keyframes blinker { @keyframes blinker {
50% { 50% {
opacity: 0; opacity: 0;
} }
} }
paper-dialog.info { paper-dialog.info {
width: 100%; width: 100%;
max-width: 75vw; max-width: 75vw;
@ -596,15 +673,18 @@ class TradePortal extends LitElement {
line-height: 1.6; line-height: 1.6;
overflow-y: auto; overflow-y: auto;
} }
.actions { .actions {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding: 0 1em; padding: 0 1em;
margin: 12px 0 -6px 0; margin: 12px 0 -6px 0;
} }
.close-icon { .close-icon {
font-size: 36px; font-size: 36px;
} }
.close-icon:hover { .close-icon:hover {
cursor: pointer; cursor: pointer;
opacity: .6; opacity: .6;
@ -666,12 +746,13 @@ class TradePortal extends LitElement {
} }
@media (min-width: 701px) { @media (min-width: 701px) {
* { * {}
}
#trade-portal {} #trade-portal {}
#first-trade-section { #first-trade-section {
display: grid; display: grid;
grid-template-columns:1fr 1fr 2fr; grid-template-columns: 1fr 1fr 2fr;
grid-auto-rows: max(450px); grid-auto-rows: max(450px);
column-gap: 0.5em; column-gap: 0.5em;
row-gap: 0.4em; row-gap: 0.4em;
@ -679,6 +760,7 @@ class TradePortal extends LitElement {
align-items: stretch; align-items: stretch;
margin-bottom: 10px; margin-bottom: 10px;
} }
#second-trade-section { #second-trade-section {
display: grid; display: grid;
grid-template-columns: 2fr 1fr; grid-template-columns: 2fr 1fr;
@ -689,6 +771,7 @@ class TradePortal extends LitElement {
align-items: stretch; align-items: stretch;
margin-bottom: 10px; margin-bottom: 10px;
} }
#third-trade-section { #third-trade-section {
display: grid; display: grid;
grid-template-columns: 1fr 2fr 1fr; grid-template-columns: 1fr 2fr 1fr;
@ -914,20 +997,28 @@ class TradePortal extends LitElement {
historicTradesTemplate() { historicTradesTemplate() {
return html` return html`
<div class="historic-trades"> <div class="historic-trades myhover">
<div class="box"> <div class="box">
<header><span>${translate("tradepage.tchange3")}</span></header> <header><span>${translate("tradepage.tchange3")}</span></header>
<div class="border-wrapper"> <div class="border-wrapper">
<div class="loadingContainer" id="loadingHistoricTrades" style="display:${this.isLoadingHistoricTrades ? 'block' : 'none'}"><div class="loading"></div><span style="color: var(--black);">${translate("login.loading")}</span></div> <div class="loadingContainer" id="loadingHistoricTrades" style="display:${this.isLoadingHistoricTrades ? 'block' : 'none'}"><div class="loading"></div><span style="color: var(--black);">${translate("login.loading")}</span></div>
<vaadin-grid theme="compact column-borders row-stripes wrap-cell-content" id="historicTradesGrid" aria-label="Historic Trades" .items="${this.listedCoins.get(this.selectedCoin).historicTrades}"> <vaadin-grid theme="compact column-borders row-stripes wrap-cell-content" id="historicTradesGrid" aria-label="Historic Trades" .items="${this.listedCoins.get(this.selectedCoin).historicTrades}">
<vaadin-grid-column auto-width resizable header="${translate("tradepage.tchange8")} (QORT)" path="qortAmount"></vaadin-grid-column> <vaadin-grid-column
auto-width
resizable
header="${translate("tradepage.tchange8")} (QORT)"
.renderer=${(root, column, data) => {
render(html`<span style="cursor: pointer;" @click="${() => this.requestTradeInfo(data)}">${data.item.qortAmount}</span>`, root)
}}
>
</vaadin-grid-column>
<vaadin-grid-column <vaadin-grid-column
auto-width auto-width
resizable resizable
header="${translate("tradepage.tchange9")} (${this.listedCoins.get(this.selectedCoin).coinCode})" header="${translate("tradepage.tchange9")} (${this.listedCoins.get(this.selectedCoin).coinCode})"
.renderer=${(root, column, data) => { .renderer=${(root, column, data) => {
const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount))
render(html`${price}`, root) render(html`<span style="cursor: pointer;" @click="${() => this.requestTradeInfo(data)}">${price}</span>`, root)
}} }}
> >
</vaadin-grid-column> </vaadin-grid-column>
@ -936,7 +1027,7 @@ class TradePortal extends LitElement {
resizable resizable
header="${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})" header="${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})"
.renderer=${(root, column, data) => { .renderer=${(root, column, data) => {
render(html`<span> ${data.item.foreignAmount} </span>`, root) render(html`<span style="cursor: pointer;" @click="${() => this.requestTradeInfo(data)}">${data.item.foreignAmount}</span>`, root)
}} }}
> >
</vaadin-grid-column> </vaadin-grid-column>
@ -1211,8 +1302,7 @@ class TradePortal extends LitElement {
<vaadin-grid-column <vaadin-grid-column
auto-width auto-width
resizable resizable
header="${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})" header="${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})" path="foreignAmount"
path="foreignAmount"
> >
</vaadin-grid-column> </vaadin-grid-column>
<vaadin-grid-column <vaadin-grid-column
@ -1419,10 +1509,11 @@ class TradePortal extends LitElement {
</div> </div>
</paper-dialog> </paper-dialog>
<trader-info-view></trader-info-view> <trader-info-view></trader-info-view>
<trade-info-view></trade-info-view>
` `
} }
pingCoinBalancesController(){ pingCoinBalancesController() {
if(!this.selectedCoin) return if(!this.selectedCoin) return
let coin = '' let coin = ''
switch (this.selectedCoin) { switch (this.selectedCoin) {
@ -1449,22 +1540,19 @@ class TradePortal extends LitElement {
} }
const customEvent = new CustomEvent('ping-coin-controller-with-coin', { const customEvent = new CustomEvent('ping-coin-controller-with-coin', {
detail: coin detail: coin
}); })
window.parent.dispatchEvent(customEvent); window.parent.dispatchEvent(customEvent)
} }
connectedCallback() { connectedCallback() {
super.connectedCallback(); super.connectedCallback()
this.intervalID = setInterval(this.pingCoinBalancesController, 30000); this.intervalID = setInterval(this.pingCoinBalancesController, 30000)
} }
disconnectedCallback() { disconnectedCallback() {
super.disconnectedCallback()
super.disconnectedCallback(); if (this.intervalID) {
if(this.intervalID){ clearInterval(this.intervalID)
clearInterval(this.intervalID);
} }
} }
@ -1859,6 +1947,18 @@ class TradePortal extends LitElement {
theInfoView.openTraderInfo(getAddress) theInfoView.openTraderInfo(getAddress)
} }
requestTradeInfo(tradeObj) {
let seller = tradeObj.item.sellerAddress
let buyer = tradeObj.item.buyerReceivingAddress
let qortAmount = tradeObj.item.qortAmount
let foreignAmount = tradeObj.item.foreignAmount
let ata = tradeObj.item.atAddress
let time = tradeObj.item.tradeTimestamp
let 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() { changeTheme() {
const checkTheme = localStorage.getItem('qortalTheme') const checkTheme = localStorage.getItem('qortalTheme')
this.theme = (checkTheme === 'dark') ? 'dark' : 'light' this.theme = (checkTheme === 'dark') ? 'dark' : 'light'