Merge branch 'bugfix/sponsorship' into release/26-08-22

This commit is contained in:
Phillip Lang Martinez 2022-08-26 19:19:10 +03:00
commit f8d743d654
4 changed files with 707 additions and 222 deletions

View File

@ -30,6 +30,7 @@ html {
--nav-icon-color: #080808; --nav-icon-color: #080808;
--nav-border-color: #eeeeee; --nav-border-color: #eeeeee;
--nav-border-selected-color: #03a9f4; --nav-border-selected-color: #03a9f4;
--error: #d50000;
--background: url("/img/qortal_background_light_.jpg"); --background: url("/img/qortal_background_light_.jpg");
} }
@ -65,5 +66,6 @@ html[theme="dark"] {
--nav-icon-color: #008fd5; --nav-icon-color: #008fd5;
--nav-border-color: #0b305e; --nav-border-color: #0b305e;
--nav-border-selected-color: #76c8f5; --nav-border-selected-color: #76c8f5;
--error: #d50000;
--background: url("/img/qortal_background_dark_.jpg"); --background: url("/img/qortal_background_dark_.jpg");
} }

View File

@ -2,27 +2,193 @@ import { LitElement, html, css } from 'lit';
import { connect } from 'pwa-helpers'; import { connect } from 'pwa-helpers';
import { store } from '../store.js'; import { store } from '../store.js';
import { translate, get } from 'lit-translate'; import { translate, get } from 'lit-translate';
import {asyncReplace} from 'lit/directives/async-replace.js';
import '../functional-components/my-button.js'; import '../functional-components/my-button.js';
import { routes } from '../plugins/routes.js'; import { routes } from '../plugins/routes.js';
import "@material/mwc-button"
import '@material/mwc-dialog'
async function* countDown(count, callback) {
while (count > 0) {
yield count--;
await new Promise((r) => setTimeout(r, 1000));
if(count === 0){
callback()
}
}
}
class StartMinting extends connect(store)(LitElement) { class StartMinting extends connect(store)(LitElement) {
static get properties() { static get properties() {
return { return {
addressInfo: { type: Object }, addressInfo: { type: Object },
mintingAccountData: { type: Array }, mintingAccountData: { type: Array },
errorMsg: { type: String }, errorMsg: { type: String },
openDialogRewardShare : {type: Boolean},
status: {type: Number},
timer: {type: Number},
privateRewardShareKey: {type: String}
}; };
} }
static get styles() { static get styles() {
return [ return [
css` css`
.dialogCustom {
position: fixed;
z-index: 10000;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
top: 0px;
bottom: 0px;
left: 0px;
width: 100vw;
}
.dialogCustomInner {
width: 300px;
min-height: 400px;
background-color: var(--white);
box-shadow: var(--mdc-dialog-box-shadow, 0px 11px 15px -7px rgba(0, 0, 0, 0.2), 0px 24px 38px 3px rgba(0, 0, 0, 0.14), 0px 9px 46px 8px rgba(0, 0, 0, 0.12));
padding: 20px 24px;
border-radius: 4px;
}
.dialogCustomInner ul {
padding-left: 0px
}
.dialogCustomInner li {
margin-bottom: 10px;
}
.start-minting-wrapper { .start-minting-wrapper {
position: absolute; position: absolute;
left: 50%; left: 50%;
transform: translateX(calc(-50% - 10px)); transform: translateX(calc(-50% - 10px));
z-index: 10;
} }
.dialog-header h1 {
font-size: 18px;
}
.row {
display: flex;
width: 100%;
align-items: center;
}
.modalFooter {
width: 100%;
display: flex;
justify-content: flex-end;
}
.hide {
visibility: hidden
}
.inactiveText {
opacity: .60
}
.column {
display: flex;
flex-direction: column;
width: 100%;
}
.smallLoading,
.smallLoading:after {
border-radius: 50%;
width: 2px;
height: 2px;
}
.smallLoading {
border-width: 0.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);
}
}
.word-break {
word-break:break-all;
}
.dialog-container {
width: 300px;
min-height: 300px;
max-height: 75vh;
padding: 5px;
display: flex;
align-items: flex-start;
flex-direction: column;
}
.between {
justify-content: space-between;
}
.no-width {
width: auto
}
.between p {
margin: 0;
padding: 0;
}
.marginLoader {
margin-left: 10px;
}
.marginRight {
margin-right: 10px;
}
.warning{
display: flex;
flex-grow: 1
}
.message-error {
color: var(--error);
}
`, `,
]; ];
} }
@ -32,6 +198,9 @@ class StartMinting extends connect(store)(LitElement) {
this.addressInfo = {}; this.addressInfo = {};
this.mintingAccountData = []; this.mintingAccountData = [];
this.errorMsg = ''; this.errorMsg = '';
this.openDialogRewardShare = false;
this.status = 0;
this.privateRewardShareKey = "";
} }
render() { render() {
@ -40,6 +209,10 @@ class StartMinting extends connect(store)(LitElement) {
firstUpdated() { firstUpdated() {
this.getMintingAcccounts(); this.getMintingAcccounts();
this.shadowRoot.querySelector('mdc-dialog--open').setAttribute('style', 'width: 100vw')
} }
async getMintingAcccounts() { async getMintingAcccounts() {
@ -60,6 +233,103 @@ class StartMinting extends connect(store)(LitElement) {
} }
} }
async changeStatus(value){
this.status = value
const publicAddress =
window.parent.reduxStore.getState().app?.selectedAddress
?.base58PublicKey;
// Check to see if a sponsorship key on a newly-level 1 minter exists. If it does, remove it.
const findMintingAccountFromOtherUser = mintingAccountData.find(
(ma) => !ma.publicKey.includes(publicAddress)
);
const removeMintingAccount = async (publicKey) => {
const url = `${nodeUrl}/admin/mintingaccounts?apiKey=${myNode.apiKey}`;
return await fetch(url, {
method: 'DELETE',
body: publicKey,
});
};
const addMintingAccount = async (sponsorshipKeyValue) => {
const url = `${nodeUrl}/admin/mintingaccounts?apiKey=${myNode.apiKey}`;
return await fetch(url, {
method: 'POST',
body: sponsorshipKeyValue,
});
};
try {
if (
findMintingAccountFromOtherUser &&
findMintingAccountFromOtherUser?.publicKey[0]
) {
await removeMintingAccount(
findMintingAccountFromOtherUser?.publicKey[0]
);
}
} catch (error) {
this.errorMsg = 'Failed to remove key';
return;
}
try {
await addMintingAccount(sponsorshipKeyValue);
routes.showSnackBar({
data: translate('becomeMinterPage.bchange19'),
});
this.status = 5;
this.getMintingAcccounts();
} catch (error) {
this.errorMsg = 'Failed to add minting key';
return;
}
}
async confirmRelationship(){
let interval = null
let stop = false
this.status = 2
const getAnswer = async () => {
const rewardShares = async (minterAddr) => {
const url = `${nodeUrl}/addresses/rewardshares?minters=${minterAddr}&recipients=${minterAddr}`;
const res = await fetch(url);
const data = await res.json();
return data;
};
if (!stop) {
stop= true;
try {
const address =
window.parent.reduxStore.getState().app?.selectedAddress?.address;
const myRewardShareArray = await rewardShares(address);
if(myRewardShareArray.length > 0){
clearInterval(interval)
this.status = 3
this.timer = countDown(180, ()=> this.changeStatus(4));
}
} catch (error) {
}
stop = false
}
};
interval = setInterval(getAnswer, 2000);
}
renderStartMintingButton() { renderStartMintingButton() {
const myNode = const myNode =
store.getState().app.nodeConfig.knownNodes[ store.getState().app.nodeConfig.knownNodes[
@ -70,12 +340,7 @@ class StartMinting extends connect(store)(LitElement) {
const mintingAccountData = this.mintingAccountData; const mintingAccountData = this.mintingAccountData;
const addressInfo = this.addressInfo; const addressInfo = this.addressInfo;
const rewardShares = async (minterAddr) => {
const url = `${nodeUrl}/addresses/rewardshares?minters=${minterAddr}&recipients=${minterAddr}`;
const res = await fetch(url);
const data = await res.json();
return data;
};
const address = const address =
window.parent.reduxStore.getState().app?.selectedAddress?.address; window.parent.reduxStore.getState().app?.selectedAddress?.address;
const nonce = const nonce =
@ -92,14 +357,7 @@ class StartMinting extends connect(store)(LitElement) {
addressInfo?.level === 1 && addressInfo?.level === 1 &&
!findMintingAccount; !findMintingAccount;
const removeMintingAccount = async (publicKey) => {
const url = `${nodeUrl}/admin/mintingaccounts?apiKey=${myNode.apiKey}`;
return await fetch(url, {
method: 'DELETE',
body: publicKey,
});
};
const makeTransactionRequest = async (lastRef) => { const makeTransactionRequest = async (lastRef) => {
let mylastRef = lastRef; let mylastRef = lastRef;
@ -128,8 +386,12 @@ class StartMinting extends connect(store)(LitElement) {
}; };
const getTxnRequestResponse = (txnResponse) => { const getTxnRequestResponse = (txnResponse) => {
if(txnResponse?.message?.includes('multiple')){
return err6string
}
if (txnResponse.success === false && txnResponse.message) { if (txnResponse.success === false && txnResponse.message) {
throw new Error(txnResponse); throw(txnResponse);
} else if ( } else if (
txnResponse.success === true && txnResponse.success === true &&
!txnResponse.data.error !txnResponse.data.error
@ -137,11 +399,12 @@ class StartMinting extends connect(store)(LitElement) {
let err6string = get('rewardsharepage.rchange21'); let err6string = get('rewardsharepage.rchange21');
return err6string; return err6string;
} else { } else {
throw new Error(txnResponse); throw(txnResponse);
} }
}; };
const createSponsorshipKey = async () => { const createSponsorshipKey = async () => {
this.status= 1
let lastRef = await getLastRef(); let lastRef = await getLastRef();
let myTransaction = await makeTransactionRequest(lastRef); let myTransaction = await makeTransactionRequest(lastRef);
@ -149,14 +412,7 @@ class StartMinting extends connect(store)(LitElement) {
getTxnRequestResponse(myTransaction); getTxnRequestResponse(myTransaction);
return myTransaction.data; return myTransaction.data;
}; };
const addMintingAccount = async (sponsorshipKeyValue) => {
const url = `${nodeUrl}/admin/mintingaccounts?apiKey=${myNode.apiKey}`;
return await fetch(url, {
method: 'POST',
body: sponsorshipKeyValue,
});
};
const getLastRef = async () => { const getLastRef = async () => {
const url = `${nodeUrl}/addresses/lastreference/${address}`; const url = `${nodeUrl}/addresses/lastreference/${address}`;
@ -167,64 +423,23 @@ class StartMinting extends connect(store)(LitElement) {
return data; return data;
}; };
const startMinting = async () => { const startMinting = async () => {
this.openDialogRewardShare = true
this.errorMsg = ''; this.errorMsg = '';
let rewardSharesList;
try { try {
rewardSharesList = await rewardShares(address);
this.privateRewardShareKey = await createSponsorshipKey();
this.confirmRelationship()
} catch (error) { } catch (error) {
this.errorMsg = 'Cannot fetch reward shares'; console.log({error})
return; this.errorMsg = error?.data?.message || 'Cannot create sponsorship key';
}
// check to see if self-share exists
const findRewardShareData = rewardSharesList.find(
(rs) =>
rs?.mintingAccount === address && rs?.recipient === address
);
let sponsorshipKeyValue = null;
try {
if (!findRewardShareData) {
// if no self-share exits, create one.
sponsorshipKeyValue = await createSponsorshipKey();
} else {
sponsorshipKeyValue =
findRewardShareData.rewardSharePublicKey;
}
} catch (error) {
this.errorMsg = 'Cannot create sponsorship key';
return; return;
} }
// Check to see if a sponsorship key on a newly-level 1 minter exists. If it does, remove it.
const findMintingAccountFromOtherUser = mintingAccountData.find(
(ma) => !ma.publicKey.includes(publicAddress)
);
try {
if (
findMintingAccountFromOtherUser &&
findMintingAccountFromOtherUser?.publicKey[0]
) {
await removeMintingAccount(
findMintingAccountFromOtherUser?.publicKey[0]
);
}
} catch (error) {
this.errorMsg = 'Failed to remove key';
return;
}
try {
await addMintingAccount(sponsorshipKeyValue);
routes.showSnackBar({
data: translate('becomeMinterPage.bchange19'),
});
this.getMintingAcccounts();
} catch (error) {
this.errorMsg = 'Failed to add minting key';
return;
}
}; };
return html` return html`
@ -246,6 +461,93 @@ class StartMinting extends connect(store)(LitElement) {
}} }}
></my-button> ></my-button>
</div> </div>
<!-- Dialog for tracking the progress of starting minting -->
${this.openDialogRewardShare ? html`
<div class="dialogCustom">
<div class="dialogCustomInner">
<div class="dialog-header" >
<div class="row">
<h1>In progress </h1> <div class=${`smallLoading marginLoader ${this.status > 3 && 'hide'}`}></div>
</div>
<hr />
</div>
<div class="dialog-container">
<ul>
<li class="row between">1. Creating relationship <div class=${`smallLoading marginLoader ${this.status !== 1 && 'hide'}`}></div></li>
<li class=${`row between ${this.status < 2 && 'inactiveText' }`}>
<p>
2. Awaiting confirmation on blockchain
</p>
<div class=${`smallLoading marginLoader ${this.status !== 2 && 'hide'}`}></div>
</li>
<li class=${`row between ${this.status < 3 && 'inactiveText' }`}>
<p>
3. Finishing up relationship
</p>
<div class="row no-width">
<div class=${`smallLoading marginLoader marginRight ${this.status !== 3 && 'hide'}`} ></div> ${asyncReplace(this.timer)}
</div>
</li>
<li class=${`row between ${this.status < 4 && 'inactiveText' }`}>
<p>
4. Adding minting key to node
</p>
<div class=${`smallLoading marginLoader ${this.status !== 4 && 'hide'}`}></div>
</li>
<li class=${`row between ${this.status < 5 && 'inactiveText' }`}>
<p>
5. Complete
</p>
</li>
</ul>
<div class="warning column">
<p>
Warning: do not close the Qortal UI until completion!
</p>
<p class="message-error">${this.errorMsg}</p>
</div>
</div>
<div class="modalFooter">
<mwc-button
slot="primaryAction"
@click=${()=>{
this.openDialogRewardShare = false
this.errorMsg = ''
}}
class="red"
>
${translate("general.close")}
</mwc-button>
</div>
</div>
<!-- </mwc-dialog> -->
</div>
` : ""}
` `
: ''} : ''}
`; `;

View File

@ -37,8 +37,8 @@ export const pageStyles = css`
.message { .message-error {
color: var(--gray); color: var(--error);
} }
@ -62,6 +62,15 @@ export const pageStyles = css`
.row { .row {
display: flex; display: flex;
width: 100%; width: 100%;
align-items: center;
}
.hide {
visibility: hidden
}
.inactiveText {
opacity: .60
} }
.column { .column {
display: flex; display: flex;
@ -156,6 +165,30 @@ export const pageStyles = css`
z-index: 9; z-index: 9;
position: fixed; position: fixed;
} }
.marginLoader {
margin-left: 10px;
}
.marginRight {
margin-right: 10px;
}
.smallLoading,
.smallLoading:after {
border-radius: 50%;
width: 2px;
height: 2px;
}
.smallLoading {
border-width: 0.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;
}
.loading, .loading,
.loading:after { .loading:after {
@ -201,9 +234,9 @@ export const pageStyles = css`
.tableGrid { .tableGrid {
display: grid; display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax( grid-template-columns: minmax(0, 3fr) minmax(0, 1fr) minmax(
0, 0,
1fr 2fr
) minmax(0, 1fr); ) minmax(0, 1fr);
align-items: center; align-items: center;
gap: 5px; gap: 5px;
@ -214,6 +247,16 @@ export const pageStyles = css`
} }
.header {
align-self: flex-start;
}
.header p {
word-break: break-word ;
}
.grid-item { .grid-item {
text-align: center; text-align: center;
@ -267,7 +310,9 @@ export const pageStyles = css`
} }
.word-break {
word-break:break-all;
}
.dialog-container { .dialog-container {
width: 300px; width: 300px;
min-height: 300px; min-height: 300px;
@ -331,6 +376,7 @@ export const pageStyles = css`
text-decoration: none; text-decoration: none;
margin: 0px; margin: 0px;
margin-right: 10px; margin-right: 10px;
word-break: break-word;
} }
.grid-item { .grid-item {
@ -356,4 +402,37 @@ export const pageStyles = css`
grid-column: 1 / -1; grid-column: 1 / -1;
} }
} }
.between {
justify-content: space-between;
}
.no-width {
width: auto
}
.between p {
margin: 0;
padding: 0;
}
#showDialogRewardShareCreationStatus .dialog-container {
width: 300px;
min-height: 250px;
max-height: 75vh;
padding: 5px;
display: flex;
align-items: flex-start;
flex-direction: column;
}
.warning{
display: flex;
flex-grow: 1
}
#showDialogRewardShareCreationStatus li {
margin-bottom: 15px;
}
` `

View File

@ -13,14 +13,27 @@ import "@polymer/paper-spinner/paper-spinner-lite.js"
import "@material/mwc-button" import "@material/mwc-button"
import "@material/mwc-textfield" import "@material/mwc-textfield"
import "@vaadin/button" import "@vaadin/button"
import "@material/mwc-button"
import "@polymer/paper-spinner/paper-spinner-lite.js" import "@polymer/paper-spinner/paper-spinner-lite.js"
import '@material/mwc-dialog' import '@material/mwc-dialog'
import {asyncReplace} from 'lit/directives/async-replace.js';
import { pageStyles } from "./sponsorship-list-css.src.js" import { pageStyles } from "./sponsorship-list-css.src.js"
const parentEpml = new Epml({ type: "WINDOW", source: window.parent }) const parentEpml = new Epml({ type: "WINDOW", source: window.parent })
async function* countDown(count, callback) {
while (count > 0) {
yield count--;
await new Promise((r) => setTimeout(r, 1000));
if(count === 0){
callback()
}
}
}
class SponsorshipList extends LitElement { class SponsorshipList extends LitElement {
static get properties() { static get properties() {
return { return {
@ -32,11 +45,14 @@ class SponsorshipList extends LitElement {
mintingAccountData: { type: Array }, mintingAccountData: { type: Array },
sponsorships: { type: Array }, sponsorships: { type: Array },
removeRewardShareLoading: { type: Array }, removeRewardShareLoading: { type: Array },
createSponsorshipMessage: { type: String }, errorMessage: { type: String },
isLoadingCreateSponsorship: { type: Array }, isLoadingCreateSponsorship: { type: Array },
publicKeyValue: { type: String }, publicKeyValue: { type: String },
error: { type: Boolean }, isOpenModal: {type: Boolean},
isOpenModal: {type: Boolean} status: {type: Number},
privateRewardShareKey: {type: String},
timer: {type: Number},
openDialogRewardShare: {type: Boolean}
} }
} }
@ -54,11 +70,14 @@ class SponsorshipList extends LitElement {
this.mintingAccountData = null this.mintingAccountData = null
this.sponsorships = [] this.sponsorships = []
this.removeRewardShareLoading = false this.removeRewardShareLoading = false
this.error = false
this.createSponsorshipMessage = "" this.errorMessage = ""
this.isLoadingCreateSponsorship = false this.isLoadingCreateSponsorship = false
this.publicKeyValue = "" this.publicKeyValue = ""
this.isOpenModal = false this.isOpenModal = false
this.status = 0
this.privateRewardShareKey = ""
this.openDialogRewardShare = false
} }
inputHandler(e) { inputHandler(e) {
@ -108,9 +127,27 @@ class SponsorshipList extends LitElement {
return nodeInfo return nodeInfo
} }
async saveToClipboard(text) {
try {
await navigator.clipboard.writeText(text)
parentEpml.request('showSnackBar', this.onSuccessMessage)
} catch (err) {
parentEpml.request('showSnackBar', this.onErrorMessage)
console.error('Copy to clipboard error:', err)
}
}
changeStatus(value){
this.status = value
this.saveToClipboard(translate(
"walletpage.wchange4"
))
}
async atMount() { async atMount() {
this.changeLanguage() this.changeLanguage()
this.addressInfo = this.addressInfo =
window.parent.reduxStore.getState().app.accountInfo.addressInfo window.parent.reduxStore.getState().app.accountInfo.addressInfo
this.isPageLoading = true this.isPageLoading = true
@ -119,6 +156,10 @@ class SponsorshipList extends LitElement {
const address = const address =
window.parent.reduxStore.getState().app?.selectedAddress window.parent.reduxStore.getState().app?.selectedAddress
?.address ?.address
let rewardShares = await this.getRewardShareRelationship( let rewardShares = await this.getRewardShareRelationship(
address address
) )
@ -152,6 +193,7 @@ class SponsorshipList extends LitElement {
if(openModal){ if(openModal){
this.shadowRoot.querySelector('#showDialog').show() this.shadowRoot.querySelector('#showDialog').show()
} }
} catch (error) { } catch (error) {
@ -250,18 +292,20 @@ class SponsorshipList extends LitElement {
removeReceiver() removeReceiver()
} }
async createRewardShare(e) { async createRewardShare(publicKeyValue) {
this.error = false this.openDialogRewardShare = true
this.createSponsorshipMessage = ""
const recipientPublicKey = this.publicKeyValue this.privateRewardShareKey = ""
this.errorMessage = ""
const recipientPublicKey = publicKeyValue
const percentageShare = 0 const percentageShare = 0
const selectedAddress = const selectedAddress =
window.parent.reduxStore.getState().app?.selectedAddress window.parent.reduxStore.getState().app?.selectedAddress
// Check for valid... // Check for valid...
this.isLoadingCreateSponsorship = true this.isLoadingCreateSponsorship = true
let recipientAddress =
window.parent.base58PublicKeyToAddress(recipientPublicKey)
// Get Last Ref // Get Last Ref
const getLastRef = async () => { const getLastRef = async () => {
@ -281,96 +325,39 @@ class SponsorshipList extends LitElement {
return myAccountDetails return myAccountDetails
} }
// Get Reward Relationship if it already exists
const getRewardShareRelationship = async (minterAddr) => {
let isRewardShareExisting = false
let myRewardShareArray = await parentEpml.request("apiCall", {
type: "api",
url: `/addresses/rewardshares?minters=${minterAddr}&recipients=${recipientAddress}`,
})
isRewardShareExisting =
myRewardShareArray.length !== 0 ? true : false
return isRewardShareExisting
}
// Validate Reward Share by Level // Validate Reward Share by Level
const validateReceiver = async () => { const validateReceiver = async () => {
let accountDetails = await getAccountDetails() let accountDetails
let lastRef = await getLastRef() try {
let isExisting = await getRewardShareRelationship( accountDetails = await getAccountDetails()
selectedAddress.address } catch (error) {
) this.errorMessage = "Couldn't fetch account details"
// Check for creating self share at different levels (also adding check for flags...)
if (accountDetails.flags === 1) {
this.error = false
this.createSponsorshipMessage = ""
let myTransaction = await makeTransactionRequest(lastRef)
if (isExisting === true) {
this.error = true
this.createSponsorshipMessage = `Cannot Create Multiple Reward Shares!`
} else {
// Send the transaction for confirmation by the user
this.error = false
this.createSponsorshipMessage = ""
getTxnRequestResponse(myTransaction)
}
} else if (accountDetails.address === recipientAddress) {
if (accountDetails.level >= 1 && accountDetails.level <= 4) {
this.error = false
this.createSponsorshipMessage = ""
let myTransaction = await makeTransactionRequest(lastRef)
if (isExisting === true) {
let err1string = get("rewardsharepage.rchange18")
this.error = true
this.createSponsorshipMessage = `${err1string}`
} else {
// Send the transaction for confirmation by the user
this.error = false
this.createSponsorshipMessage = ""
getTxnRequestResponse(myTransaction)
}
} else if (accountDetails.level >= 5) {
this.error = false
this.createSponsorshipMessage = ""
let myTransaction = await makeTransactionRequest(lastRef)
if (isExisting === true) {
let err2string = get("rewardsharepage.rchange19")
this.error = true
this.createSponsorshipMessage = `${err2string}`
} else {
// Send the transaction for confirmation by the user
this.error = false
this.createSponsorshipMessage = ""
getTxnRequestResponse(myTransaction)
}
} else {
let err3string = get("rewardsharepage.rchange20")
this.error = true
this.createSponsorshipMessage = `${err3string} ${accountDetails.level}`
}
} else {
//Check for creating reward shares
if (accountDetails.level >= 5) {
this.error = false
this.createSponsorshipMessage = ""
let myTransaction = await makeTransactionRequest(lastRef)
if (isExisting === true) {
let err4string = get("rewardsharepage.rchange18")
this.error = true
this.createSponsorshipMessage = `${err4string}`
} else {
// Send the transaction for confirmation by the user
this.error = false
this.createSponsorshipMessage = ""
getTxnRequestResponse(myTransaction)
}
} else {
this.error = true
let err5string = get("rewardsharepage.rchange20")
this.createSponsorshipMessage = `${err5string} ${accountDetails.level}`
}
} }
let lastRef = await getLastRef()
if (accountDetails.level >= 5) {
this.status = 1
this.errorMessage = ""
try {
const myTransaction = await makeTransactionRequest(lastRef)
getTxnRequestResponse(myTransaction)
} catch (error) {
this.errorMessage = error?.message || 'Error creating relationship'
}
} else {
let err5string = get("rewardsharepage.rchange20")
this.errorMessage = `${err5string} ${accountDetails.level}`
}
} }
// Make Transaction Request // Make Transaction Request
@ -397,30 +384,81 @@ class SponsorshipList extends LitElement {
} }
const getTxnRequestResponse = (txnResponse) => { const getTxnRequestResponse = (txnResponse) => {
if(txnResponse.message.includes('multiple')){
this.isLoadingCreateSponsorship = false
this.privateRewardShareKey = txnResponse.data
this.confirmRelationship(recipientPublicKey)
}
if (txnResponse.success === false && txnResponse.message) { if (txnResponse.success === false && txnResponse.message) {
this.error = true
this.createSponsorshipMessage = txnResponse.message this.errorMessage = txnResponse.message
throw new Error(txnResponse) this.isLoadingCreateSponsorship = false
throw(txnResponse)
} else if ( } else if (
txnResponse.success === true && txnResponse.success === true &&
!txnResponse.data.error !txnResponse.data.error
) { ) {
let err6string = get("rewardsharepage.rchange21")
this.createSponsorshipMessage = err6string this.isLoadingCreateSponsorship = false
this.error = false
this.privateRewardShareKey = txnResponse.data
this.confirmRelationship()
} else { } else {
this.error = true
this.createSponsorshipMessage = txnResponse.data.message this.errorMessage = txnResponse.data.message
throw new Error(txnResponse) this.isLoadingCreateSponsorship = false
throw(txnResponse)
} }
} }
validateReceiver() validateReceiver()
this.isLoadingCreateSponsorship = false
} }
render() {
async confirmRelationship(recipientPublicKey){
let interval = null
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}`,
})
if(myRewardShareArray.length > 0){
clearInterval(interval)
this.status = 3
this.timer = countDown(180, ()=> this.changeStatus(4));
}
} catch (error) {
console.error(error)
}
stop = false
}
};
interval = setInterval(getAnswer, 2000);
}
render() {
console.log({sponsors: this.sponsorships})
return html` return html`
${ ${
this.isPageLoading this.isPageLoading
@ -452,17 +490,17 @@ class SponsorshipList extends LitElement {
<p>${translate("sponsorshipspage.schange1")}</p> <p>${translate("sponsorshipspage.schange1")}</p>
</div> </div>
<div class="tableGrid table-header"> <div class="tableGrid table-header">
<div class="grid-item"> <div class="grid-item header">
<p>${translate("sponsorshipspage.schange2")}</p> <p>${translate("sponsorshipspage.schange2")}</p>
</div> </div>
<div class="grid-item"> <div class="grid-item header">
<p>${translate("walletprofile.blocksminted")}</p> <p>${translate("walletprofile.blocksminted")}</p>
</div> </div>
<div class="grid-item"> <div class="grid-item header">
<p>${translate("becomeMinterPage.bchange17")}</p> <p>${translate("becomeMinterPage.bchange17")}</p>
</div> </div>
<div class="grid-item"> <div class="grid-item header">
</div> </div>
</div> </div>
@ -472,33 +510,25 @@ class SponsorshipList extends LitElement {
(sponsorship) => html` (sponsorship) => html`
<ul class="tableGrid"> <ul class="tableGrid">
<li class="grid-item"> <li class="grid-item">
<p class="grid-item-text">
Account Address
</p>
${sponsorship.address} ${sponsorship.address}
</li> </li>
<li class="grid-item"> <li class="grid-item">
<p class="grid-item-text">
Blocks Minted
</p>
${+sponsorship.blocksMinted + ${+sponsorship.blocksMinted +
+sponsorship.blocksMintedAdjustment} +sponsorship.blocksMintedAdjustment}
</li> </li>
<li class="grid-item"> <li class="grid-item">
<p class="grid-item-text">
Copy Sponsorship Key
</p>
<button-icon-copy <mwc-button @click=${()=> this.createRewardShare(sponsorship.publicKey)}>copy</mwc-button>
title="${translate(
"becomeMinterPage.bchange17"
)}"
onSuccessMessage="${translate(
"walletpage.wchange4"
)}"
onErrorMessage="${translate(
"walletpage.wchange39"
)}"
textToCopy=${sponsorship.rewardSharePublicKey}
buttonSize="28px"
iconSize="16px"
color="var(--copybutton)"
offsetLeft="4px"
></button-icon-copy>
</li> </li>
<li class="grid-item grid-item-button"> <li class="grid-item grid-item-button">
<mwc-button <mwc-button
@ -540,7 +570,7 @@ class SponsorshipList extends LitElement {
</div> </div>
` `
: ''} : ''}
<p class="message">${this.createSponsorshipMessage}</p> <p class="message-error">${this.errorMessage}</p>
<div class="form-wrapper"> <div class="form-wrapper">
<div class="sponsor-minter-wrapper"> <div class="sponsor-minter-wrapper">
<p class="sponsor-minter-text">${translate("sponsorshipspage.schange5")}</p> <p class="sponsor-minter-text">${translate("sponsorshipspage.schange5")}</p>
@ -559,17 +589,11 @@ class SponsorshipList extends LitElement {
<div class="form-item form-item--button"> <div class="form-item form-item--button">
<vaadin-button <vaadin-button
?disabled="${this.isLoadingCreateSponsorship || !this.publicKeyValue}" ?disabled="${this.isLoadingCreateSponsorship || !this.publicKeyValue}"
@click="${this.createRewardShare}" @click="${()=> this.createRewardShare(this.publicKeyValue)}"
> >
${ ${translate(
this.isLoadingCreateSponsorship === false
? html`${translate(
"puzzlepage.pchange15" "puzzlepage.pchange15"
)}` )}
: html`<paper-spinner-lite
active
></paper-spinner-lite>`
}
</vaadin-button> </vaadin-button>
</div> </div>
</div> </div>
@ -598,6 +622,84 @@ class SponsorshipList extends LitElement {
${translate("general.close")} ${translate("general.close")}
</mwc-button> </mwc-button>
</mwc-dialog>
<mwc-dialog escapeKeyAction="" scrimClickAction="" id="showDialogRewardShareCreationStatus" ?hideActions=${this.errorMessage ? false : this.status < 4 ? true : false} ?open=${this.openDialogRewardShare}>
<div class="dialog-header" >
<div class="row">
<h1>In progress </h1> <div class=${`smallLoading marginLoader ${this.status > 3 && 'hide'}`}></div>
</div>
<hr />
</div>
<div class="dialog-container">
<ul>
<li class="row between">1. Creating relationship <div class=${`smallLoading marginLoader ${this.status !== 1 && 'hide'}`}></div></li>
<li class=${`row between ${this.status < 2 && 'inactiveText' }`}>
<p>
2. Awaiting confirmation on blockchain
</p>
<div class=${`smallLoading marginLoader ${this.status !== 2 && 'hide'}`}></div>
</li>
<li class=${`row between ${this.status < 3 && 'inactiveText' }`}>
<p>
3. Finishing up
</p>
<div class="row no-width">
<div class=${`smallLoading marginLoader marginRight ${this.status !== 3 && 'hide'}`} ></div> ${asyncReplace(this.timer)}
</div>
</li>
<li class=${`row between ${this.status < 4 && 'inactiveText' }`}>
<p>
4. Complete
</p>
</li>
${this.privateRewardShareKey && this.status === 4 ? html`
<li class=${`column word-break ${this.status < 4 && 'inactiveText' }`}>
<p>Copy the key below and share it with your sponsored person.</p>
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.privateRewardShareKey}</span>
</div>
</li>
` : ''}
</ul>
<div class="warning column">
<p>
Warning: do not close the Qortal UI until completion!
</p>
<p class="message-error">${this.errorMessage}</p>
</div>
</div>
<mwc-button
slot="primaryAction"
@click=${()=>{
this.openDialogRewardShare = false
this.errorMessage = ''
this.isLoadingCreateSponsorship = false
this.privateRewardShareKey = ""
}}
class="red"
>
${translate("general.close")}
</mwc-button>
</mwc-dialog> </mwc-dialog>
</div> </div>
` `