major UI changes

This commit is contained in:
sairaj mote 2022-03-29 18:37:26 +05:30
parent fa46e1132f
commit 1e2971ac8e
6 changed files with 1292 additions and 1614 deletions

1
args/app-config.json Normal file
View File

@ -0,0 +1 @@
{"secret":"9qWGMLljSaHWGfm4tfXMxukjig43fBtafjZ","port":"8080","sql_user":"user","sql_pwd":"Qwerty@123","sql_db":"exchange","sql_host":"localhost","backup-port":"8081","backup-floIDs":[]}

File diff suppressed because it is too large Load Diff

View File

@ -16,38 +16,29 @@ body {
}
body {
color: rgba(var(--text-color), 1);
background: rgba(var(--background-color), 1);
}
body,
body * {
--accent-color: #504dff;
--accent-color--light: #eeeeff;
--text-color: 36, 36, 36;
--background-color: 255, 255, 255;
--foreground-color: rgb(250, 252, 255);
--text-color: 20, 20, 20;
--background-color: 240, 240, 240;
--foreground-color: 250, 250, 250;
--danger-color: rgb(255, 75, 75);
--green: #1cad59;
--yellow: #f3a600;
--loan-color: rgb(255, 171, 93);
scrollbar-width: thin;
scrollbar-gutter: stable;
color: rgba(var(--text-color), 1);
background-color: rgba(var(--background-color), 1);
transition: background-color 0.3s;
}
body[data-theme=dark],
body[data-theme=dark] * {
body[data-theme=dark] {
--accent-color: #a3a1ff;
--accent-color--light: rgba(142, 140, 255, 0.06);
--text-color: 230, 230, 230;
--text-color-light: 170, 170, 170;
--text-color: 220, 220, 220;
--background-color: 10, 10, 10;
--foreground-color: rgb(24, 24, 24);
--foreground-color: 24, 24, 24;
--danger-color: rgb(255, 106, 106);
--green: #00e676;
--yellow: #ffd13a;
--loan-color: rgb(255, 232, 170);
}
body[data-theme=dark] sm-popup::part(popup) {
background-color: var(--foreground-color);
background-color: rgba(var(--foreground-color), 1);
}
p,
@ -128,7 +119,6 @@ a:any-link:focus-visible {
sm-input {
font-size: 0.9rem;
--border-radius: 0.3rem;
--background: var(--accent-color--light);
}
sm-button {
@ -149,6 +139,10 @@ sm-button.danger {
color: rgba(var(--background-color), 1);
}
sm-form {
--gap: 1rem;
}
ul {
list-style: none;
}
@ -166,7 +160,7 @@ ul {
pointer-events: none;
}
.hide-completely {
.hide {
display: none !important;
}
@ -313,11 +307,21 @@ ul {
.interact {
position: relative;
overflow: hidden;
cursor: pointer;
transition: transform 0.3s;
-webkit-tap-highlight-color: transparent;
}
.ripple {
height: 8rem;
width: 8rem;
position: absolute;
border-radius: 50%;
transform: scale(0);
background: radial-gradient(circle, rgba(var(--text-color), 0.3) 0%, rgba(0, 0, 0, 0) 50%);
pointer-events: none;
}
.empty-state {
display: grid;
justify-content: center;
@ -336,15 +340,11 @@ ul {
}
.icon {
width: 1.5rem;
height: 1.5rem;
width: 1.2rem;
height: 1.2rem;
fill: rgba(var(--text-color), 0.8);
}
.button__icon {
height: 1.2rem;
width: 1.2rem;
}
.button__icon--left {
margin-right: 0.5rem;
}
@ -392,12 +392,6 @@ ul {
margin-bottom: 1.5rem;
}
button:active,
.button:active,
.interact:active {
transform: scale(0.96);
}
.popup__header {
display: grid;
gap: 0.5rem;
@ -506,6 +500,10 @@ sm-checkbox {
height: 100%;
}
.mobile-page {
align-items: flex-start;
}
#landing {
grid-template-rows: auto 1fr;
}
@ -547,10 +545,10 @@ sm-checkbox {
#home {
height: 100%;
display: grid;
display: flex;
flex-direction: column;
align-items: flex-start;
align-content: flex-start;
grid-template-columns: minmax(0, 1fr);
}
#login_form__priv_key {
@ -558,34 +556,90 @@ sm-checkbox {
}
#main_header {
margin-top: 1.5rem;
margin-bottom: 1rem;
display: grid;
gap: 1rem;
padding: 1.5rem;
width: 100%;
align-items: center;
grid-template-columns: 1fr auto auto;
grid-column: 1/-1;
}
#flo_exchange_rate {
#main_navbar {
width: 100%;
}
.main_navbar__item {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
padding: 0.5rem 0;
}
.main_navbar__item .item__title,
.main_navbar__item .icon {
transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275), opacity 0.3s;
}
.main_navbar__item .item__title {
color: rgba(var(--text-color), 0.8);
font-size: 0.8rem;
font-weight: 500;
}
.main_navbar__item .icon {
height: 1.2rem;
margin-bottom: 0.3rem;
}
.main_navbar__item--active .item__title {
color: var(--accent-color);
}
.main_navbar__item--active .icon {
fill: var(--accent-color);
}
#pages_container {
display: flex;
flex: 1;
width: 100%;
justify-content: center;
overflow-y: auto;
padding: 0 1.5rem;
}
#pages_container > * {
width: min(42rem, 100%);
}
#exchange {
display: grid;
gap: 1.5rem;
}
.listed-asset {
position: relative;
grid-template-columns: auto 1fr auto;
gap: 0.5rem;
padding: 1rem;
border-radius: 0.5rem;
border: solid rgba(var(--text-color), 0.2) thin;
background-color: rgba(var(--background-color), 1);
opacity: 0.8;
font-weight: 400;
transition: background-color 0.3s;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
color: inherit;
}
.listed-asset__icon {
display: flex;
}
.listed-asset__icon .icon {
height: 1.5rem;
width: 1.5rem;
}
#flo_rate {
font-weight: 700;
}
#trade_form,
#login_form {
align-self: flex-start;
padding: 1rem 1.5rem 1.5rem 1.5rem;
}
.quantity-selector .button {
flex: 1;
padding: 0.5rem 0.6rem;
@ -604,24 +658,17 @@ sm-checkbox {
min-width: 8ch;
}
#my_orders_section,
#market_orders_section {
padding-top: 1rem;
#my_orders,
#market {
width: min(42rem, 100%);
grid-template-rows: auto 1fr;
}
#my_orders_section .icon,
#market_orders_section .icon {
#my_orders .icon,
#market .icon {
height: 1.2rem;
width: 1.2rem;
}
.orders_section__header {
padding: 0 1.5rem;
}
#my_orders_section__header {
height: 2.4rem;
}
#orders_section__header--primary sm-tab-header {
--gap: 1.5rem;
}
@ -631,7 +678,7 @@ sm-checkbox {
}
.list__item {
padding: 0.5rem 1.5rem;
padding: 0.5rem 0;
display: grid;
}
@ -720,13 +767,11 @@ sm-checkbox {
}
#market_orders_list .list__header {
margin-bottom: 0.5rem;
padding: 0 1.5rem;
grid-template-columns: repeat(3, 1fr) 2rem;
}
#user_section {
#wallet {
gap: 1.5rem;
padding: 1.5rem;
align-content: flex-start;
}
@ -943,53 +988,16 @@ sm-checkbox {
}
}
@media screen and (max-width: 40rem) {
#main_header {
padding: 0 1.5rem;
}
sm-button {
--padding: 0.9rem 1.6rem;
}
#home > :last-child {
padding-bottom: 5rem;
}
#bottom_nav {
position: fixed;
bottom: 0;
background-color: var(--foreground-color);
width: 100%;
}
.bottom_nav__item {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
padding: 0.5rem 0;
}
.bottom_nav__item .item__title,
.bottom_nav__item .icon {
transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.bottom_nav__item .item__title {
color: rgba(var(--text-color), 0.8);
font-size: 0.8rem;
font-weight: 500;
}
.bottom_nav__item .icon {
height: 1.2rem;
margin-bottom: 0.3rem;
}
.bottom_nav__item--active .item__title {
color: var(--accent-color);
.main_navbar__item--active .item__title {
transform: translateY(100%);
opacity: 0;
}
.bottom_nav__item--active .icon {
.main_navbar__item--active .icon {
transform: translateY(50%) scale(1.2);
fill: var(--accent-color);
}
.hide-on-mobile {
@ -1029,45 +1037,69 @@ sm-checkbox {
grid-template-columns: 1fr 90vw 1fr;
}
#home {
padding: 0 4vmax;
gap: 1rem;
}
.hide-on-desktop {
display: none;
}
.card {
border-radius: 0.5rem;
background-color: var(--foreground-color);
border: solid thin rgba(var(--text-color), 0.1);
}
}
@media screen and (min-width: 48rem) {
#home {
grid-template-rows: -webkit-min-content 1fr;
grid-template-rows: min-content 1fr;
grid-template-columns: 24rem minmax(0, 1fr);
}
#home.signed-in #orders_list,
#home.signed-in #market_orders_list {
height: 32vmin;
overflow-y: auto;
display: grid;
grid-template-columns: 12rem 1fr;
grid-template-rows: auto 1fr;
grid-template-areas: "header header" "nav .";
}
#orders_section {
grid-row: span 2;
#main_header {
grid-area: header;
}
#main_navbar {
grid-area: nav;
flex-direction: column;
height: 100%;
padding: 0 0.5rem;
}
.main_navbar__item {
padding: 1.5rem 1rem;
width: 100%;
flex: 0;
flex-direction: row;
border-radius: 0.5rem;
transition: background-color 0.3s;
}
.main_navbar__item .icon {
margin-bottom: 0;
margin-right: 0.5rem;
}
.main_navbar__item .item__title {
font-size: 0.9rem;
}
.main_navbar__item--active {
background-color: rgba(var(--text-color), 0.06);
}
#exchange {
display: grid;
grid-template-columns: 16rem 1fr;
}
.listed-asset--active {
opacity: 1;
background-color: rgba(var(--text-color), 0.06);
}
.listed-asset--active::before {
content: "";
position: absolute;
width: 0.25rem;
border-radius: 0 0.2rem 0.2rem 0;
height: 50%;
background-color: var(--accent-color);
}
}
@media screen and (min-width: 72rem) {
.page-layout {
grid-template-columns: 1fr 80vw 1fr;
}
#home.signed-in {
grid-template-columns: 24rem minmax(0, 1fr) 20rem;
}
}
@media screen and (min-width: 120rem) {
.page-layout {
@ -1088,15 +1120,6 @@ sm-checkbox {
background: rgba(var(--text-color), 0.5);
}
.interact,
button {
transition: background-color 0.3s, transform 0.3s;
}
.interact:hover,
button:hover {
background-color: var(--accent-color--light);
}
.order-card .cancel-order {
justify-self: flex-end;
overflow: hidden;

File diff suppressed because one or more lines are too long

View File

@ -16,40 +16,28 @@ body {
}
body {
&,
* {
--accent-color: #504dff;
--accent-color--light: #eeeeff;
--text-color: 36, 36, 36;
--background-color: 255, 255, 255;
--foreground-color: rgb(250, 252, 255);
--text-color: 20, 20, 20;
--background-color: 240, 240, 240;
--foreground-color: 250, 250, 250;
--danger-color: rgb(255, 75, 75);
--green: #1cad59;
--yellow: #f3a600;
--loan-color: rgb(255, 171, 93);
scrollbar-width: thin;
}
scrollbar-gutter: stable;
color: rgba(var(--text-color), 1);
background: rgba(var(--background-color), 1);
background-color: rgba(var(--background-color), 1);
transition: background-color 0.3s;
}
body[data-theme="dark"] {
&,
* {
--accent-color: #a3a1ff;
--accent-color--light: rgba(142, 140, 255, 0.06);
--text-color: 230, 230, 230;
--text-color-light: 170, 170, 170;
--text-color: 220, 220, 220;
--background-color: 10, 10, 10;
--foreground-color: rgb(24, 24, 24);
--foreground-color: 24, 24, 24;
--danger-color: rgb(255, 106, 106);
--green: #00e676;
--yellow: #ffd13a;
--loan-color: rgb(255, 232, 170);
}
sm-popup::part(popup) {
background-color: var(--foreground-color);
background-color: rgba(var(--foreground-color), 1);
}
}
@ -119,7 +107,6 @@ a:any-link:focus-visible {
sm-input {
font-size: 0.9rem;
--border-radius: 0.3rem;
--background: var(--accent-color--light);
}
sm-button {
text-transform: uppercase;
@ -143,6 +130,9 @@ sm-button {
color: rgba(var(--background-color), 1);
}
}
sm-form {
--gap: 1rem;
}
ul {
list-style: none;
}
@ -160,7 +150,7 @@ ul {
pointer-events: none;
}
.hide-completely {
.hide {
display: none !important;
}
@ -308,10 +298,23 @@ ul {
.interact {
position: relative;
overflow: hidden;
cursor: pointer;
transition: transform 0.3s;
-webkit-tap-highlight-color: transparent;
}
.ripple {
height: 8rem;
width: 8rem;
position: absolute;
border-radius: 50%;
transform: scale(0);
background: radial-gradient(
circle,
rgba(var(--text-color), 0.3) 0%,
rgba(0, 0, 0, 0) 50%
);
pointer-events: none;
}
.empty-state {
display: grid;
justify-content: center;
@ -330,15 +333,12 @@ ul {
}
.icon {
width: 1.5rem;
height: 1.5rem;
width: 1.2rem;
height: 1.2rem;
fill: rgba(var(--text-color), 0.8);
}
.button__icon {
height: 1.2rem;
width: 1.2rem;
&--left {
margin-right: 0.5rem;
}
@ -379,13 +379,6 @@ ul {
#prompt_message {
margin-bottom: 1.5rem;
}
button:active,
.button:active,
.interact:active {
transform: scale(0.96);
}
.popup__header {
display: grid;
gap: 0.5rem;
@ -487,6 +480,9 @@ sm-checkbox {
.page {
height: 100%;
}
.mobile-page {
align-items: flex-start;
}
#landing {
grid-template-rows: auto 1fr;
header {
@ -527,42 +523,94 @@ sm-checkbox {
}
#home {
height: 100%;
display: grid;
display: flex;
flex-direction: column;
align-items: flex-start;
align-content: flex-start;
grid-template-columns: minmax(0, 1fr);
}
#login_form__priv_key {
margin-top: 1rem;
}
#main_header {
margin-top: 1.5rem;
margin-bottom: 1rem;
display: grid;
gap: 1rem;
padding: 1.5rem;
width: 100%;
align-items: center;
grid-template-columns: 1fr auto auto;
grid-column: 1/-1;
}
#main_navbar {
width: 100%;
}
.main_navbar__item {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
padding: 0.5rem 0;
.item__title,
.icon {
transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275),
opacity 0.3s;
}
.item__title {
color: rgba(var(--text-color), 0.8);
font-size: 0.8rem;
font-weight: 500;
}
.icon {
height: 1.2rem;
margin-bottom: 0.3rem;
}
&--active {
.item__title {
color: var(--accent-color);
}
.icon {
fill: var(--accent-color);
}
}
}
#pages_container {
display: flex;
flex: 1;
width: 100%;
justify-content: center;
overflow-y: auto;
padding: 0 1.5rem;
& > * {
width: min(42rem, 100%);
}
}
#flo_exchange_rate {
#exchange {
display: grid;
gap: 1.5rem;
}
.listed-asset {
position: relative;
grid-template-columns: auto 1fr auto;
gap: 0.5rem;
padding: 1rem;
border-radius: 0.5rem;
border: solid rgba(var(--text-color), 0.2) thin;
background-color: rgba(var(--background-color), 1);
opacity: 0.8;
font-weight: 400;
transition: background-color 0.3s;
user-select: none;
color: inherit;
&__icon {
display: flex;
.icon {
height: 1.5rem;
width: 1.5rem;
}
}
}
#flo_rate {
font-weight: 700;
}
#trade_form,
#login_form {
align-self: flex-start;
padding: 1rem 1.5rem 1.5rem 1.5rem;
}
.quantity-selector {
.button {
flex: 1;
@ -581,20 +629,15 @@ sm-checkbox {
font-weight: 500;
min-width: 8ch;
}
#my_orders_section,
#market_orders_section {
padding-top: 1rem;
#my_orders,
#market {
width: min(42rem, 100%);
grid-template-rows: auto 1fr;
.icon {
height: 1.2rem;
width: 1.2rem;
}
}
.orders_section__header {
padding: 0 1.5rem;
}
#my_orders_section__header {
height: 2.4rem;
}
#orders_section__header--primary {
sm-tab-header {
--gap: 1.5rem;
@ -606,7 +649,7 @@ sm-checkbox {
}
.list__item {
padding: 0.5rem 1.5rem;
padding: 0.5rem 0;
display: grid;
}
.order-card {
@ -697,13 +740,11 @@ sm-checkbox {
}
.list__header {
margin-bottom: 0.5rem;
padding: 0 1.5rem;
grid-template-columns: repeat(3, 1fr) 2rem;
}
}
#user_section {
#wallet {
gap: 1.5rem;
padding: 1.5rem;
align-content: flex-start;
}
.wallet_actions__wrapper {
@ -879,52 +920,16 @@ sm-checkbox {
}
}
@media screen and (max-width: 40rem) {
#main_header {
padding: 0 1.5rem;
}
sm-button {
--padding: 0.9rem 1.6rem;
}
#home {
& > :last-child {
padding-bottom: 5rem;
}
}
#bottom_nav {
position: fixed;
bottom: 0;
background-color: var(--foreground-color);
width: 100%;
}
.bottom_nav__item {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
padding: 0.5rem 0;
.item__title,
.icon {
transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.main_navbar__item--active {
.item__title {
color: rgba(var(--text-color), 0.8);
font-size: 0.8rem;
font-weight: 500;
}
.icon {
height: 1.2rem;
margin-bottom: 0.3rem;
}
&--active {
.item__title {
color: var(--accent-color);
transform: translateY(100%);
opacity: 0;
}
.icon {
transform: translateY(50%) scale(1.2);
fill: var(--accent-color);
}
}
}
.hide-on-mobile {
@ -959,33 +964,59 @@ sm-checkbox {
.page-layout {
grid-template-columns: 1fr 90vw 1fr;
}
#home {
padding: 0 4vmax;
gap: 1rem;
}
.hide-on-desktop {
display: none;
}
.card {
border-radius: 0.5rem;
background-color: var(--foreground-color);
border: solid thin rgba(var(--text-color), 0.1);
}
}
@media screen and (min-width: 48rem) {
#home {
grid-template-rows: min-content 1fr;
grid-template-columns: 24rem minmax(0, 1fr);
&.signed-in {
#orders_list,
#market_orders_list {
height: 32vmin;
overflow-y: auto;
display: grid;
grid-template-columns: 12rem 1fr;
grid-template-rows: auto 1fr;
grid-template-areas: "header header" "nav .";
}
#main_header {
grid-area: header;
}
#main_navbar {
grid-area: nav;
flex-direction: column;
height: 100%;
padding: 0 0.5rem;
}
.main_navbar__item {
padding: 1.5rem 1rem;
width: 100%;
flex: 0;
flex-direction: row;
border-radius: 0.5rem;
transition: background-color 0.3s;
.icon {
margin-bottom: 0;
margin-right: 0.5rem;
}
.item__title {
font-size: 0.9rem;
}
&--active {
background-color: rgba(var(--text-color), 0.06);
}
}
#exchange {
display: grid;
grid-template-columns: 16rem 1fr;
}
.listed-asset {
&--active {
opacity: 1;
background-color: rgba(var(--text-color), 0.06);
&::before {
content: "";
position: absolute;
width: 0.25rem;
border-radius: 0 0.2rem 0.2rem 0;
height: 50%;
background-color: var(--accent-color);
}
}
#orders_section {
grid-row: span 2;
}
}
@media screen and (max-width: 64rem) {
@ -994,9 +1025,6 @@ sm-checkbox {
.page-layout {
grid-template-columns: 1fr 80vw 1fr;
}
#home.signed-in {
grid-template-columns: 24rem minmax(0, 1fr) 20rem;
}
}
@media screen and (min-width: 120rem) {
.page-layout {
@ -1017,13 +1045,6 @@ sm-checkbox {
background: rgba(var(--text-color), 0.5);
}
}
.interact,
button {
transition: background-color 0.3s, transform 0.3s;
&:hover {
background-color: var(--accent-color--light);
}
}
.order-card {
.cancel-order {
justify-self: flex-end;

View File

@ -21,12 +21,8 @@
<script>console.debug(floExchangeAPI);</script>
</head>
<body class="hide-completely">
<body class="hide">
<sm-notifications id="notification_drawer"></sm-notifications>
<audio id="notification_sound">
<source src="https://rmservices.duckdns.org/files/notification-sound.mp3" type="audio/mpeg">
<source src="https://rmservices.duckdns.org/files/notification-sound.ogg" type="audio/ogg">
</audio>
<sm-popup id="confirmation_popup">
<h4 id="confirm_title"></h4>
<p id="confirm_message"></p>
@ -59,7 +55,7 @@
</div>
</div>
<theme-toggle></theme-toggle>
<button id="user_popup_button" class="hide-completely" onclick="showPopup('user_popup')">
<button id="user_popup_button" class="hide" onclick="showPopup('user_popup')">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" height="24px" viewBox="0 0 24 24" width="24px"
fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" />
@ -68,14 +64,16 @@
</svg>
</button>
</header>
<section id="dashboard" class="card mobile-page">
<sm-form id="login_form" class="hide-">
<section id="pages_container">
<section id="exchange" class="mobile-page">
<sm-form id="login_form">
<div class="grid gap-0-5">
<h4>Login</h4>
<p>Please login for trading and accessing your account.</p>
<p>Please login for exchange.</p>
</div>
<sm-input type="password" id="login_form__priv_key" placeholder="Private key" variant="outlined" animate
required hiderequired></sm-input>
<sm-input type="password" id="login_form__priv_key" placeholder="Private key" animate required>
</sm-input>
</sm-input>
<sm-checkbox id="remember_me" checked>
<span class="button__icon--right">
Remember me
@ -86,53 +84,50 @@
<div id="login_button_wrapper" class="stateful-button-wrapper">
<sm-button variant="primary" onclick="UI_evt.login();">Log in</sm-button>
</div>
<sm-button onclick="showPopup('registration_popup')" style="display: none;" disabled>Not registered? click here!</sm-button>
<sm-button onclick="showPopup('registration_popup')" style="display: none;" disabled>Not registered?
click here!</sm-button>
<div class="grid gap-0-5">
<p>Don't have FLO credentials?</p>
<sm-button onclick="showPopup('sign_up_popup')">Generate FLO credentials</sm-button>
</div>
<sm-button onclick="floExchangeAPI.clearAllLocalData()">clear local data</sm-button>
</sm-form>
<sm-form id="trade_form" class="user-content hide-completely">
<div id="flo_exchange_rate" class="grid align-center">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
d="M16.36,15.39c1.83,0,4.26-2.49,4.36-4.74-5.65-.19-4.91.47-7.28,2.39,2.19-2.4,1.42-7.79-1.43-10V6.17c2.33,1.49,2.21,5.14,0,7.15-2.23-2-2.27-5.69,0-7.15V3c-2.83,2.26-3.62,7.66-1.44,10-2.36-1.93-1.63-2.58-7.28-2.39.1,2.26,2.55,4.73,4.36,4.74,0,0-1.93.22-2.74-2.62,2.38-.37,4.29-.14,6.28,2-.79-.11-4.89,1.13-4.38,3.26.53.06,3,.3,3.58-.83-.17.18-1.25.5-1.53.05.38-1.39,2.32-2,2.32-2-1,1.82-.48,4.63.82,5.72,1.31-1.08,1.8-3.95.82-5.72,0,0,1.95.6,2.32,2-.29.46-1.36.12-1.53-.05.58,1.14,3.06.88,3.58.83.49-2.17-3.58-3.36-4.38-3.26,2-2.17,3.92-2.39,6.28-2C18.3,15.62,16.36,15.39,16.36,15.39ZM12,19.46c-.91-.79-.5-3,0-3.59C12.5,16.45,12.91,18.66,12,19.46Z" />
</svg>
<p><b>FLO</b>/INR</p>
<span id="flo_rate"></span>
<div class="grid gap-1 align-start hide user-content">
<h4>Assets</h4>
<ul id="listed_assets" class="user-content hide"></ul>
</div>
<sm-form id="trade_form" class="user-content hide hide-on-mobile">
<div class="flex space-between align-center">
<h4>Trade FLO</h4>
<h4 id="traded_asset">Trade FLO</h4>
<strip-select id="trade_type_selector" class="tab">
<strip-option value="buy" selected>Buy</strip-option>
<strip-option value="sell">Sell</strip-option>
</strip-select>
</div>
<sm-select id="get_asset"></sm-select>
<sm-input id="get_price" variant="outlined" placeholder="Max price (₹)" type="number" step="0.01"
required hiderequired animate>
<sm-input id="get_price" placeholder="Max price (₹)" type="number" step="0.01" required animate>
</sm-input>
<sm-input id="get_quantity" variant="outlined" placeholder="Quantity (FLO)" type="number" step="0.0001"
required hiderequired animate></sm-input>
<sm-input id="get_total" variant="outlined" placeholder="Total (₹)" type="number" min="0.01" step="0.01"
required hiderequired animate>
<sm-input id="get_quantity" placeholder="Quantity" type="number" step="0.0001" required animate>
</sm-input>
</sm-input>
<sm-input id="get_total" placeholder="Total (₹)" type="number" min="0.01" step="0.01" required
animate>
</sm-input>
<div id="quantity_selector" class="flex align-center quantity-selector">
<span id="quantity_type">Rupee</span>
<button class="button" value="0.25">25%</button>
<button class="button" value="0.5">50%</button>
<button class="button" value="0.75">75%</button>
<button class="button" value="1">100%</button>
<button class="button" value="0.25" title="Buy FLO worth 25% of total rupee">25%</button>
<button class="button" value="0.5" title="Buy FLO worth 50% of total rupee">50%</button>
<button class="button" value="0.75" title="Buy FLO worth 75% of total rupee">75%</button>
<button class="button" value="1" title="Buy FLO worth 100% of total rupee">100%</button>
</div>
<div id="trade_button_wrapper" class="stateful-button-wrapper flex align-center justify-center">
<sm-button id="trade_button" class="uppercase w-100" variant="primary" onclick="tradeFlo()">BUY FLO
<sm-button id="trade_button" class="uppercase w-100" variant="primary" onclick="tradeFlo()">
BUY
FLO
</sm-button>
</div>
</sm-form>
</section>
<section id="orders_section" class="grid gap-1">
<section id="my_orders_section" class="grid gap-1 card user-content mobile-page hide-on-mobile">
<section id="my_orders" class="grid gap-1 hide mobile-page">
<div id="my_orders_section__header" class="orders_section__header flex">
<div id="orders_section__header--primary" class="flex w-100 align-center space-between">
<h4>
@ -143,8 +138,7 @@
<strip-option value="completed">History</strip-option>
</strip-select>
</div>
<div id="orders_section__header--secondary"
class="flex w-100 align-center space-between hide-completely">
<div id="orders_section__header--secondary" class="flex w-100 align-center space-between hide">
<button class="" onclick="clearSelection()" title="Clear all selection">
<svg xmlns="http://www.w3.org/2000/svg" class="icon button__icon--left" height="24px"
viewBox="0 0 24 24" width="24px">
@ -166,7 +160,7 @@
No orders placed
</p>
</section>
<section id="market_orders_section" class="grid gap-1 card mobile-page hide-on-mobile">
<section id="market" class="grid gap-1 hide mobile-page">
<div class="orders_section__header flex align-center space-between">
<h4 class="flex align-center">
Market orders
@ -189,8 +183,7 @@
No orders placed
</p>
</section>
</section>
<section id="user_section" class="grid card user-content mobile-page hide-completely hide-on-mobile">
<section id="wallet" class="grid mobile-page hide">
<h4 class="flex align-center user_section__header">
<svg xmlns="http://www.w3.org/2000/svg" class="icon button__icon--left" height="24px"
viewBox="0 0 24 24" width="24px">
@ -203,8 +196,7 @@
</h4>
<div id="wallet_actions">
<p class="label">Select asset</p>
<sm-select id="wallet_asset_selector">
</sm-select>
<sm-select id="wallet_asset_selector"></sm-select>
<div class="flex wallet_actions__wrapper">
<button class="button" value="deposit">
Deposit
@ -240,18 +232,18 @@
</div>
</div>
</section>
</article>
<footer id="bottom_nav" class="flex align-center hide-on-desktop">
<a href="#/dashboard" class="bottom_nav__item bottom_nav__item--active">
</section>
<nav id="main_navbar" class="flex align-center">
<a href="#/exchange" class="main_navbar__item main_navbar__item--active interact">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px"
viewBox="0 0 24 24" width="24px" fill="#000000">
<rect fill="none" height="24" width="24" />
<path
d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M5,19V5h6v14H5z M19,19h-6v-7h6V19z M19,10h-6V5h6V10z" />
</svg>
<div class="item__title">Dashboard</div>
<div class="item__title">Exchange</div>
</a>
<a href="#/my_orders" class="bottom_nav__item user-content hide-completely">
<a href="#/my_orders" class="main_navbar__item user-content hide interact">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px"
viewBox="0 0 24 24" width="24px" fill="#000000">
<path d="M0,0h24v24H0V0z" fill="none" />
@ -266,7 +258,7 @@
</svg>
<div class="item__title">My orders</div>
</a>
<a href="#/market" class="bottom_nav__item">
<a href="#/market" class="main_navbar__item interact">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px"
viewBox="0 0 24 24" width="24px" fill="#000000">
<g>
@ -282,7 +274,7 @@
</svg>
<div class="item__title">Market</div>
</a>
<a href="#/wallet" class="bottom_nav__item user-content hide-completely">
<a href="#/wallet" class="main_navbar__item user-content hide interact">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"
fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" />
@ -292,7 +284,8 @@
</svg>
<div class="item__title">Wallet</div>
</a>
</footer>
</nav>
</article>
<sm-popup id="user_popup">
<header slot="header" class="popup__header">
<button class="popup__header__close" onclick="hidePopup()">
@ -336,8 +329,8 @@
<div class="grid gap-1-5">
<sm-form id="register_section">
<p>Enter the private key of FLO ID you want to register.</p>
<sm-input id="get_registration_key" variant="outlined" placeholder="Private key" type="password"
required hiderequired></sm-input>
<sm-input id="get_registration_key" placeholder="Private key" type="password" required>
</sm-input>
<sm-button variant="primary" onclick="UI_evt.signup()" disabled>Register</sm-button>
</sm-form>
</div>
@ -364,7 +357,8 @@
<sm-copy id="generated_private_key"></sm-copy>
</div>
</div>
<sm-button id="sign_up_button" variant="primary" onclick="registerID()" style="display: none;" disabled>Register these credentials
<sm-button id="sign_up_button" variant="primary" onclick="registerID()" style="display: none;" disabled>
Register these credentials
</sm-button>
<strong class="warning">
Keep your private key secure and don't share with anyone.
@ -385,8 +379,8 @@
</header>
<sm-form id="wallet_form">
<input type="text" id="sink_id" style="display: none;" hidden />
<sm-input id="get_user_amount" variant="outlined" placeholder="Quantity" type="number" min="0.01"
step="0.00001" required hiderequired animate>
<sm-input id="get_user_amount" placeholder="Quantity" type="number" min="0.01" step="0.00001" required
animate>
</sm-input>
<div id="wallet_quantity_selector" class="flex align-center quantity-selector">
<span id="wallet_quantity_type">Rupee</span>
@ -395,14 +389,14 @@
<button class="button" value="0.75">75%</button>
<button class="button" value="1">100%</button>
</div>
<sm-input id="get_private_key" variant="outlined" placeholder="FLO private key" type="password" required
error-text="Invalid private key" hiderequired animate>
<sm-input id="get_private_key" placeholder="FLO private key" type="password" required
error-text="Invalid private key" animate>
</sm-input>
<div id="wallet_popup__cta_wrapper" class="stateful-button-wrapper">
<sm-button id="wallet_popup__cta" class="uppercase" variant="primary"></sm-button>
</div>
</sm-form>
<div id="wallet_result" class="grid gap-2 hide-completely">
<div id="wallet_result" class="grid gap-2 hide">
<div id="wallet_result__icon"></div>
<div class="grid gap-0-5">
<h4 id="wallet_result__title"></h4>
@ -437,6 +431,18 @@
</div>
</div>
</sm-popup>
<!-- templates -->
<template id="listed_asset_template">
<li>
<a class="listed-asset interact grid align-center">
<div class="listed-asset__icon"></div>
<h4 class="listed-asset__name"></h4>
<strong class="listed-asset__rate"></strong>
</a>
</li>
</template>
<template id="net_balance_template">
<span class="available-balance"></span>
</template>
@ -724,10 +730,6 @@
break;
}
getRef("notification_drawer").push(message, { pinned, icon });
if (navigator.onLine && sound) {
getRef("notification_sound").currentTime = 0;
getRef("notification_sound").play();
}
if (mode === 'error') {
console.error(message)
}
@ -784,8 +786,7 @@
window.addEventListener('hashchange', e => showPage(window.location.hash))
window.addEventListener("load", () => {
showPage(window.location.hash)
document.body.classList.remove('hide-completely')
document.body.classList.remove('hide')
document.querySelectorAll('sm-input[data-private-key]').forEach(input => input.customValidation = floCrypto.getPubKeyHex)
document.addEventListener('keyup', (e) => {
if (e.key === 'Escape') {
@ -795,17 +796,51 @@
document.addEventListener('copy', () => {
notify('copied', 'success')
})
document.addEventListener("pointerdown", (e) => {
if (e.target.closest("button:not([disabled]), sm-button:not([disabled]), .interact")) {
createRipple(e, e.target.closest("button, sm-button, .interact"));
}
});
});
function createRipple(event, target) {
const circle = document.createElement("span");
const diameter = Math.max(target.clientWidth, target.clientHeight);
const radius = diameter / 2;
const targetDimensions = target.getBoundingClientRect();
circle.style.width = circle.style.height = `${diameter}px`;
circle.style.left = `${event.clientX - (targetDimensions.left + radius)}px`;
circle.style.top = `${event.clientY - (targetDimensions.top + radius)}px`;
circle.classList.add("ripple");
const rippleAnimation = circle.animate(
[
{
transform: "scale(4)",
opacity: 0,
},
],
{
duration: 600,
fill: "forwards",
easing: "ease-out",
}
);
target.append(circle);
rippleAnimation.onfinish = () => {
circle.remove();
};
}
const pagesData = {
openedPages: [],
lastPage: '',
params: {}
}
async function showPage(targetPage, options = {}) {
const { firstLoad, hashChange } = options
let pageId
let params
let subPageId
let params = {}
let searchParams
if (targetPage === '') {
if (typeof proxy.userID === "undefined") {
pageId = 'landing'
@ -814,53 +849,72 @@
}
} else {
if (targetPage.includes('/')) {
if (targetPage.includes('?')) {
const splitAddress = targetPage.split('?')
searchParams = splitAddress.pop()
const pages = splitAddress.pop().split('/')
pageId = pages[1]
subPageId = pages[2]
} else {
const pages = targetPage.split('/')
pageId = pages[1]
subPageId = pages[2]
}
} else {
pageId = targetPage
}
}
if (pagesData.lastPage !== pageId) {
let target
if (searchParams) {
const urlSearchParams = new URLSearchParams('?' + searchParams);
params = Object.fromEntries(urlSearchParams.entries());
}
switch (pageId) {
case 'dashboard':
target = 'dashboard'
case 'exchange':
if (!params.hasOwnProperty('asset') || params.asset === '') {
params.asset = 'FLO'
}
if (getRef('listed_assets').querySelector('.listed-asset--active'))
getRef('listed_assets').querySelector('.listed-asset--active').classList.remove('listed-asset--active')
getRef('listed_assets').querySelector(`[href="#/exchange?asset=${params.asset}"]`).classList.add('listed-asset--active')
getRef('get_price').value = parseFloat(floGlobals.exchangeRates[params.asset].toFixed(2))
getRef('traded_asset').textContent = `Trade ${params.asset}`
getRef('trade_button').textContent = `${tradeType} ${params.asset}`
getRef('quantity_type').textContent = tradeType === 'buy' ? formatAmount(allTokens.rupee.net) : `${parseFloat(allTokens[params.asset].net.toFixed(3))} ${params.asset}`
getRef('quantity_selector').querySelectorAll('.button').forEach(button => {
if (tradeType === 'buy') {
button.title = `Buy ${params.asset} worth ${button.textContent} of total rupee`
} else {
button.title = `Sell ${button.textContent} of total ${params.asset}`
}
})
break;
case 'my_orders':
target = 'my_orders_section'
break;
case 'market':
target = 'market_orders_section'
break;
case 'wallet':
target = 'user_section'
break;
}
if (target) {
document.querySelectorAll('.mobile-page').forEach(elem => elem.classList.add('hide-on-mobile'))
getRef(target).classList.remove('hide-on-mobile')
document.querySelectorAll('.bottom_nav__item').forEach(elem => elem.classList.remove('bottom_nav__item--active'))
document.querySelector(`.bottom_nav__item[href="#/${pageId}"]`).classList.add('bottom_nav__item--active')
getRef(target)?.animate([
if (pagesData.lastPage !== pageId) {
document.querySelectorAll('.mobile-page').forEach(elem => elem.classList.add('hide'))
getRef(pageId).classList.remove('hide')
document.querySelectorAll('.main_navbar__item').forEach(elem => elem.classList.remove('main_navbar__item--active'))
document.querySelector(`.main_navbar__item[href="#/${pageId}"]`).classList.add('main_navbar__item--active')
getRef(pageId)?.animate([
{
transform: 'translateY(1rem)',
opacity: 0,
},
{
transform: 'none',
opacity: 1,
},
],
{
duration: 300,
duration: 150,
easing: 'ease'
})
pagesData.lastPage = target
if (!pagesData.openedPages.includes(target)) {
pagesData.openedPages.push(target)
}
}
pagesData.lastPage = pageId
}
pagesData.params = params
}
// class based lazy loading
class LazyLoader {
@ -939,10 +993,27 @@
}
</script>
<script>
const listedAssets = {
FLO: {
icon: `<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
d="M16.36,15.39c1.83,0,4.26-2.49,4.36-4.74-5.65-.19-4.91.47-7.28,2.39,2.19-2.4,1.42-7.79-1.43-10V6.17c2.33,1.49,2.21,5.14,0,7.15-2.23-2-2.27-5.69,0-7.15V3c-2.83,2.26-3.62,7.66-1.44,10-2.36-1.93-1.63-2.58-7.28-2.39.1,2.26,2.55,4.73,4.36,4.74,0,0-1.93.22-2.74-2.62,2.38-.37,4.29-.14,6.28,2-.79-.11-4.89,1.13-4.38,3.26.53.06,3,.3,3.58-.83-.17.18-1.25.5-1.53.05.38-1.39,2.32-2,2.32-2-1,1.82-.48,4.63.82,5.72,1.31-1.08,1.8-3.95.82-5.72,0,0,1.95.6,2.32,2-.29.46-1.36.12-1.53-.05.58,1.14,3.06.88,3.58.83.49-2.17-3.58-3.36-4.38-3.26,2-2.17,3.92-2.39,6.28-2C18.3,15.62,16.36,15.39,16.36,15.39ZM12,19.46c-.91-.79-.5-3,0-3.59C12.5,16.45,12.91,18.66,12,19.46Z" />
</svg>`
},
}
function formatAmount(amount) {
return amount.toLocaleString(`en-IN`, { style: 'currency', currency: 'INR' })
}
const render = {
listedAsset(name, rate) {
const clone = getRef('listed_asset_template').content.cloneNode(true).firstElementChild.firstElementChild
clone.href = `#/exchange?asset=${name}`
clone.querySelector('.listed-asset__icon').innerHTML = listedAssets[name] ? listedAssets[name].icon : ''
clone.querySelector('.listed-asset__rate').textContent = rate
clone.querySelector('.listed-asset__name').textContent = name
return clone
},
orderCard(orderDetails = {}) {
const { id, asset, quantity, price, time, type } = orderDetails
const card = getRef('order_template').content.cloneNode(true).firstElementChild
@ -1010,12 +1081,21 @@
let tradeType = 'buy'
getRef('trade_type_selector').addEventListener('change', e => {
tradeType = e.detail.value
const selectedAsset = pagesData.params.asset
getRef('get_price').setAttribute('placeholder', tradeType === 'buy' ? 'Max price' : 'Min price')
getRef('trade_button').textContent = `${tradeType} FLO`
getRef('quantity_type').textContent = tradeType === 'buy' ? `Rupee` : `FLO`
getRef('trade_button').textContent = `${tradeType} ${selectedAsset}`
getRef('quantity_type').textContent = tradeType === 'buy' ? formatAmount(allTokens.rupee.net) : `${parseFloat(allTokens[selectedAsset].net.toFixed(3))} ${selectedAsset}`
getRef('quantity_selector').querySelectorAll('.button').forEach(button => {
if (tradeType === 'buy') {
button.title = `Buy ${selectedAsset} worth ${button.textContent} of total rupee`
} else {
button.title = `Sell ${button.textContent} of total ${selectedAsset}`
}
})
})
async function tradeFlo() {
const asset = getRef('get_asset').value;
const asset = pagesData.params.asset;
const quantity = parseFloat(getRef('get_quantity').value)
const price = parseFloat(getRef('get_price').value)
showProcess('trade_button_wrapper')
@ -1052,18 +1132,19 @@
const target = e.target.closest('button')
const unitValue = parseFloat(getRef('get_price').value)
const fraction = parseFloat(target.value)
const selectedAsset = pagesData.params.asset
if (tradeType === 'buy') {
getRef('get_total').value = parseFloat((fraction * balance.rupee).toFixed(2))
getRef('get_quantity').value = parseFloat(((balance.rupee * fraction) / unitValue).toFixed(4))
console.log(parseFloat((fraction * allTokens['rupee'].net).toFixed(2)), parseFloat(((allTokens['rupee'].net * fraction) / unitValue).toFixed(4)))
getRef('get_total').value = parseFloat((fraction * allTokens['rupee'].net).toFixed(2))
getRef('get_quantity').value = parseFloat(((allTokens['rupee'].net * fraction) / unitValue).toFixed(4))
} else {
console.log(fraction, balance.flo, floExchangeRate)
getRef('get_total').value = parseFloat((fraction * balance.flo * floExchangeRate).toFixed(2))
getRef('get_quantity').value = parseFloat((balance.flo * fraction).toFixed(4))
getRef('get_total').value = parseFloat((fraction * allTokens[selectedAsset].net * floGlobals.exchangeRates[selectedAsset]).toFixed(2))
getRef('get_quantity').value = parseFloat((allTokens[selectedAsset].net * fraction).toFixed(4))
}
}
})
getRef('get_price').addEventListener('keyup', e => {
const unitValue = parseFloat(getRef('get_price').value) || floExchangeRate
const unitValue = parseFloat(getRef('get_price').value) || floGlobals.exchangeRates[pagesData.params.asset]
const quantity = parseFloat(getRef('get_quantity').value) || 0
getRef('get_total').value = parseFloat((quantity * unitValue).toFixed(2)) || 0
})
@ -1089,16 +1170,14 @@
getRef('get_user_amount').setAttribute('step', asset === 'FLO' ? '0.0001' : '0.01')
getRef('get_user_amount').setAttribute('min', asset === 'FLO' ? '0.0001' : '0.01')
if (type === 'withdraw') {
getRef('get_private_key').classList.add('hide-completely')
getRef('wallet_quantity_selector').classList.remove('hide-completely')
getRef('get_private_key').classList.add('hide')
getRef('wallet_quantity_selector').classList.remove('hide')
getRef('get_private_key').removeAttribute('required')
getRef('get_private_key').removeAttribute('hiderequired')
} else {
getRef('get_private_key').setAttribute('required', '')
getRef('wallet_quantity_selector').classList.add('hide-completely')
getRef('get_private_key').setAttribute('hiderequired', '')
getRef('get_private_key').classList.remove('hide-completely')
getRef('wallet_quantity_selector').classList.add('hide')
getRef('get_private_key').classList.remove('hide')
}
getRef('wallet_form').elementsChanged()
}
@ -1128,8 +1207,8 @@
getRef('wallet_result__description').textContent = description
getRef('wallet_form').animate(slideOutLeft, animOptions)
.onfinish = () => {
getRef('wallet_form').classList.add('hide-completely')
getRef('wallet_result').classList.remove('hide-completely')
getRef('wallet_form').classList.add('hide')
getRef('wallet_result').classList.remove('hide')
getRef('wallet_result').animate(slideInLeft, animOptions)
}
}
@ -1141,8 +1220,8 @@
}
getRef('wallet_result').animate(slideOutRight, animOptions)
.onfinish = () => {
getRef('wallet_result').classList.add('hide-completely')
getRef('wallet_form').classList.remove('hide-completely')
getRef('wallet_result').classList.add('hide')
getRef('wallet_form').classList.remove('hide')
getRef('wallet_form').animate(slideInRight, animOptions)
}
}
@ -1150,9 +1229,9 @@
// Get latest balance and exchange rate
if (e.target.closest('button')) {
const target = e.target.closest('button')
const asset = getRef('wallet_asset_selector').value.toLowerCase()
const asset = getRef('wallet_asset_selector').value
const fraction = parseFloat(target.value)
getRef('get_user_amount').value = parseFloat((balance[asset] * fraction).toFixed(asset === "flo" ? 4 : 2))
getRef('get_user_amount').value = parseFloat((allTokens[asset].net * fraction).toFixed(asset === "rupee" ? 2 : 4))
}
})
getRef('wallet_popup__cta').addEventListener('click', async e => {
@ -1263,14 +1342,14 @@
selectedOrders.delete(target.dataset.id)
}
getRef('selected_orders').textContent = `${selectedOrders.size} selected`
if (selectedOrders.size === 1 && !getRef('my_orders_section__header').children[0].classList.contains('hide-completely')) {
if (selectedOrders.size === 1 && !getRef('my_orders_section__header').children[0].classList.contains('hide')) {
getRef('my_orders_section__header').children[0].animate(slideOutLeft, animOptions)
.onfinish = () => {
getRef('my_orders_section__header').children[0].classList.add('hide-completely')
getRef('my_orders_section__header').children[1].classList.remove('hide-completely')
getRef('my_orders_section__header').children[0].classList.add('hide')
getRef('my_orders_section__header').children[1].classList.remove('hide')
getRef('my_orders_section__header').children[1].animate(slideInLeft, animOptions)
}
} else if (selectedOrders.size === 0 && getRef('my_orders_section__header').children[0].classList.contains('hide-completely')) {
} else if (selectedOrders.size === 0 && getRef('my_orders_section__header').children[0].classList.contains('hide')) {
hideMyOrdersOptions()
}
})
@ -1282,8 +1361,8 @@
}
getRef('my_orders_section__header').children[1].animate(slideOutRight, animOptions)
.onfinish = () => {
getRef('my_orders_section__header').children[1].classList.add('hide-completely')
getRef('my_orders_section__header').children[0].classList.remove('hide-completely')
getRef('my_orders_section__header').children[1].classList.add('hide')
getRef('my_orders_section__header').children[0].classList.remove('hide')
getRef('my_orders_section__header').children[0].animate(slideInRight, animOptions)
}
}
@ -1295,16 +1374,16 @@
const target = e.target.closest('.more-info')
showPopup('transaction_info_popup')
if (target.dataset.buyer !== 'undefined') {
getRef('transaction__buyer_wrapper').classList.remove('hide-completely')
getRef('transaction__buyer_wrapper').classList.remove('hide')
getRef('transaction__buyer').value = target.dataset.buyer
} else {
getRef('transaction__buyer_wrapper').classList.add('hide-completely')
getRef('transaction__buyer_wrapper').classList.add('hide')
}
if (target.dataset.seller !== 'undefined') {
getRef('transaction__seller_wrapper').classList.remove('hide-completely')
getRef('transaction__seller_wrapper').classList.remove('hide')
getRef('transaction__seller').value = target.dataset.seller
} else {
getRef('transaction__seller_wrapper').classList.add('hide-completely')
getRef('transaction__seller_wrapper').classList.add('hide')
}
getRef('transaction_time__label').textContent = target.dataset.pending === 'true' ? 'Placed on' : 'Completed on'
getRef('transaction_time').textContent = getFormattedTime(target.dataset.time)
@ -1601,30 +1680,33 @@
})
}
}
let floExchangeRate = 0
function updateRate(init = false) {
floExchangeAPI.getRates().then(rates => {
console.debug(rates);
if (init) {
let assetList = getRef('get_asset');
let walletList = getRef('wallet_asset_selector');
let c = document.createElement('sm-option');
c.setAttribute('value', floGlobals.currency);
c.innerText = floGlobals.currency;
walletList.appendChild(c);
for (let asset in rates) {
let e = document.createElement('sm-option');
e.setAttribute('value', asset);
e.innerText = asset;
assetList.appendChild(e);
walletList.appendChild(e.cloneNode(true));
floGlobals.exchangeRates = rates
getRef('wallet_asset_selector').append(
createElement('sm-option', {
textContent: floGlobals.currency,
attributes: { value: floGlobals.currency },
})
);
Object.entries(rates).sort((a, b) => a[1] < b[1] ? 1 : -1).forEach(([asset, rate]) => {
if (!allTokens.hasOwnProperty(asset)) {
allTokens[asset] = {
total: 0,
locked: 0,
net: 0
}
}
let flo_rate = rates["FLO"];
floExchangeRate = parseFloat(flo_rate)
getRef('flo_rate').textContent = formatAmount(parseFloat(flo_rate))
getRef('get_price').value = parseFloat(parseFloat(flo_rate).toFixed(2))
getRef('listed_assets').append(render.listedAsset(asset, formatAmount(parseFloat(rate))));
getRef('wallet_asset_selector').append(createElement('sm-option', {
textContent: asset,
attributes: { value: asset },
}));
})
}
getRef('get_price').value = parseFloat(parseFloat(rates["FLO"]).toFixed(2))
}).catch(error => console.error(error))
}
@ -1632,10 +1714,9 @@
if (init) {
console.info("init");
if (!proxy.userID) {
getRef('home').classList.remove('signed-in');
floExchangeAPI.getLoginCode().then(response => {
getRef("login_form").classList.remove('hide-completely');
document.querySelectorAll(".user-content").forEach(elem => elem.classList.add('hide-completely'))
getRef("login_form").classList.remove('hide');
document.querySelectorAll(".user-content").forEach(elem => elem.classList.add('hide'))
getRef('sign_in_code').value = response.code;
getRef('sign_in_hash').value = response.hash;
proxy.clear();
@ -1662,40 +1743,51 @@
getRef(`${type}_balance`).append(card)
}
const balance = {}
let accountDetails = {}
const allTokens = {}
async function account() {
floExchangeAPI.getAccount(proxy.userID, await proxy.secret).then(acc => {
getRef("login_form").classList.add('hide-completely')
getRef('home').classList.add('signed-in')
getRef('user_popup_button').classList.remove('hide-completely')
floExchangeAPI.getAccount(proxy.userID, await proxy.secret).then(async acc => {
getRef("login_form").classList.add('hide')
getRef('user_popup_button').classList.remove('hide')
accountDetails = acc
console.debug(acc);
//Element display
document.querySelectorAll(".user-content").forEach(elem => elem.classList.remove('hide-completely'))
getRef('trade_form').classList.remove('hide-completely')
document.querySelectorAll(".user-content").forEach(elem => elem.classList.remove('hide'))
getRef("user_id").value = acc.floID;
getRef("sink_id").value = acc.sinkID;
//FLO Balance
console.debug(acc.vault);
let flo_total = acc.vault.reduce((a, x) => a + (x.asset === "FLO" ? x.quantity : 0), 0);
let flo_locked = acc.sellOrders.reduce((a, x) => a + x.quantity, 0);
let flo_net = flo_total - flo_locked;
console.debug("FLO", flo_total, flo_locked, flo_net);
balance.flo = flo_net
// token balance
acc.vault.forEach(({ asset, quantity }) => {
if (!allTokens.hasOwnProperty(asset)) {
allTokens[asset] = {
total: 0,
locked: 0,
net: 0
}
}
allTokens[asset].total += quantity
})
acc.sellOrders.forEach(({ quantity }) => {
allTokens[asset].locked += quantity
})
for (const asset in allTokens) {
allTokens[asset].net = allTokens[asset].total - allTokens[asset].locked
}
console.debug("FLO", allTokens['FLO']);
showBalance("flo", allTokens['FLO'].net, allTokens['FLO'].locked)
console.log(await floExchangeAPI.getBalance(acc.floID))
showBalance("flo", flo_net, flo_locked,)
//Rupee Balance
let rupee_total = acc.cash;
let rupee_locked = acc.buyOrders.reduce((a, x) => a + x.quantity * x.maxPrice, 0);
let rupee_net = rupee_total - rupee_locked;
console.debug("RUPEE", rupee_total, rupee_locked, rupee_net);
balance.rupee = rupee_net
showBalance("rupee", rupee_net, rupee_locked)
allTokens['rupee'] = {
total: acc.cash,
locked: acc.buyOrders.reduce((a, x) => a + x.quantity * x.maxPrice, 0),
}
allTokens['rupee'].net = allTokens['rupee'].total - allTokens['rupee'].locked
console.debug("RUPEE", allTokens['rupee']);
showBalance("rupee", allTokens['rupee'].net, allTokens['rupee'].locked)
//My orders
renderUserOrders();
proxy.secret.then(_ => null).catch(_ => null);
showPage(window.location.hash)
}).catch(error => console.error(error))
};