1.0.2 Major UI change | Neater layout

This commit is contained in:
Vivek Teega 2022-03-27 15:50:30 +05:30
parent dd6b8b1b82
commit fdf3d4c21b
8 changed files with 5221 additions and 3652 deletions

View File

@ -1,3 +1,13 @@
/*
Add CSS variables here to change CSS of components
Suppose you want to customize button from component, just add
sm-button {
--background : #CCC;
}
*/
* {
padding: 0;
margin: 0;
@ -9,7 +19,8 @@
font-size: clamp(1rem, 1.2vmax, 3rem);
}
html, body {
html,
body {
height: 100%;
scroll-behavior: smooth;
}
@ -20,15 +31,15 @@ body {
}
body,
body * {
--accent-color: #0D7377;
--accent-color: #0d7377;
--text-color: 17, 17, 17;
--background-color: 255, 255, 255;
--danger-color: red;
}
body[data-theme=dark],
body[data-theme=dark] * {
--accent-color: #32E0C4;
body[data-theme="dark"],
body[data-theme="dark"] * {
--accent-color: #32e0c4;
--text-color: 240, 240, 240;
--text-color-light: 170, 170, 170;
--background-color: 10, 10, 10;
@ -315,15 +326,30 @@ ul {
margin-left: auto;
}
h1,
h2,
h3,
h4.h5 {
font-family: "Poppins", sans-serif;
}
h2 {
margin: 3rem 0 1rem 0;
text-transform: capitalize;
}
main {
display: grid;
height: 100%;
grid-template-rows: auto 1fr auto;
grid-template-areas: "main-header" "." "side-nav";
}
#main_header {
display: flex;
gap: 1rem;
align-items: center;
position: sticky;
grid-area: main-header;
padding: 1rem 1.5rem;
background: rgba(var(--background-color), 1);
border-bottom: solid 1px rgba(var(--text-color), 0.16);
z-index: 2;
border-bottom: 1px solid rgba(var(--text-color), 0.1);
gap:0.5rem;
}
#logo {
@ -338,12 +364,6 @@ ul {
text-transform: capitalize;
font-size: 1rem;
font-weight: 600;
margin-top: 0.2rem;
}
#logo h5 {
font-size: 0.8rem;
font-family: "Roboto", sans-serif;
font-weight: 400;
}
#logo #main_logo {
height: 1.4rem;
@ -352,46 +372,144 @@ ul {
stroke: none;
}
sm-tab-header {
padding: 0 1.5rem;
background-color: rgba(var(--text-color), 0.06);
.right {
max-height: 100%;
overflow-y: auto;
}
sm-tab {
padding: 0.5rem 0.8rem;
#side_nav {
grid-area: side-nav;
}
#side_nav h4 {
font-size: 0.9rem;
letter-spacing: 0.08em;
text-transform: uppercase;
padding: 1.5rem;
}
.section {
.nav-list {
list-style: none;
display: flex;
justify-content: space-evenly;
}
.nav-list li {
width: 100%;
}
.nav-list__item {
display: flex;
padding: 0.8rem 1.5rem;
text-transform: capitalize;
}
.nav-list__item--active {
color: var(--accent-color);
}
.nav-list__item--active .icon {
fill: var(--accent-color);
}
.right {
padding: 1.5rem;
}
.right h1 {
margin-bottom: 1.5rem;
}
.page {
display: flex;
flex-direction: column;
margin-top: 3rem;
padding: 0 1.5rem;
}
.section:first-of-type {
margin-top: 0;
padding-bottom: 3rem;
}
.section__header {
display: flex;
padding: 1rem 0;
justify-content: space-between;
.card-wrapper {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
gap: 1.5rem;
}
.card {
padding: 1.5rem;
display: flex;
flex-direction: column;
min-width: 20rem;
border-radius: 0.5rem;
margin-right: 1.5rem;
background-color: rgba(var(--text-color), 0.06);
}
.card h3 {
font-weight: 500;
}
@media screen and (max-width: 640px) {
main {
grid-template-rows: auto 1fr;
grid-template-columns: 1fr;
}
.nav-list__item {
flex-direction: column;
justify-content: center;
align-items: center;
padding: 0.4rem;
}
.nav-list__item span {
font-size: 0.8rem;
margin-top: 0.3rem;
}
}
@media screen and (min-width: 640px) {
sm-popup {
--width: 24rem;
--width: 32rem;
}
}
main {
grid-template-columns: 14rem minmax(0, 1fr);
grid-template-rows: auto 1fr;
grid-template-areas: "main-header main-header" "side-nav .";
}
.nav-list {
flex-direction: column;
}
.nav-list__item {
align-items: center;
justify-content: start;
}
.nav-list__item--active {
background: rgba(var(--text-color), 0.06);
}
.nav-list__item .icon {
margin-right: 0.5rem;
}
.right {
display: grid;
grid-template-columns: 1fr 90% 1fr;
}
.right > * {
grid-column: 2/3;
}
.page__title {
font-size: 2.5rem;
}
}
@media (any-hover: hover) {
::-webkit-scrollbar {
width: 0.5rem;
height: 0.5rem;
}
::-webkit-scrollbar-thumb {
background: rgba(var(--text-color), 0.3);
border-radius: 1rem;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(var(--text-color), 0.5);
}
.nav-list__item:hover {
background: rgba(var(--text-color), 0.1);
cursor: pointer;
}
}

File diff suppressed because one or more lines are too long

2
css/main.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -257,15 +257,24 @@ ul{
}
}
}
h1,h2,h3,h4.h5{
font-family: 'Poppins', sans-serif;
}
h2{
margin: 3rem 0 1rem 0;
text-transform: capitalize;
}
main{
display: grid;
height: 100%;
grid-template-rows: auto 1fr auto;
grid-template-areas: 'main-header' '.' 'side-nav';
}
#main_header{
display: flex;
gap: 1rem;
align-items: center;
position: sticky;
grid-area: main-header;
padding: 1rem 1.5rem;
background: rgba(var(--background-color), 1);
border-bottom: solid 1px rgba(var(--text-color), 0.16);
z-index: 2;
border-bottom: 1px solid rgba(var(--text-color), .1);
}
#logo{
display: grid;
@ -278,12 +287,6 @@ ul{
text-transform: capitalize;
font-size: 1rem;
font-weight: 600;
margin-top: 0.2rem;
}
h5{
font-size: 0.8rem;
font-family: 'Roboto', sans-serif;
font-weight: 400;
}
#main_logo{
height: 1.4rem;
@ -292,43 +295,113 @@ ul{
stroke: none;
}
}
sm-tab-header{
padding: 0 1.5rem;
background-color: rgba(var(--text-color), 0.06);
.right{
max-height: 100%;
overflow-y: auto;
}
sm-tab{
padding: 0.5rem 0.8rem;
}
.section{
display: flex;
flex-direction: column;
margin-top: 3rem;
padding: 0 1.5rem;
&:first-of-type{
margin-top: 0;
#side_nav{
grid-area: side-nav;
h4{
font-size: 0.9rem;
letter-spacing: 0.08em;
text-transform: uppercase;
padding: 1.5rem;
}
}
.section__header{
.nav-list{
list-style: none;
display: flex;
padding: 1rem 0;
justify-content: space-between;
justify-content: space-evenly;
li{
width: 100%;
}
}
.card{
.nav-list__item{
display: flex;
padding: 0.8rem 1.5rem;
text-transform: capitalize;
&--active{
color: var(--accent-color);
.icon{
fill: var(--accent-color);
}
}
}
.right{
padding: 1.5rem;
display: flex;
flex-direction: column;
min-width: 20rem;
border-radius: 0.5rem;
margin-right: 1.5rem;
background-color: rgba(var(--text-color), 0.06);
h3{
font-weight: 500;
h1{
margin-bottom: 1.5rem;
}
}
@media screen and (min-width: 640px) {
// for tablet and desktop
.page{
display: flex;
flex-direction: column;
padding-bottom: 3rem;
}
@media screen and (max-width: 640px){
main{
grid-template-rows: auto 1fr;
grid-template-columns: 1fr;
}
.nav-list__item{
flex-direction: column;
justify-content: center;
align-items: center;
padding: 0.4rem;
span{
font-size: 0.8rem;
margin-top: 0.3rem;
}
}
}
@media screen and (min-width: 640px){
sm-popup{
--width: 24rem;
--width: 32rem;
}
main{
grid-template-columns: 14rem minmax(0, 1fr);
grid-template-rows: auto 1fr;
grid-template-areas: 'main-header main-header' 'side-nav .';
}
.nav-list{
flex-direction: column;
}
.nav-list__item{
align-items: center;
justify-content: start;
&--active{
background: rgba(var(--text-color), .06);
}
.icon{
margin-right: 0.5rem;
}
}
.right{
display: grid;
grid-template-columns: 1fr 90% 1fr;
& > * {
grid-column: 2/3;
}
}
.page__title{
font-size: 2.5rem;
}
}
@media (any-hover: hover){
::-webkit-scrollbar{
width: 0.5rem;
height: 0.5rem;
}
::-webkit-scrollbar-thumb{
background: rgba(var(--text-color), 0.3);
border-radius: 1rem;
&:hover{
background: rgba(var(--text-color), 0.5);
}
}
.nav-list__item:hover{
background: rgba(var(--text-color), .1);
cursor: pointer;
}
}

7841
index.html

File diff suppressed because it is too large Load Diff

11
js/components.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,645 +0,0 @@
//console.log(document.cookie.toString());
const INVALID_SERVER_MSG = "INCORRECT_SERVER_ERROR";
var nodeList, nodeURL, nodeKBucket; //Container for (backup) node list
function exchangeAPI(api, options) {
return new Promise((resolve, reject) => {
let curPos = exchangeAPI.curPos || 0;
if (curPos >= nodeList.length)
return resolve('No Nodes online');
let url = "https://" + nodeURL[nodeList[curPos]];
(options ? fetch(url + api, options) : fetch(url + api))
.then(result => resolve(result)).catch(error => {
console.warn(nodeList[curPos], 'is offline');
//try next node
exchangeAPI.curPos = curPos + 1;
exchangeAPI(api, options)
.then(result => resolve(result))
.catch(error => reject(error))
});
})
}
function ResponseError(status, data) {
if (data === INVALID_SERVER_MSG)
location.reload();
else if (this instanceof ResponseError) {
this.data = data;
this.status = status;
} else
return new ResponseError(status, data);
}
function responseParse(response, json_ = true) {
return new Promise((resolve, reject) => {
if (!response.ok)
response.text()
.then(result => reject(ResponseError(response.status, result)))
.catch(error => reject(error));
else if (json_)
response.json()
.then(result => resolve(result))
.catch(error => reject(error));
else
response.text()
.then(result => resolve(result))
.catch(error => reject(error));
});
}
function getAccount(floID, proxySecret) {
return new Promise((resolve, reject) => {
let request = {
floID: floID,
timestamp: Date.now()
};
if (floCrypto.getFloID(proxySecret) === floID) //Direct signing (without proxy)
request.pubKey = floCrypto.getPubKeyHex(proxySecret);
request.sign = signRequest({
type: "get_account",
timestamp: request.timestamp
}, proxySecret);
console.debug(request);
exchangeAPI('/account', {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
}).then(result => responseParse(result)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error));
});
}
function getBuyList() {
return new Promise((resolve, reject) => {
exchangeAPI('/list-buyorders')
.then(result => responseParse(result)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error));
});
}
function getSellList() {
return new Promise((resolve, reject) => {
exchangeAPI('/list-sellorders')
.then(result => responseParse(result)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error));
});
}
function getTradeList() {
return new Promise((resolve, reject) => {
exchangeAPI('/list-trades')
.then(result => responseParse(result)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error));
});
}
function getRates(asset = null) {
return new Promise((resolve, reject) => {
exchangeAPI('/get-rates' + (asset ? "?asset=" + asset : ""))
.then(result => responseParse(result)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error));
});
}
function getBalance(floID = null, token = null) {
return new Promise((resolve, reject) => {
if (!floID && !token)
return reject("Need atleast one argument")
let queryStr = (floID ? "floID=" + floID : "") +
(floID && token ? "&" : "") +
(token ? "token=" + token : "");
exchangeAPI('/get-balance?' + queryStr)
.then(result => responseParse(result)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error));
})
}
function getTx(txid) {
return new Promise((resolve, reject) => {
if (!txid)
return reject('txid required');
exchangeAPI('/get-transaction?txid=' + txid)
.then(result => responseParse(result)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error));
})
}
function signRequest(request, signKey) {
if (typeof request !== "object")
throw Error("Request is not an object");
let req_str = Object.keys(request).sort().map(r => r + ":" + request[r]).join("|");
return floCrypto.signData(req_str, signKey);
}
function getLoginCode() {
return new Promise((resolve, reject) => {
exchangeAPI('/get-login-code')
.then(result => responseParse(result)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error));
})
}
/*
function signUp(privKey, code, hash) {
return new Promise((resolve, reject) => {
if (!code || !hash)
return reject("Login Code missing")
let request = {
pubKey: floCrypto.getPubKeyHex(privKey),
floID: floCrypto.getFloID(privKey),
code: code,
hash: hash,
timestamp: Date.now()
};
request.sign = signRequest({
type: "create_account",
random: code,
timestamp: request.timestamp
}, privKey);
console.debug(request);
exchangeAPI("/signup", {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
}).then(result => responseParse(result, false)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error));
});
}
*/
function login(privKey, proxyKey, code, hash) {
return new Promise((resolve, reject) => {
if (!code || !hash)
return reject("Login Code missing")
let request = {
proxyKey: proxyKey,
floID: floCrypto.getFloID(privKey),
pubKey: floCrypto.getPubKeyHex(privKey),
timestamp: Date.now(),
code: code,
hash: hash
};
if (!privKey || !request.floID)
return reject("Invalid Private key");
request.sign = signRequest({
type: "login",
random: code,
proxyKey: proxyKey,
timestamp: request.timestamp
}, privKey);
console.debug(request);
exchangeAPI("/login", {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
}).then(result => responseParse(result, false)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error));
})
}
function logout(floID, proxySecret) {
return new Promise((resolve, reject) => {
let request = {
floID: floID,
timestamp: Date.now()
};
if (floCrypto.getFloID(proxySecret) === floID) //Direct signing (without proxy)
request.pubKey = floCrypto.getPubKeyHex(proxySecret);
request.sign = signRequest({
type: "logout",
timestamp: request.timestamp
}, proxySecret);
console.debug(request);
exchangeAPI("/logout", {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
}).then(result => responseParse(result, false)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error))
})
}
function buy(asset, quantity, max_price, floID, proxySecret) {
return new Promise((resolve, reject) => {
if (typeof quantity !== "number" || quantity <= 0)
return reject(`Invalid quantity (${quantity})`);
else if (typeof max_price !== "number" || max_price <= 0)
return reject(`Invalid max_price (${max_price})`);
let request = {
floID: floID,
asset: asset,
quantity: quantity,
max_price: max_price,
timestamp: Date.now()
};
if (floCrypto.getFloID(proxySecret) === floID) //Direct signing (without proxy)
request.pubKey = floCrypto.getPubKeyHex(proxySecret);
request.sign = signRequest({
type: "buy_order",
asset: asset,
quantity: quantity,
max_price: max_price,
timestamp: request.timestamp
}, proxySecret);
console.debug(request);
exchangeAPI('/buy', {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
}).then(result => responseParse(result, false)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error))
})
}
function sell(asset, quantity, min_price, floID, proxySecret) {
return new Promise((resolve, reject) => {
if (typeof quantity !== "number" || quantity <= 0)
return reject(`Invalid quantity (${quantity})`);
else if (typeof min_price !== "number" || min_price <= 0)
return reject(`Invalid min_price (${min_price})`);
let request = {
floID: floID,
asset: asset,
quantity: quantity,
min_price: min_price,
timestamp: Date.now()
};
if (floCrypto.getFloID(proxySecret) === floID) //Direct signing (without proxy)
request.pubKey = floCrypto.getPubKeyHex(proxySecret);
request.sign = signRequest({
type: "sell_order",
quantity: quantity,
asset: asset,
min_price: min_price,
timestamp: request.timestamp
}, proxySecret);
console.debug(request);
exchangeAPI('/sell', {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
}).then(result => responseParse(result, false)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error))
})
}
function cancelOrder(type, id, floID, proxySecret) {
return new Promise((resolve, reject) => {
if (type !== "buy" && type !== "sell")
return reject(`Invalid type (${type}): type should be sell (or) buy`);
let request = {
floID: floID,
orderType: type,
orderID: id,
timestamp: Date.now()
};
if (floCrypto.getFloID(proxySecret) === floID) //Direct signing (without proxy)
request.pubKey = floCrypto.getPubKeyHex(proxySecret);
request.sign = signRequest({
type: "cancel_order",
order: type,
id: id,
timestamp: request.timestamp
}, proxySecret);
console.debug(request);
exchangeAPI('/cancel', {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
}).then(result => responseParse(result, false)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error))
})
}
//receiver should be object eg {floID1: amount1, floID2: amount2 ...}
function transferToken(receiver, token, floID, proxySecret) {
return new Promise((resolve, reject) => {
if (typeof receiver !== 'object' || receiver === null)
return reject("Invalid receiver: parameter is not an object");
let invalidIDs = [],
invalidAmt = [];
for (let f in receiver) {
if (!floCrypto.validateAddr(f))
invalidIDs.push(f);
else if (typeof receiver[f] !== "number" || receiver[f] <= 0)
invalidAmt.push(receiver[f])
}
if (invalidIDs.length)
return reject(INVALID(`Invalid receiver (${invalidIDs})`));
else if (invalidAmt.length)
return reject(`Invalid amount (${invalidAmt})`);
let request = {
floID: floID,
token: token,
receiver: receiver,
timestamp: Date.now()
};
if (floCrypto.getFloID(proxySecret) === floID) //Direct signing (without proxy)
request.pubKey = floCrypto.getPubKeyHex(proxySecret);
request.sign = signRequest({
type: "transfer_token",
receiver: JSON.stringify(receiver),
token: token,
timestamp: request.timestamp
}, proxySecret);
console.debug(request);
exchangeAPI('/transfer-token', {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
}).then(result => responseParse(result, false)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error))
})
}
function depositFLO(quantity, floID, sinkID, privKey, proxySecret = null) {
return new Promise((resolve, reject) => {
if (typeof quantity !== "number" || quantity <= floGlobals.fee)
return reject(`Invalid quantity (${quantity})`);
floBlockchainAPI.sendTx(floID, sinkID, quantity, privKey, 'Deposit FLO in market').then(txid => {
let request = {
floID: floID,
txid: txid,
timestamp: Date.now()
};
if (!proxySecret) //Direct signing (without proxy)
request.pubKey = floCrypto.getPubKeyHex(privKey);
request.sign = signRequest({
type: "deposit_flo",
txid: txid,
timestamp: request.timestamp
}, proxySecret || privKey);
console.debug(request);
exchangeAPI('/deposit-flo', {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
}).then(result => responseParse(result, false)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error))
}).catch(error => reject(error))
})
}
function withdrawFLO(quantity, floID, proxySecret) {
return new Promise((resolve, reject) => {
let request = {
floID: floID,
amount: quantity,
timestamp: Date.now()
};
if (floCrypto.getFloID(proxySecret) === floID) //Direct signing (without proxy)
request.pubKey = floCrypto.getPubKeyHex(proxySecret);
request.sign = signRequest({
type: "withdraw_flo",
amount: quantity,
timestamp: request.timestamp
}, proxySecret);
console.debug(request);
exchangeAPI('/withdraw-flo', {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
}).then(result => responseParse(result, false)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error))
})
}
function depositToken(token, quantity, floID, sinkID, privKey, proxySecret = null) {
return new Promise((resolve, reject) => {
if (!floCrypto.verifyPrivKey(privKey, floID))
return reject("Invalid Private Key");
tokenAPI.sendToken(privKey, quantity, sinkID, 'Deposit Rupee in market', token).then(txid => {
let request = {
floID: floID,
txid: txid,
timestamp: Date.now()
};
if (!proxySecret) //Direct signing (without proxy)
request.pubKey = floCrypto.getPubKeyHex(privKey);
request.sign = signRequest({
type: "deposit_token",
txid: txid,
timestamp: request.timestamp
}, proxySecret || privKey);
console.debug(request);
exchangeAPI('/deposit-token', {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
}).then(result => responseParse(result, false)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error))
}).catch(error => reject(error))
})
}
function withdrawToken(token, quantity, floID, proxySecret) {
return new Promise((resolve, reject) => {
let request = {
floID: floID,
token: token,
amount: quantity,
timestamp: Date.now()
};
if (floCrypto.getFloID(proxySecret) === floID) //Direct signing (without proxy)
request.pubKey = floCrypto.getPubKeyHex(proxySecret);
request.sign = signRequest({
type: "withdraw_token",
token: token,
amount: quantity,
timestamp: request.timestamp
}, proxySecret);
console.debug(request);
exchangeAPI('/withdraw-token', {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
}).then(result => responseParse(result, false)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error))
})
}
function addUserTag(tag_user, tag, floID, proxySecret) {
return new Promise((resolve, reject) => {
let request = {
floID: floID,
user: tag_user,
tag: tag,
timestamp: Date.now()
};
if (floCrypto.getFloID(proxySecret) === floID) //Direct signing (without proxy)
request.pubKey = floCrypto.getPubKeyHex(proxySecret);
request.sign = signRequest({
type: "add_tag",
user: tag_user,
tag: tag,
timestamp: request.timestamp
}, proxySecret);
console.debug(request);
exchangeAPI('/add-tag', {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
}).then(result => responseParse(result, false)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error))
})
}
function removeUserTag(tag_user, tag, floID, proxySecret) {
return new Promise((resolve, reject) => {
let request = {
floID: floID,
user: tag_user,
tag: tag,
timestamp: Date.now()
};
if (floCrypto.getFloID(proxySecret) === floID) //Direct signing (without proxy)
request.pubKey = floCrypto.getPubKeyHex(proxySecret);
request.sign = signRequest({
type: "remove_tag",
user: tag_user,
tag: tag,
timestamp: request.timestamp
}, proxySecret);
console.debug(request);
exchangeAPI('/remove-tag', {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
}).then(result => responseParse(result, false)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error))
})
}
function refreshDataFromBlockchain() {
return new Promise((resolve, reject) => {
let nodes, lastTx;
try {
nodes = JSON.parse(localStorage.getItem('exchange-nodes'));
if (typeof nodes !== 'object' || nodes === null)
throw Error('nodes must be an object')
else
lastTx = parseInt(localStorage.getItem('exchange-lastTx')) || 0;
} catch (error) {
nodes = {};
lastTx = 0;
}
floBlockchainAPI.readData(floGlobals.adminID, {
ignoreOld: lastTx,
sentOnly: true,
pattern: floGlobals.application
}).then(result => {
result.data.reverse().forEach(data => {
var content = JSON.parse(data)[floGlobals.application];
//Node List
if (content.Nodes) {
if (content.Nodes.remove)
for (let n of content.Nodes.remove)
delete nodes[n];
if (content.Nodes.add)
for (let n in content.Nodes.add)
nodes[n] = content.Nodes.add[n];
}
});
localStorage.setItem('exchange-lastTx', result.totalTxs);
localStorage.setItem('exchange-nodes', JSON.stringify(nodes));
nodeURL = nodes;
nodeKBucket = new K_Bucket(floGlobals.adminID, Object.keys(nodeURL));
nodeList = nodeKBucket.order;
resolve(nodes);
}).catch(error => reject(error));
})
}
function clearAllLocalData() {
localStorage.removeItem('exchange-nodes');
localStorage.removeItem('exchange-lastTx');
localStorage.removeItem('exchange-proxy_secret');
localStorage.removeItem('exchange-user_ID');
location.reload();
}

