Components update and UI tweaks

This commit is contained in:
sairaj mote 2022-11-13 20:49:17 +05:30
parent 580d2a64da
commit 845cfb1873
5 changed files with 304 additions and 3058 deletions

File diff suppressed because one or more lines are too long

View File

@ -90,10 +90,10 @@ a:focus-visible {
box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 1) inset; box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 1) inset;
} }
button { button,
.button {
-webkit-user-select: none; -webkit-user-select: none;
-moz-user-select: none; -moz-user-select: none;
-ms-user-select: none;
user-select: none; user-select: none;
position: relative; position: relative;
display: inline-flex; display: inline-flex;
@ -103,39 +103,62 @@ button {
color: inherit; color: inherit;
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
align-items: center; align-items: center;
font-size: 0.9rem; font-size: inherit;
font-weight: 500; font-weight: 500;
white-space: nowrap; white-space: nowrap;
padding: 0.8rem; padding: 0.8rem;
border-radius: 0.3rem; border-radius: 0.3rem;
justify-content: center; justify-content: center;
text-transform: capitalize;
} }
button:focus-visible { button:focus-visible,
.button:focus-visible {
outline: var(--accent-color) solid medium; outline: var(--accent-color) solid medium;
} }
button:not(:disabled) { button:not(:disabled),
.button:not(:disabled) {
cursor: pointer; cursor: pointer;
} }
.button { .button {
background-color: rgba(var(--text-color), 0.06); background-color: rgba(var(--text-color), 0.02);
border: solid thin rgba(var(--text-color), 0.06);
} }
.button--primary,
.button--danger {
color: rgba(var(--background-color), 1);
}
.button--primary .icon,
.button--danger .icon {
fill: rgba(var(--background-color), 1);
}
.button--primary { .button--primary {
color: rgba(var(--background-color), 1);
background-color: var(--accent-color); background-color: var(--accent-color);
} }
.button--primary .icon {
fill: rgba(var(--background-color), 1);
}
.button--colored {
color: var(--accent-color);
}
.button--colored .icon {
fill: var(--accent-color);
}
.button--danger { .button--danger {
background-color: var(--danger-color); background-color: rgba(255, 115, 115, 0.062745098);
color: var(--danger-color);
}
.button--danger .icon {
fill: var(--danger-color);
}
.button--small {
padding: 0.4rem 0.6rem;
}
.button--outlined {
border: solid rgba(var(--text-color), 0.3) 0.1rem;
background-color: rgba(var(--foreground-color), 1);
}
.button--transparent {
background-color: transparent;
}
button:disabled {
opacity: 0.4;
cursor: not-allowed;
filter: saturate(0);
} }
.cta { .cta {
@ -143,6 +166,7 @@ button:not(:disabled) {
font-size: 0.8rem; font-size: 0.8rem;
font-weight: 700; font-weight: 700;
letter-spacing: 0.05em; letter-spacing: 0.05em;
padding: 0.8rem 1rem;
} }
.icon-only { .icon-only {
@ -150,10 +174,6 @@ button:not(:disabled) {
border-radius: 0.3rem; border-radius: 0.3rem;
} }
button:disabled {
opacity: 0.5;
}
a:-webkit-any-link:focus-visible { a:-webkit-any-link:focus-visible {
outline: rgba(var(--text-color), 1) 0.1rem solid; outline: rgba(var(--text-color), 1) 0.1rem solid;
} }
@ -174,7 +194,6 @@ details summary {
display: flex; display: flex;
-webkit-user-select: none; -webkit-user-select: none;
-moz-user-select: none; -moz-user-select: none;
-ms-user-select: none;
user-select: none; user-select: none;
cursor: pointer; cursor: pointer;
align-items: center; align-items: center;
@ -192,7 +211,7 @@ details[open] > summary .down-arrow {
sm-input, sm-input,
sm-textarea { sm-textarea {
font-size: 0.9rem; font-size: 0.9rem;
--border-radius: 0.3rem; --border-radius: 0.5rem;
--background-color: rgba(var(--foreground-color), 1); --background-color: rgba(var(--foreground-color), 1);
} }
sm-input button .icon, sm-input button .icon,
@ -200,20 +219,6 @@ sm-textarea button .icon {
fill: var(--accent-color); fill: var(--accent-color);
} }
sm-button {
--padding: 0.6rem 0.8rem;
}
sm-button[variant=primary] .icon {
fill: rgba(var(--background-color), 1);
}
sm-button[disabled] .icon {
fill: rgba(var(--text-color), 0.6);
}
sm-button.danger {
--background: var(--danger-color);
color: rgba(var(--background-color), 1);
}
sm-spinner { sm-spinner {
--size: 1rem; --size: 1rem;
--stroke-width: 0.1rem; --stroke-width: 0.1rem;
@ -223,19 +228,18 @@ sm-form {
--gap: 1rem; --gap: 1rem;
} }
strip-select { sm-chips {
--gap: 0; --gap: 0.3rem;
background-color: rgba(var(--text-color), 0.06);
border-radius: 0.3rem;
padding: 0.3rem;
} }
strip-option { sm-chip {
font-size: 0.8rem; position: relative;
--border-radius: 0.2rem; font-size: 0.9rem;
--border-radius: 0.5rem;
--padding: 0.5rem 0.8rem;
--background: rgba(var(--text-color), 0.06);
-webkit-user-select: none; -webkit-user-select: none;
-moz-user-select: none; -moz-user-select: none;
-ms-user-select: none;
user-select: none; user-select: none;
} }
@ -255,7 +259,6 @@ ul {
word-wrap: break-word; word-wrap: break-word;
word-break: break-word; word-break: break-word;
-webkit-hyphens: auto; -webkit-hyphens: auto;
-ms-hyphens: auto;
hyphens: auto; hyphens: auto;
} }
@ -317,6 +320,10 @@ h3 {
grid-auto-flow: column; grid-auto-flow: column;
} }
.gap-0-3 {
gap: 0.3rem;
}
.gap-0-5 { .gap-0-5 {
gap: 0.5rem; gap: 0.5rem;
} }
@ -484,41 +491,34 @@ h3 {
} }
#confirmation_popup h4, #confirmation_popup h4,
#prompt_popup h4 { #prompt_popup h4 {
font-weight: 500;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
} }
#confirmation_popup sm-button,
#prompt_popup sm-button {
margin: 0;
}
#confirmation_popup .flex, #confirmation_popup .flex,
#prompt_popup .flex { #prompt_popup .flex {
padding: 0;
margin-top: 1rem; margin-top: 1rem;
} }
#confirmation_popup .flex sm-button:first-of-type,
#prompt_popup .flex sm-button:first-of-type {
margin-right: 0.6rem;
margin-left: auto;
}
#prompt_message {
margin-bottom: 1.5rem;
}
.popup__header { .popup__header {
position: relative;
display: grid; display: grid;
gap: 0.5rem; gap: 0.5rem;
width: 100%; width: 100%;
padding: 0 1.5rem; padding: 0 1.5rem;
align-items: center; align-items: center;
grid-auto-flow: column;
} }
.popup__header > * {
grid-row: 1;
}
.popup__header h3,
.popup__header h4 {
grid-column: 1/-1;
justify-self: center;
align-self: center;
}
.popup__header__close { .popup__header__close {
padding: 0.5rem; grid-column: 1;
margin-left: -0.5rem; margin-left: -1rem;
cursor: pointer; justify-self: flex-start;
} }
#show_character_count { #show_character_count {
@ -706,7 +706,6 @@ h3 {
background-color: rgba(var(--text-color), 0.03); background-color: rgba(var(--text-color), 0.03);
-webkit-user-select: none; -webkit-user-select: none;
-moz-user-select: none; -moz-user-select: none;
-ms-user-select: none;
user-select: none; user-select: none;
} }
.saved-id.highlight { .saved-id.highlight {
@ -845,6 +844,17 @@ h3 {
fill: rgba(var(--background-color), 1); fill: rgba(var(--background-color), 1);
} }
#balance_card {
display: flex;
flex-direction: column;
gap: 1rem;
padding: max(1rem, 2vw);
background-color: rgba(var(--text-color), 0.06);
aspect-ratio: 4/2;
justify-content: flex-end;
border-radius: 0.5rem;
}
#transaction_result { #transaction_result {
display: grid; display: grid;
gap: 0.5rem; gap: 0.5rem;
@ -936,22 +946,17 @@ h3 {
body { body {
background-size: cover; background-size: cover;
} }
sm-popup { sm-popup {
--width: 24rem; --width: 24rem;
} }
.popup__header { .popup__header {
grid-column: 1/-1;
padding: 1rem 1.5rem 0 1.5rem; padding: 1rem 1.5rem 0 1.5rem;
} }
body { body {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
#main_card { #main_card {
display: grid; display: grid;
grid-template-columns: auto 1fr; grid-template-columns: auto 1fr;
@ -963,15 +968,12 @@ h3 {
box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.05), 0 1rem 3rem rgba(0, 0, 0, 0.2); box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.05), 0 1rem 3rem rgba(0, 0, 0, 0.2);
background-color: rgba(var(--foreground-color), 0.9); background-color: rgba(var(--foreground-color), 0.9);
} }
#main_header { #main_header {
grid-area: header; grid-area: header;
} }
#pages_container { #pages_container {
grid-area: main; grid-area: main;
} }
#main_navbar { #main_navbar {
grid-area: nav; grid-area: nav;
border-top: none; border-top: none;
@ -986,7 +988,6 @@ h3 {
#main_navbar ul li:last-of-type { #main_navbar ul li:last-of-type {
margin-top: auto; margin-top: auto;
} }
.nav-item { .nav-item {
aspect-ratio: 1/1; aspect-ratio: 1/1;
} }
@ -997,12 +998,10 @@ h3 {
border-radius: 0 1rem 1rem 0; border-radius: 0 1rem 1rem 0;
bottom: auto; bottom: auto;
} }
#create_flo_id_popup, #create_flo_id_popup,
#retrieve_flo_id_popup { #retrieve_flo_id_popup {
--width: 26rem; --width: 26rem;
} }
#send sm-form::part(form) { #send sm-form::part(form) {
align-items: flex-start; align-items: flex-start;
grid-template-columns: 45% 1fr; grid-template-columns: 45% 1fr;
@ -1019,7 +1018,6 @@ h3 {
width: 0.5rem; width: 0.5rem;
height: 0.5rem; height: 0.5rem;
} }
::-webkit-scrollbar-thumb { ::-webkit-scrollbar-thumb {
background: rgba(var(--text-color), 0.3); background: rgba(var(--text-color), 0.3);
border-radius: 1rem; border-radius: 1rem;
@ -1027,14 +1025,12 @@ h3 {
::-webkit-scrollbar-thumb:hover { ::-webkit-scrollbar-thumb:hover {
background: rgba(var(--text-color), 0.5); background: rgba(var(--text-color), 0.5);
} }
.interact:not([disabled]) { .interact:not([disabled]) {
transition: background-color 0.3s; transition: background-color 0.3s;
} }
.interact:not([disabled]):hover { .interact:not([disabled]):hover {
background-color: rgba(var(--text-color), 0.06); background-color: rgba(var(--text-color), 0.06);
} }
.button:not([disabled]) { .button:not([disabled]) {
transition: background-color 0.3s, filter 0.3s; transition: background-color 0.3s, filter 0.3s;
} }

2
css/main.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -91,7 +91,8 @@ a {
} }
} }
button { button,
.button {
user-select: none; user-select: none;
position: relative; position: relative;
display: inline-flex; display: inline-flex;
@ -101,50 +102,78 @@ button {
color: inherit; color: inherit;
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
align-items: center; align-items: center;
font-size: 0.9rem; font-size: inherit;
font-weight: 500; font-weight: 500;
white-space: nowrap; white-space: nowrap;
padding: 0.8rem; padding: 0.8rem;
border-radius: 0.3rem; border-radius: 0.3rem;
justify-content: center; justify-content: center;
text-transform: capitalize;
&:focus-visible { &:focus-visible {
outline: var(--accent-color) solid medium; outline: var(--accent-color) solid medium;
} }
&:not(:disabled) { &:not(:disabled) {
cursor: pointer; cursor: pointer;
} }
} }
.button { .button {
background-color: rgba(var(--text-color), 0.06); background-color: rgba(var(--text-color), 0.02);
} border: solid thin rgba(var(--text-color), 0.06);
.button--primary, &--primary {
.button--danger { color: rgba(var(--background-color), 1);
color: rgba(var(--background-color), 1); background-color: var(--accent-color);
.icon {
fill: rgba(var(--background-color), 1); .icon {
fill: rgba(var(--background-color), 1);
}
}
&--colored {
color: var(--accent-color);
.icon {
fill: var(--accent-color);
}
}
&--danger {
background-color: #ff737310;
color: var(--danger-color);
.icon {
fill: var(--danger-color);
}
}
&--small {
padding: 0.4rem 0.6rem;
}
&--outlined {
border: solid rgba(var(--text-color), 0.3) 0.1rem;
background-color: rgba(var(--foreground-color), 1);
}
&--transparent {
background-color: transparent;
} }
} }
.button--primary { button:disabled {
background-color: var(--accent-color); opacity: 0.4;
} cursor: not-allowed;
.button--danger { filter: saturate(0);
background-color: var(--danger-color);
} }
.cta { .cta {
text-transform: uppercase; text-transform: uppercase;
font-size: 0.8rem; font-size: 0.8rem;
font-weight: 700; font-weight: 700;
letter-spacing: 0.05em; letter-spacing: 0.05em;
padding: 0.8rem 1rem;
} }
.icon-only { .icon-only {
padding: 0.5rem; padding: 0.5rem;
border-radius: 0.3rem; border-radius: 0.3rem;
} }
button:disabled {
opacity: 0.5;
}
a:any-link:focus-visible { a:any-link:focus-visible {
outline: rgba(var(--text-color), 1) 0.1rem solid; outline: rgba(var(--text-color), 1) 0.1rem solid;
} }
@ -173,7 +202,7 @@ details[open] {
sm-input, sm-input,
sm-textarea { sm-textarea {
font-size: 0.9rem; font-size: 0.9rem;
--border-radius: 0.3rem; --border-radius: 0.5rem;
--background-color: rgba(var(--foreground-color), 1); --background-color: rgba(var(--foreground-color), 1);
button { button {
.icon { .icon {
@ -181,24 +210,6 @@ sm-textarea {
} }
} }
} }
sm-button {
--padding: 0.6rem 0.8rem;
&[variant="primary"] {
.icon {
fill: rgba(var(--background-color), 1);
}
}
&[disabled] {
.icon {
fill: rgba(var(--text-color), 0.6);
}
}
&.danger {
--background: var(--danger-color);
color: rgba(var(--background-color), 1);
}
}
sm-spinner { sm-spinner {
--size: 1rem; --size: 1rem;
--stroke-width: 0.1rem; --stroke-width: 0.1rem;
@ -206,15 +217,16 @@ sm-spinner {
sm-form { sm-form {
--gap: 1rem; --gap: 1rem;
} }
strip-select { sm-chips {
--gap: 0; --gap: 0.3rem;
background-color: rgba(var(--text-color), 0.06);
border-radius: 0.3rem;
padding: 0.3rem;
} }
strip-option {
font-size: 0.8rem; sm-chip {
--border-radius: 0.2rem; position: relative;
font-size: 0.9rem;
--border-radius: 0.5rem;
--padding: 0.5rem 0.8rem;
--background: rgba(var(--text-color), 0.06);
user-select: none; user-select: none;
} }
ul { ul {
@ -287,7 +299,9 @@ h3 {
.flow-column { .flow-column {
grid-auto-flow: column; grid-auto-flow: column;
} }
.gap-0-3 {
gap: 0.3rem;
}
.gap-0-5 { .gap-0-5 {
gap: 0.5rem; gap: 0.5rem;
} }
@ -452,39 +466,37 @@ h3 {
#confirmation_popup, #confirmation_popup,
#prompt_popup { #prompt_popup {
flex-direction: column; flex-direction: column;
h4 { h4 {
font-weight: 500;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
} }
sm-button {
margin: 0;
}
.flex { .flex {
padding: 0;
margin-top: 1rem; margin-top: 1rem;
sm-button:first-of-type {
margin-right: 0.6rem;
margin-left: auto;
}
} }
} }
#prompt_message {
margin-bottom: 1.5rem;
}
.popup__header { .popup__header {
position: relative;
display: grid; display: grid;
gap: 0.5rem; gap: 0.5rem;
width: 100%; width: 100%;
padding: 0 1.5rem; padding: 0 1.5rem;
align-items: center; align-items: center;
grid-auto-flow: column; & > * {
} grid-row: 1;
}
.popup__header__close { h3,
padding: 0.5rem; h4 {
margin-left: -0.5rem; grid-column: 1/-1;
cursor: pointer; justify-self: center;
align-self: center;
}
&__close {
grid-column: 1;
margin-left: -1rem;
justify-self: flex-start;
}
} }
#show_character_count { #show_character_count {
@ -792,7 +804,16 @@ h3 {
fill: rgba(var(--background-color), 1); fill: rgba(var(--background-color), 1);
} }
} }
#balance_card {
display: flex;
flex-direction: column;
gap: 1rem;
padding: max(1rem, 2vw);
background-color: rgba(var(--text-color), 0.06);
aspect-ratio: 4/2;
justify-content: flex-end;
border-radius: 0.5rem;
}
#transaction_result { #transaction_result {
display: grid; display: grid;
gap: 0.5rem; gap: 0.5rem;
@ -877,7 +898,6 @@ h3 {
--width: 24rem; --width: 24rem;
} }
.popup__header { .popup__header {
grid-column: 1/-1;
padding: 1rem 1.5rem 0 1.5rem; padding: 1rem 1.5rem 0 1.5rem;
} }

View File

@ -31,9 +31,9 @@
<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>
<div class="flex align-center"> <div class="flex align-center gap-0-5 margin-left-auto">
<sm-button variant="no-outline" class="cancel-btn">Cancel</sm-button> <button class="button cancel-button">Cancel</button>
<sm-button variant="no-outline" class="submit-btn">OK</sm-button> <button class="button button--primary confirm-button">OK</button>
</div> </div>
</sm-popup> </sm-popup>
<div id="main_card"> <div id="main_card">
@ -256,11 +256,11 @@
</svg> </svg>
<h5>Transactions</h5> <h5>Transactions</h5>
</div> </div>
<strip-select id="filter_selector"> <sm-chips id="filter_selector">
<strip-option value="sent" selected>Sent</strip-option> <sm-chip value="sent" selected>Sent</sm-chip>
<strip-option value="received">Received</strip-option> <sm-chip value="received">Received</sm-chip>
<strip-option value="all">All</strip-option> <sm-chip value="all">All</sm-chip>
</strip-select> </sm-chips>
</div> </div>
<ul id="transactions_list" class="flex"></ul> <ul id="transactions_list" class="flex"></ul>
</div> </div>
@ -286,6 +286,16 @@
</div> </div>
<sm-form id="send_form"> <sm-form id="send_form">
<div class="grid gap-1"> <div class="grid gap-1">
<div id="balance_card">
<h5>Available balance</h5>
<div class="flex align-end gap-0-3">
<b id="sender_balance" style="font-size: 3rem;line-height: 1;">0</b>
<span>FLO</span>
</div>
<p style="line-height: 1.2; opacity: 0.7;">
Sender balance will be shown once you enter a valid address
</p>
</div>
<sm-input id="getBal_addr" class="w-100" placeholder="Sender FLO ID" error-text="Invalid FLO ID" <sm-input id="getBal_addr" class="w-100" placeholder="Sender FLO ID" error-text="Invalid FLO ID"
data-flo-id="" animate required> data-flo-id="" animate required>
<button slot="right" class="icon-only" onclick="showFloIdPicker('sender')" <button slot="right" class="icon-only" onclick="showFloIdPicker('sender')"
@ -298,12 +308,6 @@
</svg> </svg>
</button> </button>
</sm-input> </sm-input>
<div class="flex align-center space-between">
<span id="sender_balance" style="font-size: 0.9rem;"></span>
<button id="getBal_btn" class="button" style="padding: 0.4rem 0.6rem;"
onclick="checkSenderBalance()" disabled>Check
balance</button>
</div>
<sm-input id="receiver" class="w-100" placeholder="Receiver's FLO ID" <sm-input id="receiver" class="w-100" placeholder="Receiver's FLO ID"
error-text="Invalid FLO ID" data-flo-id="" animate required> error-text="Invalid FLO ID" data-flo-id="" animate required>
<button slot="right" class="icon-only" onclick="showFloIdPicker('receiver')" <button slot="right" class="icon-only" onclick="showFloIdPicker('receiver')"
@ -321,7 +325,7 @@
<sm-input id="amount" type="number" placeholder="Amount" step="0.00001" min="0.00001" <sm-input id="amount" type="number" placeholder="Amount" step="0.00001" min="0.00001"
error-text="Invalid amount" animate required> error-text="Invalid amount" animate required>
</sm-input> </sm-input>
<sm-textarea id="flo_data_textarea" placeholder="FLO data" rows="6" maxlength="1040" animate> <sm-textarea id="flo_data_textarea" placeholder="FLO data" rows="4" maxlength="1040" animate>
</sm-textarea> </sm-textarea>
<div id="show_character_count">1040/1040</div> <div id="show_character_count">1040/1040</div>
<p id="flo_data_status"></p> <p id="flo_data_status"></p>
@ -346,7 +350,7 @@
<button class="button button--danger cta justify-self-start" onclick="deleteDB()">Clear <button class="button button--danger cta justify-self-start" onclick="deleteDB()">Clear
data</button> data</button>
</section> </section>
<details> <!-- <details>
<summary> <summary>
<h4>Developer options</h4> <h4>Developer options</h4>
<svg class="icon down-arrow" xmlns="http://www.w3.org/2000/svg" height="24px" <svg class="icon down-arrow" xmlns="http://www.w3.org/2000/svg" height="24px"
@ -364,7 +368,7 @@
</strong> </strong>
</div> </div>
</sm-switch> </sm-switch>
</details> </details> -->
<div class="flex"> <div class="flex">
<b> <b>
Powered by Powered by
@ -415,17 +419,15 @@
</div> </div>
<sm-popup id="add_address_popup"> <sm-popup id="add_address_popup">
<header slot="header" class="popup__header"> <header slot="header" class="popup__header">
<div class="flex align-center"> <button class="popup__header__close" onclick="closePopup()">
<button class="popup__header__close" onclick="closePopup()"> <svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"
<svg class="icon" xmlns="http://www.w3.org/2000/svg" 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" /> <path
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" /> </svg>
</svg> </button>
</button> <h3>Add address</h3>
<h3>Add address</h3>
</div>
</header> </header>
<sm-form> <sm-form>
<sm-input id="floAddr" placeholder="FLO ID" error-text="Invalid FLO ID" autofocus data-flo-id animate <sm-input id="floAddr" placeholder="FLO ID" error-text="Invalid FLO ID" autofocus data-flo-id animate
@ -437,17 +439,15 @@
</sm-popup> </sm-popup>
<sm-popup id="edit_saved_popup"> <sm-popup id="edit_saved_popup">
<header slot="header" class="popup__header"> <header slot="header" class="popup__header">
<div class="flex align-center"> <button class="popup__header__close" onclick="closePopup()">
<button class="popup__header__close" onclick="closePopup()"> <svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"
<svg class="icon" xmlns="http://www.w3.org/2000/svg" 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" /> <path
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" /> </svg>
</svg> </button>
</button> <h3>Edit</h3>
<h3>Edit</h3>
</div>
</header> </header>
<section class="grid gap-1-5"> <section class="grid gap-1-5">
<div class="grid gap-0-5"> <div class="grid gap-0-5">
@ -471,16 +471,14 @@
</sm-popup> </sm-popup>
<sm-popup id="create_flo_id_popup"> <sm-popup id="create_flo_id_popup">
<header slot="header" class="popup__header"> <header slot="header" class="popup__header">
<div class="flex align-center"> <button class="popup__header__close" onclick="closePopup()">
<button class="popup__header__close" onclick="closePopup()"> <svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"
<svg class="icon" xmlns="http://www.w3.org/2000/svg" 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" /> <path
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" /> </svg>
</svg> </button>
</button>
</div>
</header> </header>
<div class="grid gap-2"> <div class="grid gap-2">
<div id="flo_id_warning" class="grid justify-center gap-0-5"> <div id="flo_id_warning" class="grid justify-center gap-0-5">
@ -498,16 +496,14 @@
</sm-popup> </sm-popup>
<sm-popup id="retrieve_flo_id_popup"> <sm-popup id="retrieve_flo_id_popup">
<header slot="header" class="popup__header"> <header slot="header" class="popup__header">
<div class="flex align-center"> <button class="popup__header__close" onclick="closePopup()">
<button class="popup__header__close" onclick="closePopup()"> <svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"
<svg class="icon" xmlns="http://www.w3.org/2000/svg" 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" /> <path
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" /> </svg>
</svg> </button>
</button>
</div>
</header> </header>
<section class="grid gap-1-5"> <section class="grid gap-1-5">
<div class="grid gap-0-5"> <div class="grid gap-0-5">
@ -545,18 +541,17 @@
</sm-popup> </sm-popup>
<sm-popup id="saved_ids_popup"> <sm-popup id="saved_ids_popup">
<header slot="header" class="popup__header"> <header slot="header" class="popup__header">
<div class="grid gap-1"> <button class="popup__header__close justify-self-start" onclick="closePopup()">
<button class="popup__header__close justify-self-start" onclick="closePopup()"> <svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"
<svg class="icon" xmlns="http://www.w3.org/2000/svg" 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" /> <path
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" /> </svg>
</svg> </button>
</button> <h3>Select an address</h3>
<sm-input id="search_saved_ids_picker" placeholder="Search"></sm-input>
</div>
</header> </header>
<sm-input id="search_saved_ids_picker" placeholder="Search"></sm-input>
<section class="grid gap-1"> <section class="grid gap-1">
<ul id="saved_ids_picker_list" class="observe-empty-state grid gap-0-5 h-100" style="overflow-y: auto;"> <ul id="saved_ids_picker_list" class="observe-empty-state grid gap-0-5 h-100" style="overflow-y: auto;">
</ul> </ul>
@ -802,15 +797,19 @@
// displays a popup for asking permission. Use this instead of JS confirm // displays a popup for asking permission. Use this instead of JS confirm
const getConfirmation = (title, options = {}) => { const getConfirmation = (title, options = {}) => {
return new Promise(resolve => { return new Promise(resolve => {
const { message, cancelText = 'Cancel', confirmText = 'OK' } = options const { message = '', cancelText = 'Cancel', confirmText = 'OK', danger = false } = options
openPopup('confirmation_popup', true) openPopup('confirmation_popup', true)
getRef('confirm_title').textContent = title; getRef('confirm_title').innerText = title;
getRef('confirm_message').textContent = message; getRef('confirm_message').innerText = message;
let cancelButton = getRef('confirmation_popup').children[2].children[0], const cancelButton = getRef('confirmation_popup').querySelector('.cancel-button');
submitButton = getRef('confirmation_popup').children[2].children[1] const confirmButton = getRef('confirmation_popup').querySelector('.confirm-button')
submitButton.textContent = confirmText confirmButton.textContent = confirmText
cancelButton.textContent = cancelText cancelButton.textContent = cancelText
submitButton.onclick = () => { if (danger)
confirmButton.classList.add('button--danger')
else
confirmButton.classList.remove('button--danger')
confirmButton.onclick = () => {
closePopup() closePopup()
resolve(true); resolve(true);
} }
@ -823,7 +822,6 @@
//Function for displaying toast notifications. pass in error for mode param if you want to show an error. //Function for displaying toast notifications. pass in error for mode param if you want to show an error.
function notify(message, mode, options = {}) { function notify(message, mode, options = {}) {
const { pinned = false, sound = false } = options
let icon let icon
switch (mode) { switch (mode) {
case 'success': case 'success':
@ -831,12 +829,13 @@
break; break;
case 'error': case 'error':
icon = `<svg class="icon icon--error" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-7v2h2v-2h-2zm0-8v6h2V7h-2z"/></svg>` icon = `<svg class="icon icon--error" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-7v2h2v-2h-2zm0-8v6h2V7h-2z"/></svg>`
options.pinned = true
break; break;
} }
getRef("notification_drawer").push(message, { pinned, icon });
if (mode === 'error') { if (mode === 'error') {
console.error(message) console.error(message)
} }
return getRef("notification_drawer").push(message, { icon, ...options });
} }
function getFormattedTime(time, format) { function getFormattedTime(time, format) {
@ -883,9 +882,38 @@
} }
}) })
} }
// detect browser version
function detectBrowser() {
let ua = navigator.userAgent,
tem,
M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
if (/trident/i.test(M[1])) {
tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
return 'IE ' + (tem[1] || '');
}
if (M[1] === 'Chrome') {
tem = ua.match(/\b(OPR|Edge)\/(\d+)/);
if (tem != null) return tem.slice(1).join(' ').replace('OPR', 'Opera');
}
M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?'];
if ((tem = ua.match(/version\/(\d+)/i)) != null) M.splice(1, 1, tem[1]);
return M.join(' ');
}
window.addEventListener('hashchange', e => showPage(window.location.hash)) window.addEventListener('hashchange', e => showPage(window.location.hash))
window.addEventListener("load", () => { window.addEventListener("load", () => {
const [browserName, browserVersion] = detectBrowser().split(' ');
const supportedVersions = {
Chrome: 85,
Firefox: 75,
Safari: 13,
}
if (browserName in supportedVersions) {
if (parseInt(browserVersion) < supportedVersions[browserName]) {
notify(`${browserName} ${browserVersion} is not fully supported, some features may not work properly. Please update to ${supportedVersions[browserName]} or higher.`, 'error')
}
} else {
notify('Browser is not fully compatible, some features may not work. for best experience please use Chrome, Edge, Firefox or Safari', 'error')
}
document.body.classList.remove('hide') document.body.classList.remove('hide')
document.querySelectorAll('sm-input[data-flo-id]').forEach(input => input.customValidation = floCrypto.validateAddr) document.querySelectorAll('sm-input[data-flo-id]').forEach(input => input.customValidation = floCrypto.validateAddr)
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)
@ -898,8 +926,8 @@
notify('copied', 'success') notify('copied', 'success')
}) })
document.addEventListener("pointerdown", (e) => { document.addEventListener("pointerdown", (e) => {
if (e.target.closest("button:not([disabled]), sm-button:not([disabled]), .interact")) { if (e.target.closest("button:not([disabled]), .interact")) {
createRipple(e, e.target.closest("button, sm-button, .interact")); createRipple(e, e.target.closest("button, .interact"));
} }
}); });
getRef('accent_color_selector').colors = selectedColors getRef('accent_color_selector').colors = selectedColors
@ -1499,20 +1527,19 @@
} }
getRef('getBal_addr').addEventListener('input', debounce(e => { getRef('getBal_addr').addEventListener('input', debounce(e => {
getRef('getBal_btn').disabled = !e.target.isValid if (e.target.isValid) {
if (!e.target.isValid) { checkSenderBalance()
getRef('sender_balance').textContent = ``; } else {
getRef('sender_balance').textContent = `0`;
} }
}, 100)) }, 100))
function checkSenderBalance() { function checkSenderBalance() {
getRef('sender_balance').innerHTML = `<sm-spinner></sm-spinner>`; getRef('sender_balance').innerHTML = `<sm-spinner></sm-spinner>`;
floWebWallet.getBalance(getRef('getBal_addr').value.trim()).then((retrievedBal) => { floWebWallet.getBalance(getRef('getBal_addr').value.trim()).then((retrievedBal) => {
getRef('sender_balance').textContent = `Balance: ${parseFloat(retrievedBal.toFixed(3))} FLO`; getRef('sender_balance').textContent = parseFloat(retrievedBal.toFixed(3));
}).catch((error) => { }).catch((error) => {
console.error(error); console.error(error);
}).finally(() => {
getRef('getBal_btn').disabled = true;
}) })
} }
@ -1658,16 +1685,16 @@
checkFloData() checkFloData()
} }
let preventUnconfirmedUTXO = true // let preventUnconfirmedUTXO = true
getRef('allow_utxo_switch').addEventListener('change', e => { // getRef('allow_utxo_switch').addEventListener('change', e => {
preventUnconfirmedUTXO = !e.target.checked // preventUnconfirmedUTXO = !e.target.checked
localStorage.preventUnconfirmedUTXO = preventUnconfirmedUTXO // localStorage.preventUnconfirmedUTXO = preventUnconfirmedUTXO
}) // })
if (localStorage.getItem('preventUnconfirmedUTXO') !== 'null') { // if (localStorage.getItem('preventUnconfirmedUTXO') !== 'null') {
const getBoolean = (localStorage.preventUnconfirmedUTXO === 'false') // const getBoolean = (localStorage.preventUnconfirmedUTXO === 'false')
preventUnconfirmedUTXO = getBoolean // preventUnconfirmedUTXO = getBoolean
getRef('allow_utxo_switch').checked = getBoolean // getRef('allow_utxo_switch').checked = getBoolean
} // }
const selectedColors = [ const selectedColors = [
'--dark-red', '--dark-red',
@ -9776,7 +9803,7 @@
//send transaction to the blockchain using API : resolves (txid) //send transaction to the blockchain using API : resolves (txid)
sendTransaction: function (sender, receiver, amount, floData, privKey) { sendTransaction: function (sender, receiver, amount, floData, privKey) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
floBlockchainAPI.sendTx(sender, receiver, amount, privKey, floData, preventUnconfirmedUTXO) floBlockchainAPI.sendTx(sender, receiver, amount, privKey, floData)
.then(txid => resolve(txid)) .then(txid => resolve(txid))
.catch(error => reject(error)) .catch(error => reject(error))
}) })