Skip to content

Commit

Permalink
PIVX Promos integration (#124)
Browse files Browse the repository at this point in the history
* Full Redeem implementation and UI

* Hide redeem button during redeems

* Upgrade to PIVX Promos v0.2.0, optimise redeems

* Implement basic Promo Code Creation

* [HTML, CSS, JS] More responsive and animated

* [JS] Supress small error when element is not found

* Prettify + improve Create UX

* Add DB persistance to the Promo Creator

* Add code tracking + UX fixes

* Add CSS, copy button and explorer link to codes

* fix: Smooth table animation

* Move promo fee to a const

* Fix update ticks

* Add Entropy system + UX Sanity checks

* fix: Don't allow deleting Unclaimed codes

* fix: Unlock prompting and render-skipping

* Explain the promo creation unlock prompt

* Split from global.js to promos.js for #134

* fix: state update bugs

---------

Co-authored-by: BreadJS <[email protected]>
  • Loading branch information
JSKitty and BreadJS committed Jun 2, 2023
1 parent 62be767 commit eea8346
Show file tree
Hide file tree
Showing 13 changed files with 1,006 additions and 27 deletions.
54 changes: 54 additions & 0 deletions assets/style/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,45 @@ button {
transition: all .2s ease-in-out;
}

progress {
color: #7300ff;
border-radius: 6px;
border: none;
}

progress[value]::-webkit-progress-value {
background-image: -webkit-linear-gradient(
top,
rgba(255, 255, 255, 0.25),
rgba(0, 0, 0, 0.25)
),
-webkit-linear-gradient(
left,
#380c6a,
#7300ff
);

border-radius: 6px;
background-size: 35px 20px, 100% 100%, 100% 100%;
}

progress[value]::-moz-progress-bar {
background-image:
-moz-linear-gradient(
top,
rgba(255, 255, 255, 0.25),
rgba(0, 0, 0, 0.25)
),
-moz-linear-gradient(
left,
#380c6a,
#7300ff
);

border-radius: 6px;
background-size: 35px 20px, 100% 100%, 100% 100%;
}

.hide-element {
width: 0px;
height: 0px;
Expand Down Expand Up @@ -289,6 +328,10 @@ button {
border-radius: 8px;
}

.mono {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !important;
}

/* a bootstrap override */
.modal-footer {
display: block !important;
Expand Down Expand Up @@ -2711,6 +2754,17 @@ input {
background: #696969;
}

@media (min-width: 768px) {
.max-w-600 {
max-width: 600px;
}
}

.table-promo {
transition:all 0.5s ease-in-out;
max-height: 0px;
}

select.form-control {
color: #ffffff;
background-color: rgba(255, 255, 255, 18%);
Expand Down
89 changes: 88 additions & 1 deletion index.template.html
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ <h5 class="modal-title" id="walletBreakdownModalLabel">Wallet Breakdown</h5>
<br />
<!-- // CONFIRM MODAL -->
<div class="modal" id="confirmModal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered" role="document" style="max-width: 600px;">
<div class="modal-dialog modal-dialog-centered max-w-600" role="document">
<div class="modal-content">
<div class="modal-header" id="confirmModalHeader">
<h3 class="modal-title" id="confirmModalTitle" style="text-align: center; width: 100%; color: #8e21ff;"></h3>
Expand Down Expand Up @@ -426,6 +426,90 @@ <h5 class="modal-title" id="encryptWalletLabel">Encrypt wallet</h5>
</div>
<!-- // Lock Wallet -->

<!-- Redeem Code (PIVX Promos) -->
<div class="modal" id="redeemCodeModal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered max-w-600" role="document">
<div class="modal-content">
<div class="modal-header" id="redeemCodeModalHeader">
<h3 class="modal-title" id="redeemCodeModalTitle" style="text-align: center; width: 100%; color: #8e21ff;">Redeem Code</h3>
</div>
<div class="modal-body center-text">
<center>
<p class="mono" style="font-size: small;">
<b>PIVX Promos</b> is a decentralised system for gift codes worth PIV
</p>
<div id="redeemCodeModeBox">
<button type="button" onclick="MPW.setPromoMode(true)" id="redeemCodeModeRedeem" class="pivx-button-big" style="margin: 0;border-top-right-radius: 0;border-bottom-right-radius: 0;opacity: 0.5;">Redeem</button>
<button type="button" onclick="MPW.setPromoMode(false)" id="redeemCodeModeCreate" class="pivx-button-big" style="margin: 0;border-top-left-radius: 0;border-bottom-left-radius: 0;opacity: 0.8;">Create</button>
</div>
<br>
<br>
<div id="redeemCodeUse">
<div class="col-8" id="redeemCodeInputBox">
<div class="input-group" style="border-color: #9121ff;border-style: solid;border-radius: 10px;">
<input class="btn-group-input mono center-text" type="text" id="redeemCodeInput" placeholder="Enter your 'PIVX Promos' code" autocomplete="nope" />
<div class="input-group-append">
<span class="input-group-text ptr" onclick="MPW.openPromoQRScanner()"><i class="fa-solid fa-qrcode fa-2xl"></i></span>
</div>
</div>
</div>
<center>
<div id="redeemCodeGiftIconBox" style="display: none;">
<br>
<br>
<i id="redeemCodeGiftIcon" onclick="MPW.sweepPromoCode();" class="fa-solid fa-gift fa-2xl" style="color: #813d9c; font-size: 4em;"></i>
</div>

<p id="redeemCodeETA" style="margin-bottom: 0; display: none;">
<br><br>
</p>
<progress id="redeemCodeProgress" min="0" max="100" value="50" style="display: none"></progress>
</center>
</div>
<div id="redeemCodeCreate" style="display: none;">
<div class="col-11">
<div class="row">
<div class="col-6" style="padding-right:3px;">
<div class="input-group" style="border-color: #9121ff;border-style: solid;border-radius: 10px;">
<input class="btn-group-input mono center-text" style="border-top-right-radius: 9px; border-bottom-right-radius: 9px;" type="text" id="redeemCodeCreateInput" placeholder="Promo Name (Optional)" autocomplete="nope" />
</div>
</div>
<div class="col-6" style="padding-left:3px;">
<div class="input-group" style="border-color: #9121ff;border-style: solid;border-radius: 10px;">
<input class="btn-group-input mono center-text" style="border-top-right-radius: 9px; border-bottom-right-radius: 9px;" type="text" id="redeemCodeCreateAmountInput" placeholder="Promo Amount" autocomplete="nope" />
</div>
</div>
</div>
</div>
<div class="table-promo d-none" id="promo-table">
<br>
<table class="table table-hover">
<thead>
<tr>
<td class="text-center"><b> Manage </b></td>
<td class="text-center"><b> Promo Code </b></td>
<td class="text-center"><b> Amount </b></td>
<td class="text-center"><b> State </b></td>
</tr>
</thead>
<tbody id="redeemCodeCreatePendingList" style="text-align: center; vertical-align: middle;">

</tbody>
</table>
</div>
</div>
<br>
</center>
</div>
<div class="modal-footer" hidden="true" id="redeemCodeModalButtons">
<button type="button" onclick="MPW.promoConfirm()" id="redeemCodeModalConfirmButton" class="pivx-button-big" style="float: right;">Redeem</button>
<button type="button" data-dismiss="modal" aria-label="Close" class="pivx-button-big" style="float: right; opacity: 0.7;">Close</button>
</div>
</div>
</div>
</div>
<!-- // Redeem Code (PIVX Promos) -->

<!-- WALLET FEATURES -->
<div id="guiWallet" style="display: none;">
<div class="row p-0">
Expand Down Expand Up @@ -459,6 +543,9 @@ <h3 class="noselect balance-title">
<a class="dropdown-item ptr" id="guiNewAddress" data-toggle="modal" data-target="#qrModal" onclick="MPW.getNewAddress({updateGUI: true, verify: true});">
<i class="fas fa-sync-alt"></i> Refresh address
</a>
<a class="dropdown-item ptr" data-toggle="modal" data-target="#redeemCodeModal">
<i class="fa-solid fa-gift"></i> Redeem or Create Code
</a>
</div>
</div>
</div>
Expand Down
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"jdenticon": "^3.2.0",
"jquery": "^3.6.3",
"lodash-es": "^4.17.21",
"pivx-promos": "^0.2.0",
"qr-scanner": "^1.4.2",
"qrcode-generator": "^1.4.4"
},
Expand Down
47 changes: 46 additions & 1 deletion scripts/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import Masternode from './masternode.js';
import { Settings } from './settings.js';
import { cChainParams } from './chain_params.js';
import { confirmPopup, sanitizeHTML, createAlert } from './misc.js';
import { PromoWallet } from './promos.js';

/** The current version of the DB - increasing this will prompt the Upgrade process for clients with an older version */
export const DB_VERSION = 2;

/**
*
Expand Down Expand Up @@ -52,6 +56,28 @@ export class Database {
await store.delete('masternode');
}

/**
* Add Promo Code to the database for tracking and management
* @param {PromoWallet} promo
*/
async addPromo(promo) {
const store = this.#db
.transaction('promos', 'readwrite')
.objectStore('promos');
// The plaintext code is our key, since codes are unique and deterministic anyway
await store.put(promo, promo.code);
}
/**
* Removes a Promo Code from the Promo management system
* @param {string} promo - the promo code to remove
*/
async removePromo(promo) {
const store = this.#db
.transaction('promos', 'readwrite')
.objectStore('promos');
await store.delete(promo);
}

/**
* Adds an account to the database
* @param {Object} o
Expand Down Expand Up @@ -103,6 +129,17 @@ export class Database {
return new Masternode(await store.get('masternode'));
}

/**
* @returns {Promise<Array<PromoWallet>>} all Promo Codes stored in the db
*/
async getAllPromos() {
const store = this.#db
.transaction('promos', 'readonly')
.objectStore('promos');
// Convert all promo objects in to their Class and return them as a new array
return (await store.getAll()).map((promo) => new PromoWallet(promo));
}

/**
* @returns {Promise<Settings>}
*/
Expand Down Expand Up @@ -190,14 +227,22 @@ export class Database {
static async create(name) {
let migrate = false;
const database = new Database({ db: null });
const db = await openDB(`MPW-${name}`, 1, {
const db = await openDB(`MPW-${name}`, DB_VERSION, {
upgrade: (db, oldVersion) => {
console.log(
'DB: Upgrading from ' + oldVersion + ' to ' + DB_VERSION
);
if (oldVersion == 0) {
db.createObjectStore('masternodes');
db.createObjectStore('accounts');
db.createObjectStore('settings');
migrate = true;
}

// The introduction of PIVXPromos (safely added during <v2 upgrades)
if (oldVersion <= 1) {
db.createObjectStore('promos');
}
},
blocking: () => {
// Another instance is waiting to upgrade, and we're preventing it
Expand Down
Loading

0 comments on commit eea8346

Please sign in to comment.