View File

@ -1,5 +1,5 @@
// Global variables
const appPages = ['dashboard', 'settings'];
const appPages = ['dashboard', 'userinfo', 'subadmin', 'settings'];
const domRefs = {};
let timerId;
const currentYear = new Date().getFullYear();
@ -11,6 +11,10 @@ if (!navigator.onLine)
"error",
{ sound: true }
);
window.addEventListener("online", () => {
getRef("notification_drawer").clearAll();
notify("We are back online.", "success");
});
window.addEventListener("offline", () => {
notify(
"There seems to be a problem connecting to the internet, Please check you internet connection.",
@ -18,10 +22,6 @@ window.addEventListener("offline", () => {
{ pinned: true, sound: true }
);
});
window.addEventListener("online", () => {
getRef("notification_drawer").clearAll();
notify("We are back online.", "success");
});
// Use instead of document.getElementById
function getRef(elementId) {
@ -96,7 +96,7 @@ class Stack {
}
pop() {
if (this.items.length == 0)
return "Underflow";
return "Underflow";
return this.items.pop();
}
peek() {
@ -104,15 +104,16 @@ class Stack {
}
}
let zIndex = 10
// function required for popups or modals to appear
function showPopup(popupId, pinned) {
zIndex++
getRef(popupId).setAttribute('style', `z-index: ${zIndex}`)
popupStack = getRef(popupId).show({ pinned, popupStack })
getRef(popupId).show({ pinned })
return getRef(popupId);
}
// hides the popup or modal
// hides the popup or modal
function hidePopup() {
if (popupStack.peek() === undefined)
return;
@ -168,10 +169,10 @@ async function getPromptInput(title, message = '', isPassword = true, cancelText
}
//Function for displaying toast notifications. pass in error for mode param if you want to show an error.
function notify(message, mode, options = {}) {
function notify(message, type, options = {}) {
const { pinned = false, sound = false } = options
let icon
switch (mode) {
switch (type) {
case 'success':
icon = `<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 15.172l9.192-9.193 1.415 1.414L10 18l-6.364-6.364 1.414-1.414z"/></svg>`
break;
@ -273,7 +274,7 @@ function showPage(targetPage, options = {}) {
else {
pageId = targetPage.includes('#') ? targetPage.split('#')[1] : targetPage
}
if(!appPages.includes(pageId)) return
if (!appPages.includes(pageId)) return
document.querySelector('.page:not(.hide-completely)').classList.add('hide-completely')
document.querySelector('.nav-list__item--active').classList.remove('nav-list__item--active')
getRef(pageId).classList.remove('hide-completely')