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

File diff suppressed because one or more lines are too long

View File

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

View File

@ -21,12 +21,8 @@
<script>console.debug(floExchangeAPI);</script> <script>console.debug(floExchangeAPI);</script>
</head> </head>
<body class="hide-completely"> <body class="hide">
<sm-notifications id="notification_drawer"></sm-notifications> <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"> <sm-popup id="confirmation_popup">
<h4 id="confirm_title"></h4> <h4 id="confirm_title"></h4>
<p id="confirm_message"></p> <p id="confirm_message"></p>
@ -59,7 +55,7 @@
</div> </div>
</div> </div>
<theme-toggle></theme-toggle> <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" <svg xmlns="http://www.w3.org/2000/svg" class="icon" height="24px" viewBox="0 0 24 24" width="24px"
fill="#000000"> fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" /> <path d="M0 0h24v24H0V0z" fill="none" />
@ -68,71 +64,70 @@
</svg> </svg>
</button> </button>
</header> </header>
<section id="dashboard" class="card mobile-page"> <section id="pages_container">
<sm-form id="login_form" class="hide-"> <section id="exchange" class="mobile-page">
<div class="grid gap-0-5"> <sm-form id="login_form">
<h4>Login</h4> <div class="grid gap-0-5">
<p>Please login for trading and accessing your account.</p> <h4>Login</h4>
<p>Please login for exchange.</p>
</div>
<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
</span>
</sm-checkbox>
<input type="text" id="sign_in_code" style="display: none;" hidden />
<input type="text" id="sign_in_hash" style="display: none;" hidden />
<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>
<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>
<div class="grid gap-1 align-start hide user-content">
<h4>Assets</h4>
<ul id="listed_assets" class="user-content hide"></ul>
</div> </div>
<sm-input type="password" id="login_form__priv_key" placeholder="Private key" variant="outlined" animate <sm-form id="trade_form" class="user-content hide hide-on-mobile">
required hiderequired></sm-input> <div class="flex space-between align-center">
<sm-checkbox id="remember_me" checked> <h4 id="traded_asset">Trade FLO</h4>
<span class="button__icon--right"> <strip-select id="trade_type_selector" class="tab">
Remember me <strip-option value="buy" selected>Buy</strip-option>
</span> <strip-option value="sell">Sell</strip-option>
</sm-checkbox> </strip-select>
<input type="text" id="sign_in_code" style="display: none;" hidden /> </div>
<input type="text" id="sign_in_hash" style="display: none;" hidden /> <sm-input id="get_price" placeholder="Max price (₹)" type="number" step="0.01" required animate>
<div id="login_button_wrapper" class="stateful-button-wrapper"> </sm-input>
<sm-button variant="primary" onclick="UI_evt.login();">Log in</sm-button> <sm-input id="get_quantity" placeholder="Quantity" type="number" step="0.0001" required animate>
</div> </sm-input>
<sm-button onclick="showPopup('registration_popup')" style="display: none;" disabled>Not registered? click here!</sm-button> </sm-input>
<div class="grid gap-0-5"> <sm-input id="get_total" placeholder="Total (₹)" type="number" min="0.01" step="0.01" required
<p>Don't have FLO credentials?</p> animate>
<sm-button onclick="showPopup('sign_up_popup')">Generate FLO credentials</sm-button> </sm-input>
</div> <div id="quantity_selector" class="flex align-center quantity-selector">
<sm-button onclick="floExchangeAPI.clearAllLocalData()">clear local data</sm-button> <span id="quantity_type">Rupee</span>
</sm-form> <button class="button" value="0.25" title="Buy FLO worth 25% of total rupee">25%</button>
<sm-form id="trade_form" class="user-content hide-completely"> <button class="button" value="0.5" title="Buy FLO worth 50% of total rupee">50%</button>
<div id="flo_exchange_rate" class="grid align-center"> <button class="button" value="0.75" title="Buy FLO worth 75% of total rupee">75%</button>
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <button class="button" value="1" title="Buy FLO worth 100% of total rupee">100%</button>
<path </div>
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" /> <div id="trade_button_wrapper" class="stateful-button-wrapper flex align-center justify-center">
</svg> <sm-button id="trade_button" class="uppercase w-100" variant="primary" onclick="tradeFlo()">
<p><b>FLO</b>/INR</p> BUY
<span id="flo_rate"></span> FLO
</div> </sm-button>
<div class="flex space-between align-center"> </div>
<h4>Trade FLO</h4> </sm-form>
<strip-select id="trade_type_selector" class="tab"> </section>
<strip-option value="buy" selected>Buy</strip-option> <section id="my_orders" class="grid gap-1 hide mobile-page">
<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>
<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>
<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>
</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>
</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">
<div id="my_orders_section__header" class="orders_section__header flex"> <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"> <div id="orders_section__header--primary" class="flex w-100 align-center space-between">
<h4> <h4>
@ -143,8 +138,7 @@
<strip-option value="completed">History</strip-option> <strip-option value="completed">History</strip-option>
</strip-select> </strip-select>
</div> </div>
<div id="orders_section__header--secondary" <div id="orders_section__header--secondary" class="flex w-100 align-center space-between hide">
class="flex w-100 align-center space-between hide-completely">
<button class="" onclick="clearSelection()" title="Clear all selection"> <button class="" onclick="clearSelection()" title="Clear all selection">
<svg xmlns="http://www.w3.org/2000/svg" class="icon button__icon--left" height="24px" <svg xmlns="http://www.w3.org/2000/svg" class="icon button__icon--left" height="24px"
viewBox="0 0 24 24" width="24px"> viewBox="0 0 24 24" width="24px">
@ -166,7 +160,7 @@
No orders placed No orders placed
</p> </p>
</section> </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"> <div class="orders_section__header flex align-center space-between">
<h4 class="flex align-center"> <h4 class="flex align-center">
Market orders Market orders
@ -189,110 +183,109 @@
No orders placed No orders placed
</p> </p>
</section> </section>
<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">
<path d="M0 0h24v24H0V0z" fill="none" />
<path
d="M21 7.28V5c0-1.1-.9-2-2-2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-2.28c.59-.35 1-.98 1-1.72V9c0-.74-.41-1.37-1-1.72zM20 9v6h-7V9h7zM5 19V5h14v2h-6c-1.1 0-2 .9-2 2v6c0 1.1.9 2 2 2h6v2H5z" />
<circle cx="16" cy="12" r="1.5" />
</svg>
My wallet
</h4>
<div id="wallet_actions">
<p class="label">Select asset</p>
<sm-select id="wallet_asset_selector"></sm-select>
<div class="flex wallet_actions__wrapper">
<button class="button" value="deposit">
Deposit
</button>
<button class="button" value="withdraw">
Withdraw
</button>
</div>
</div>
<div class="grid gap-0-5">
<h4>Balance</h4>
<div class="grid gap-1">
<div class="balance-card">
<div class="balance-card__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>
</div>
<div class="balance-card__token">FLO</div>
<div id="flo_balance"></div>
</div>
<div class="balance-card">
<div class="balance-card__icon">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
d="M15.3,4.91a4.78,4.78,0,0,0-.39-.5l3.14,0L18.75,2H6L5.25,4.6H9a4.22,4.22,0,0,1,3.06,1,3.16,3.16,0,0,1,.75,1.24H5.93L5.25,9.22h7.62a3.15,3.15,0,0,1-.34.82,3,3,0,0,1-1.37,1.17,5.34,5.34,0,0,1-2.2.4H5.5l0,1.9,7,8.49h3.56v-.17L9.68,14l.09,0a8.07,8.07,0,0,0,3.65-1,5,5,0,0,0,2-2.09A6.29,6.29,0,0,0,16,9.22h2.1l.69-2.42H15.93A5.93,5.93,0,0,0,15.3,4.91Z" />
</svg>
</div>
<div class="balance-card__token">Rupee</div>
<div id="rupee_balance"></div>
</div>
</div>
</div>
</section>
</section> </section>
<section id="user_section" class="grid card user-content mobile-page hide-completely hide-on-mobile"> <nav id="main_navbar" class="flex align-center">
<h4 class="flex align-center user_section__header"> <a href="#/exchange" class="main_navbar__item main_navbar__item--active interact">
<svg xmlns="http://www.w3.org/2000/svg" class="icon button__icon--left" height="24px" <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"> 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">Exchange</div>
</a>
<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" />
<g>
<path
d="M19.5,3.5L18,2l-1.5,1.5L15,2l-1.5,1.5L12,2l-1.5,1.5L9,2L7.5,3.5L6,2v14H3v3c0,1.66,1.34,3,3,3h12c1.66,0,3-1.34,3-3V2 L19.5,3.5z M15,20H6c-0.55,0-1-0.45-1-1v-1h10V20z M19,19c0,0.55-0.45,1-1,1s-1-0.45-1-1v-3H8V5h11V19z" />
<rect height="2" width="6" x="9" y="7" />
<rect height="2" width="2" x="16" y="7" />
<rect height="2" width="6" x="9" y="10" />
<rect height="2" width="2" x="16" y="10" />
</g>
</svg>
<div class="item__title">My orders</div>
</a>
<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>
<rect fill="none" height="24" width="24" />
</g>
<g>
<g />
<g>
<path
d="M21.9,8.89l-1.05-4.37c-0.22-0.9-1-1.52-1.91-1.52H5.05C4.15,3,3.36,3.63,3.15,4.52L2.1,8.89 c-0.24,1.02-0.02,2.06,0.62,2.88C2.8,11.88,2.91,11.96,3,12.06V19c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2v-6.94 c0.09-0.09,0.2-0.18,0.28-0.28C21.92,10.96,22.15,9.91,21.9,8.89z M18.91,4.99l1.05,4.37c0.1,0.42,0.01,0.84-0.25,1.17 C19.57,10.71,19.27,11,18.77,11c-0.61,0-1.14-0.49-1.21-1.14L16.98,5L18.91,4.99z M13,5h1.96l0.54,4.52 c0.05,0.39-0.07,0.78-0.33,1.07C14.95,10.85,14.63,11,14.22,11C13.55,11,13,10.41,13,9.69V5z M8.49,9.52L9.04,5H11v4.69 C11,10.41,10.45,11,9.71,11c-0.34,0-0.65-0.15-0.89-0.41C8.57,10.3,8.45,9.91,8.49,9.52z M4.04,9.36L5.05,5h1.97L6.44,9.86 C6.36,10.51,5.84,11,5.23,11c-0.49,0-0.8-0.29-0.93-0.47C4.03,10.21,3.94,9.78,4.04,9.36z M5,19v-6.03C5.08,12.98,5.15,13,5.23,13 c0.87,0,1.66-0.36,2.24-0.95c0.6,0.6,1.4,0.95,2.31,0.95c0.87,0,1.65-0.36,2.23-0.93c0.59,0.57,1.39,0.93,2.29,0.93 c0.84,0,1.64-0.35,2.24-0.95c0.58,0.59,1.37,0.95,2.24,0.95c0.08,0,0.15-0.02,0.23-0.03V19H5z" />
</g>
</g>
</svg>
<div class="item__title">Market</div>
</a>
<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" /> <path d="M0 0h24v24H0V0z" fill="none" />
<path <path
d="M21 7.28V5c0-1.1-.9-2-2-2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-2.28c.59-.35 1-.98 1-1.72V9c0-.74-.41-1.37-1-1.72zM20 9v6h-7V9h7zM5 19V5h14v2h-6c-1.1 0-2 .9-2 2v6c0 1.1.9 2 2 2h6v2H5z" /> d="M21 7.28V5c0-1.1-.9-2-2-2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-2.28c.59-.35 1-.98 1-1.72V9c0-.74-.41-1.37-1-1.72zM20 9v6h-7V9h7zM5 19V5h14v2h-6c-1.1 0-2 .9-2 2v6c0 1.1.9 2 2 2h6v2H5z" />
<circle cx="16" cy="12" r="1.5" /> <circle cx="16" cy="12" r="1.5" />
</svg> </svg>
My wallet <div class="item__title">Wallet</div>
</h4> </a>
<div id="wallet_actions"> </nav>
<p class="label">Select asset</p>
<sm-select id="wallet_asset_selector">
</sm-select>
<div class="flex wallet_actions__wrapper">
<button class="button" value="deposit">
Deposit
</button>
<button class="button" value="withdraw">
Withdraw
</button>
</div>
</div>
<div class="grid gap-0-5">
<h4>Balance</h4>
<div class="grid gap-1">
<div class="balance-card">
<div class="balance-card__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>
</div>
<div class="balance-card__token">FLO</div>
<div id="flo_balance"></div>
</div>
<div class="balance-card">
<div class="balance-card__icon">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
d="M15.3,4.91a4.78,4.78,0,0,0-.39-.5l3.14,0L18.75,2H6L5.25,4.6H9a4.22,4.22,0,0,1,3.06,1,3.16,3.16,0,0,1,.75,1.24H5.93L5.25,9.22h7.62a3.15,3.15,0,0,1-.34.82,3,3,0,0,1-1.37,1.17,5.34,5.34,0,0,1-2.2.4H5.5l0,1.9,7,8.49h3.56v-.17L9.68,14l.09,0a8.07,8.07,0,0,0,3.65-1,5,5,0,0,0,2-2.09A6.29,6.29,0,0,0,16,9.22h2.1l.69-2.42H15.93A5.93,5.93,0,0,0,15.3,4.91Z" />
</svg>
</div>
<div class="balance-card__token">Rupee</div>
<div id="rupee_balance"></div>
</div>
</div>
</div>
</section>
</article> </article>
<footer id="bottom_nav" class="flex align-center hide-on-desktop">
<a href="#/dashboard" class="bottom_nav__item bottom_nav__item--active">
<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>
</a>
<a href="#/my_orders" class="bottom_nav__item user-content hide-completely">
<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" />
<g>
<path
d="M19.5,3.5L18,2l-1.5,1.5L15,2l-1.5,1.5L12,2l-1.5,1.5L9,2L7.5,3.5L6,2v14H3v3c0,1.66,1.34,3,3,3h12c1.66,0,3-1.34,3-3V2 L19.5,3.5z M15,20H6c-0.55,0-1-0.45-1-1v-1h10V20z M19,19c0,0.55-0.45,1-1,1s-1-0.45-1-1v-3H8V5h11V19z" />
<rect height="2" width="6" x="9" y="7" />
<rect height="2" width="2" x="16" y="7" />
<rect height="2" width="6" x="9" y="10" />
<rect height="2" width="2" x="16" y="10" />
</g>
</svg>
<div class="item__title">My orders</div>
</a>
<a href="#/market" class="bottom_nav__item">
<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>
<rect fill="none" height="24" width="24" />
</g>
<g>
<g />
<g>
<path
d="M21.9,8.89l-1.05-4.37c-0.22-0.9-1-1.52-1.91-1.52H5.05C4.15,3,3.36,3.63,3.15,4.52L2.1,8.89 c-0.24,1.02-0.02,2.06,0.62,2.88C2.8,11.88,2.91,11.96,3,12.06V19c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2v-6.94 c0.09-0.09,0.2-0.18,0.28-0.28C21.92,10.96,22.15,9.91,21.9,8.89z M18.91,4.99l1.05,4.37c0.1,0.42,0.01,0.84-0.25,1.17 C19.57,10.71,19.27,11,18.77,11c-0.61,0-1.14-0.49-1.21-1.14L16.98,5L18.91,4.99z M13,5h1.96l0.54,4.52 c0.05,0.39-0.07,0.78-0.33,1.07C14.95,10.85,14.63,11,14.22,11C13.55,11,13,10.41,13,9.69V5z M8.49,9.52L9.04,5H11v4.69 C11,10.41,10.45,11,9.71,11c-0.34,0-0.65-0.15-0.89-0.41C8.57,10.3,8.45,9.91,8.49,9.52z M4.04,9.36L5.05,5h1.97L6.44,9.86 C6.36,10.51,5.84,11,5.23,11c-0.49,0-0.8-0.29-0.93-0.47C4.03,10.21,3.94,9.78,4.04,9.36z M5,19v-6.03C5.08,12.98,5.15,13,5.23,13 c0.87,0,1.66-0.36,2.24-0.95c0.6,0.6,1.4,0.95,2.31,0.95c0.87,0,1.65-0.36,2.23-0.93c0.59,0.57,1.39,0.93,2.29,0.93 c0.84,0,1.64-0.35,2.24-0.95c0.58,0.59,1.37,0.95,2.24,0.95c0.08,0,0.15-0.02,0.23-0.03V19H5z" />
</g>
</g>
</svg>
<div class="item__title">Market</div>
</a>
<a href="#/wallet" class="bottom_nav__item user-content hide-completely">
<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" />
<path
d="M21 7.28V5c0-1.1-.9-2-2-2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-2.28c.59-.35 1-.98 1-1.72V9c0-.74-.41-1.37-1-1.72zM20 9v6h-7V9h7zM5 19V5h14v2h-6c-1.1 0-2 .9-2 2v6c0 1.1.9 2 2 2h6v2H5z" />
<circle cx="16" cy="12" r="1.5" />
</svg>
<div class="item__title">Wallet</div>
</a>
</footer>
<sm-popup id="user_popup"> <sm-popup id="user_popup">
<header slot="header" class="popup__header"> <header slot="header" class="popup__header">
<button class="popup__header__close" onclick="hidePopup()"> <button class="popup__header__close" onclick="hidePopup()">
@ -336,8 +329,8 @@
<div class="grid gap-1-5"> <div class="grid gap-1-5">
<sm-form id="register_section"> <sm-form id="register_section">
<p>Enter the private key of FLO ID you want to register.</p> <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" <sm-input id="get_registration_key" placeholder="Private key" type="password" required>
required hiderequired></sm-input> </sm-input>
<sm-button variant="primary" onclick="UI_evt.signup()" disabled>Register</sm-button> <sm-button variant="primary" onclick="UI_evt.signup()" disabled>Register</sm-button>
</sm-form> </sm-form>
</div> </div>
@ -364,7 +357,8 @@
<sm-copy id="generated_private_key"></sm-copy> <sm-copy id="generated_private_key"></sm-copy>
</div> </div>
</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> </sm-button>
<strong class="warning"> <strong class="warning">
Keep your private key secure and don't share with anyone. Keep your private key secure and don't share with anyone.
@ -385,8 +379,8 @@
</header> </header>
<sm-form id="wallet_form"> <sm-form id="wallet_form">
<input type="text" id="sink_id" style="display: none;" hidden /> <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" <sm-input id="get_user_amount" placeholder="Quantity" type="number" min="0.01" step="0.00001" required
step="0.00001" required hiderequired animate> animate>
</sm-input> </sm-input>
<div id="wallet_quantity_selector" class="flex align-center quantity-selector"> <div id="wallet_quantity_selector" class="flex align-center quantity-selector">
<span id="wallet_quantity_type">Rupee</span> <span id="wallet_quantity_type">Rupee</span>
@ -395,14 +389,14 @@
<button class="button" value="0.75">75%</button> <button class="button" value="0.75">75%</button>
<button class="button" value="1">100%</button> <button class="button" value="1">100%</button>
</div> </div>
<sm-input id="get_private_key" variant="outlined" placeholder="FLO private key" type="password" required <sm-input id="get_private_key" placeholder="FLO private key" type="password" required
error-text="Invalid private key" hiderequired animate> error-text="Invalid private key" animate>
</sm-input> </sm-input>
<div id="wallet_popup__cta_wrapper" class="stateful-button-wrapper"> <div id="wallet_popup__cta_wrapper" class="stateful-button-wrapper">
<sm-button id="wallet_popup__cta" class="uppercase" variant="primary"></sm-button> <sm-button id="wallet_popup__cta" class="uppercase" variant="primary"></sm-button>
</div> </div>
</sm-form> </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 id="wallet_result__icon"></div>
<div class="grid gap-0-5"> <div class="grid gap-0-5">
<h4 id="wallet_result__title"></h4> <h4 id="wallet_result__title"></h4>
@ -437,6 +431,18 @@
</div> </div>
</div> </div>
</sm-popup> </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"> <template id="net_balance_template">
<span class="available-balance"></span> <span class="available-balance"></span>
</template> </template>
@ -724,10 +730,6 @@
break; break;
} }
getRef("notification_drawer").push(message, { pinned, icon }); getRef("notification_drawer").push(message, { pinned, icon });
if (navigator.onLine && sound) {
getRef("notification_sound").currentTime = 0;
getRef("notification_sound").play();
}
if (mode === 'error') { if (mode === 'error') {
console.error(message) console.error(message)
} }
@ -784,8 +786,7 @@
window.addEventListener('hashchange', e => showPage(window.location.hash)) window.addEventListener('hashchange', e => showPage(window.location.hash))
window.addEventListener("load", () => { window.addEventListener("load", () => {
showPage(window.location.hash) document.body.classList.remove('hide')
document.body.classList.remove('hide-completely')
document.querySelectorAll('sm-input[data-private-key]').forEach(input => input.customValidation = floCrypto.getPubKeyHex) document.querySelectorAll('sm-input[data-private-key]').forEach(input => input.customValidation = floCrypto.getPubKeyHex)
document.addEventListener('keyup', (e) => { document.addEventListener('keyup', (e) => {
if (e.key === 'Escape') { if (e.key === 'Escape') {
@ -795,17 +796,51 @@
document.addEventListener('copy', () => { document.addEventListener('copy', () => {
notify('copied', 'success') 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 = { const pagesData = {
openedPages: [], lastPage: '',
params: {} params: {}
} }
async function showPage(targetPage, options = {}) { async function showPage(targetPage, options = {}) {
const { firstLoad, hashChange } = options const { firstLoad, hashChange } = options
let pageId let pageId
let params let subPageId
let params = {}
let searchParams
if (targetPage === '') { if (targetPage === '') {
if (typeof proxy.userID === "undefined") { if (typeof proxy.userID === "undefined") {
pageId = 'landing' pageId = 'landing'
@ -814,53 +849,72 @@
} }
} else { } else {
if (targetPage.includes('/')) { if (targetPage.includes('/')) {
const pages = targetPage.split('/') if (targetPage.includes('?')) {
pageId = pages[1] 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 { } else {
pageId = targetPage pageId = targetPage
} }
} }
if (pagesData.lastPage !== pageId) { if (searchParams) {
let target const urlSearchParams = new URLSearchParams('?' + searchParams);
switch (pageId) { params = Object.fromEntries(urlSearchParams.entries());
case 'dashboard':
target = 'dashboard'
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([
{
transform: 'translateY(1rem)',
opacity: 0,
},
{
transform: 'none',
opacity: 1,
},
],
{
duration: 300,
easing: 'ease'
})
pagesData.lastPage = target
if (!pagesData.openedPages.includes(target)) {
pagesData.openedPages.push(target)
}
}
} }
switch (pageId) {
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':
break;
case 'market':
break;
case 'wallet':
break;
}
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([
{
opacity: 0,
},
{
opacity: 1,
},
],
{
duration: 150,
easing: 'ease'
})
pagesData.lastPage = pageId
}
pagesData.params = params
} }
// class based lazy loading // class based lazy loading
class LazyLoader { class LazyLoader {
@ -939,10 +993,27 @@
} }
</script> </script>
<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) { function formatAmount(amount) {
return amount.toLocaleString(`en-IN`, { style: 'currency', currency: 'INR' }) return amount.toLocaleString(`en-IN`, { style: 'currency', currency: 'INR' })
} }
const render = { 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 = {}) { orderCard(orderDetails = {}) {
const { id, asset, quantity, price, time, type } = orderDetails const { id, asset, quantity, price, time, type } = orderDetails
const card = getRef('order_template').content.cloneNode(true).firstElementChild const card = getRef('order_template').content.cloneNode(true).firstElementChild
@ -1010,12 +1081,21 @@
let tradeType = 'buy' let tradeType = 'buy'
getRef('trade_type_selector').addEventListener('change', e => { getRef('trade_type_selector').addEventListener('change', e => {
tradeType = e.detail.value tradeType = e.detail.value
const selectedAsset = pagesData.params.asset
getRef('get_price').setAttribute('placeholder', tradeType === 'buy' ? 'Max price' : 'Min price') getRef('get_price').setAttribute('placeholder', tradeType === 'buy' ? 'Max price' : 'Min price')
getRef('trade_button').textContent = `${tradeType} FLO` getRef('trade_button').textContent = `${tradeType} ${selectedAsset}`
getRef('quantity_type').textContent = tradeType === 'buy' ? `Rupee` : `FLO` 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() { async function tradeFlo() {
const asset = getRef('get_asset').value; const asset = pagesData.params.asset;
const quantity = parseFloat(getRef('get_quantity').value) const quantity = parseFloat(getRef('get_quantity').value)
const price = parseFloat(getRef('get_price').value) const price = parseFloat(getRef('get_price').value)
showProcess('trade_button_wrapper') showProcess('trade_button_wrapper')
@ -1052,18 +1132,19 @@
const target = e.target.closest('button') const target = e.target.closest('button')
const unitValue = parseFloat(getRef('get_price').value) const unitValue = parseFloat(getRef('get_price').value)
const fraction = parseFloat(target.value) const fraction = parseFloat(target.value)
const selectedAsset = pagesData.params.asset
if (tradeType === 'buy') { if (tradeType === 'buy') {
getRef('get_total').value = parseFloat((fraction * balance.rupee).toFixed(2)) console.log(parseFloat((fraction * allTokens['rupee'].net).toFixed(2)), parseFloat(((allTokens['rupee'].net * fraction) / unitValue).toFixed(4)))
getRef('get_quantity').value = parseFloat(((balance.rupee * 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 { } else {
console.log(fraction, balance.flo, floExchangeRate) getRef('get_total').value = parseFloat((fraction * allTokens[selectedAsset].net * floGlobals.exchangeRates[selectedAsset]).toFixed(2))
getRef('get_total').value = parseFloat((fraction * balance.flo * floExchangeRate).toFixed(2)) getRef('get_quantity').value = parseFloat((allTokens[selectedAsset].net * fraction).toFixed(4))
getRef('get_quantity').value = parseFloat((balance.flo * fraction).toFixed(4))
} }
} }
}) })
getRef('get_price').addEventListener('keyup', e => { 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 const quantity = parseFloat(getRef('get_quantity').value) || 0
getRef('get_total').value = parseFloat((quantity * unitValue).toFixed(2)) || 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('step', asset === 'FLO' ? '0.0001' : '0.01')
getRef('get_user_amount').setAttribute('min', asset === 'FLO' ? '0.0001' : '0.01') getRef('get_user_amount').setAttribute('min', asset === 'FLO' ? '0.0001' : '0.01')
if (type === 'withdraw') { if (type === 'withdraw') {
getRef('get_private_key').classList.add('hide-completely') getRef('get_private_key').classList.add('hide')
getRef('wallet_quantity_selector').classList.remove('hide-completely') getRef('wallet_quantity_selector').classList.remove('hide')
getRef('get_private_key').removeAttribute('required') getRef('get_private_key').removeAttribute('required')
getRef('get_private_key').removeAttribute('hiderequired')
} else { } else {
getRef('get_private_key').setAttribute('required', '') getRef('get_private_key').setAttribute('required', '')
getRef('wallet_quantity_selector').classList.add('hide-completely') getRef('wallet_quantity_selector').classList.add('hide')
getRef('get_private_key').setAttribute('hiderequired', '') getRef('get_private_key').classList.remove('hide')
getRef('get_private_key').classList.remove('hide-completely')
} }
getRef('wallet_form').elementsChanged() getRef('wallet_form').elementsChanged()
} }
@ -1128,8 +1207,8 @@
getRef('wallet_result__description').textContent = description getRef('wallet_result__description').textContent = description
getRef('wallet_form').animate(slideOutLeft, animOptions) getRef('wallet_form').animate(slideOutLeft, animOptions)
.onfinish = () => { .onfinish = () => {
getRef('wallet_form').classList.add('hide-completely') getRef('wallet_form').classList.add('hide')
getRef('wallet_result').classList.remove('hide-completely') getRef('wallet_result').classList.remove('hide')
getRef('wallet_result').animate(slideInLeft, animOptions) getRef('wallet_result').animate(slideInLeft, animOptions)
} }
} }
@ -1141,8 +1220,8 @@
} }
getRef('wallet_result').animate(slideOutRight, animOptions) getRef('wallet_result').animate(slideOutRight, animOptions)
.onfinish = () => { .onfinish = () => {
getRef('wallet_result').classList.add('hide-completely') getRef('wallet_result').classList.add('hide')
getRef('wallet_form').classList.remove('hide-completely') getRef('wallet_form').classList.remove('hide')
getRef('wallet_form').animate(slideInRight, animOptions) getRef('wallet_form').animate(slideInRight, animOptions)
} }
} }
@ -1150,9 +1229,9 @@
// Get latest balance and exchange rate // Get latest balance and exchange rate
if (e.target.closest('button')) { if (e.target.closest('button')) {
const target = 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) 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 => { getRef('wallet_popup__cta').addEventListener('click', async e => {
@ -1263,14 +1342,14 @@
selectedOrders.delete(target.dataset.id) selectedOrders.delete(target.dataset.id)
} }
getRef('selected_orders').textContent = `${selectedOrders.size} selected` 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) getRef('my_orders_section__header').children[0].animate(slideOutLeft, animOptions)
.onfinish = () => { .onfinish = () => {
getRef('my_orders_section__header').children[0].classList.add('hide-completely') getRef('my_orders_section__header').children[0].classList.add('hide')
getRef('my_orders_section__header').children[1].classList.remove('hide-completely') getRef('my_orders_section__header').children[1].classList.remove('hide')
getRef('my_orders_section__header').children[1].animate(slideInLeft, animOptions) 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() hideMyOrdersOptions()
} }
}) })
@ -1282,8 +1361,8 @@
} }
getRef('my_orders_section__header').children[1].animate(slideOutRight, animOptions) getRef('my_orders_section__header').children[1].animate(slideOutRight, animOptions)
.onfinish = () => { .onfinish = () => {
getRef('my_orders_section__header').children[1].classList.add('hide-completely') getRef('my_orders_section__header').children[1].classList.add('hide')
getRef('my_orders_section__header').children[0].classList.remove('hide-completely') getRef('my_orders_section__header').children[0].classList.remove('hide')
getRef('my_orders_section__header').children[0].animate(slideInRight, animOptions) getRef('my_orders_section__header').children[0].animate(slideInRight, animOptions)
} }
} }
@ -1295,16 +1374,16 @@
const target = e.target.closest('.more-info') const target = e.target.closest('.more-info')
showPopup('transaction_info_popup') showPopup('transaction_info_popup')
if (target.dataset.buyer !== 'undefined') { 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 getRef('transaction__buyer').value = target.dataset.buyer
} else { } else {
getRef('transaction__buyer_wrapper').classList.add('hide-completely') getRef('transaction__buyer_wrapper').classList.add('hide')
} }
if (target.dataset.seller !== 'undefined') { 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 getRef('transaction__seller').value = target.dataset.seller
} else { } 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__label').textContent = target.dataset.pending === 'true' ? 'Placed on' : 'Completed on'
getRef('transaction_time').textContent = getFormattedTime(target.dataset.time) getRef('transaction_time').textContent = getFormattedTime(target.dataset.time)
@ -1601,30 +1680,33 @@
}) })
} }
} }
let floExchangeRate = 0
function updateRate(init = false) { function updateRate(init = false) {
floExchangeAPI.getRates().then(rates => { floExchangeAPI.getRates().then(rates => {
console.debug(rates); console.debug(rates);
if (init) { if (init) {
let assetList = getRef('get_asset'); floGlobals.exchangeRates = rates
let walletList = getRef('wallet_asset_selector'); getRef('wallet_asset_selector').append(
let c = document.createElement('sm-option'); createElement('sm-option', {
c.setAttribute('value', floGlobals.currency); textContent: floGlobals.currency,
c.innerText = floGlobals.currency; attributes: { value: floGlobals.currency },
walletList.appendChild(c); })
for (let asset in rates) { );
let e = document.createElement('sm-option'); Object.entries(rates).sort((a, b) => a[1] < b[1] ? 1 : -1).forEach(([asset, rate]) => {
e.setAttribute('value', asset); if (!allTokens.hasOwnProperty(asset)) {
e.innerText = asset; allTokens[asset] = {
assetList.appendChild(e); total: 0,
walletList.appendChild(e.cloneNode(true)); locked: 0,
} net: 0
}
}
getRef('listed_assets').append(render.listedAsset(asset, formatAmount(parseFloat(rate))));
getRef('wallet_asset_selector').append(createElement('sm-option', {
textContent: asset,
attributes: { value: asset },
}));
})
} }
let flo_rate = rates["FLO"]; getRef('get_price').value = parseFloat(parseFloat(rates["FLO"]).toFixed(2))
floExchangeRate = parseFloat(flo_rate)
getRef('flo_rate').textContent = formatAmount(parseFloat(flo_rate))
getRef('get_price').value = parseFloat(parseFloat(flo_rate).toFixed(2))
}).catch(error => console.error(error)) }).catch(error => console.error(error))
} }
@ -1632,10 +1714,9 @@
if (init) { if (init) {
console.info("init"); console.info("init");
if (!proxy.userID) { if (!proxy.userID) {
getRef('home').classList.remove('signed-in');
floExchangeAPI.getLoginCode().then(response => { floExchangeAPI.getLoginCode().then(response => {
getRef("login_form").classList.remove('hide-completely'); getRef("login_form").classList.remove('hide');
document.querySelectorAll(".user-content").forEach(elem => elem.classList.add('hide-completely')) document.querySelectorAll(".user-content").forEach(elem => elem.classList.add('hide'))
getRef('sign_in_code').value = response.code; getRef('sign_in_code').value = response.code;
getRef('sign_in_hash').value = response.hash; getRef('sign_in_hash').value = response.hash;
proxy.clear(); proxy.clear();
@ -1662,40 +1743,51 @@
getRef(`${type}_balance`).append(card) getRef(`${type}_balance`).append(card)
} }
const balance = {}
let accountDetails = {} let accountDetails = {}
const allTokens = {}
async function account() { async function account() {
floExchangeAPI.getAccount(proxy.userID, await proxy.secret).then(acc => { floExchangeAPI.getAccount(proxy.userID, await proxy.secret).then(async acc => {
getRef("login_form").classList.add('hide-completely') getRef("login_form").classList.add('hide')
getRef('home').classList.add('signed-in') getRef('user_popup_button').classList.remove('hide')
getRef('user_popup_button').classList.remove('hide-completely')
accountDetails = acc accountDetails = acc
console.debug(acc); console.debug(acc);
//Element display //Element display
document.querySelectorAll(".user-content").forEach(elem => elem.classList.remove('hide-completely')) document.querySelectorAll(".user-content").forEach(elem => elem.classList.remove('hide'))
getRef('trade_form').classList.remove('hide-completely')
getRef("user_id").value = acc.floID; getRef("user_id").value = acc.floID;
getRef("sink_id").value = acc.sinkID; getRef("sink_id").value = acc.sinkID;
//FLO Balance // token balance
console.debug(acc.vault); acc.vault.forEach(({ asset, quantity }) => {
let flo_total = acc.vault.reduce((a, x) => a + (x.asset === "FLO" ? x.quantity : 0), 0); if (!allTokens.hasOwnProperty(asset)) {
let flo_locked = acc.sellOrders.reduce((a, x) => a + x.quantity, 0); allTokens[asset] = {
let flo_net = flo_total - flo_locked; total: 0,
console.debug("FLO", flo_total, flo_locked, flo_net); locked: 0,
balance.flo = flo_net 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 //Rupee Balance
let rupee_total = acc.cash; allTokens['rupee'] = {
let rupee_locked = acc.buyOrders.reduce((a, x) => a + x.quantity * x.maxPrice, 0); total: acc.cash,
let rupee_net = rupee_total - rupee_locked; locked: acc.buyOrders.reduce((a, x) => a + x.quantity * x.maxPrice, 0),
console.debug("RUPEE", rupee_total, rupee_locked, rupee_net); }
balance.rupee = rupee_net allTokens['rupee'].net = allTokens['rupee'].total - allTokens['rupee'].locked
showBalance("rupee", rupee_net, rupee_locked) console.debug("RUPEE", allTokens['rupee']);
showBalance("rupee", allTokens['rupee'].net, allTokens['rupee'].locked)
//My orders //My orders
renderUserOrders(); renderUserOrders();
proxy.secret.then(_ => null).catch(_ => null); proxy.secret.then(_ => null).catch(_ => null);
showPage(window.location.hash)
}).catch(error => console.error(error)) }).catch(error => console.error(error))
}; };