Added emoji picker and support for specific emoji styling

This commit is contained in:
sairaj mote 2021-01-08 20:08:45 +05:30
parent 86755a1118
commit 3dd5ca4819
5 changed files with 398 additions and 173 deletions

View File

@ -27,6 +27,10 @@ body {
color: rgba(var(--text-color), 1);
background: rgba(var(--foreground-color), 1);
}
body #scroll_to_bottom {
background: rgba(var(--foreground-color), 1);
box-shadow: 0 0.3rem 0.4rem rgba(0, 0, 0, 0.2);
}
body[data-theme=dark] {
--secondary-color: #FDB956;
@ -35,11 +39,16 @@ body[data-theme=dark] {
--foreground-color: 20, 20, 20;
}
body[data-theme=dark] .initial {
color: rgba(var(--text-color), 1) !important;
box-shadow: 0 0.1rem 0.1rem #00000016, 0 0.1rem 0.3rem #00000040;
}
body[data-theme=dark] .message {
color: rgba(var(--text-color), 1);
}
body[data-theme=dark] #scroll_to_bottom {
background: linear-gradient(rgba(var(--text-color), 0.1), rgba(var(--text-color), 0.1)), rgba(var(--foreground-color), 1);
box-shadow: 0 0.4rem 0.4rem rgba(0, 0, 0, 0.3);
}
p {
line-height: 1.6;
@ -171,9 +180,8 @@ textarea:focus {
}
a:any-link {
text-decoration: none;
word-wrap: break-word;
color: var(--accent-color);
text-transform: capitalize;
font-weight: 500;
}
@ -350,14 +358,13 @@ sm-button[variant=primary] .icon {
width: 100%;
padding: 0 1.5rem;
height: 100%;
align-items: flex-end;
align-items: center;
}
#landing .logo-section {
padding: 1.5rem;
display: flex;
}
#landing .title-font {
text-transform: capitalize;
line-height: 1.2;
font-weight: 700;
font-size: 2.5rem;
@ -370,6 +377,7 @@ sm-button[variant=primary] .icon {
}
#landing .left h4 {
color: rgba(var(--foreground-color), 1);
font-weight: 500;
}
#landing .left sm-button {
margin: 1.5rem 0 2rem 0;
@ -399,9 +407,6 @@ sm-button[variant=primary] .icon {
#sign_in_popup::part(popup-body) {
padding: 0;
}
#sign_in_popup #sign_in .left {
background-size: 60%;
}
.sign-in-box {
width: 100%;
@ -534,6 +539,7 @@ sm-button[variant=primary] .icon {
}
}
.initial {
position: relative;
justify-content: center;
font-size: 1.2rem;
width: 2.4rem;
@ -544,25 +550,13 @@ sm-button[variant=primary] .icon {
text-transform: uppercase;
}
.chat {
animation: slide-up 0.3s forwards;
}
@keyframes slide-up {
from {
transform: translateY(1rem);
}
to {
transform: none;
}
}
.contact {
position: relative;
display: grid;
gap: 0 1rem;
grid-template-columns: auto 1fr auto;
grid-template-areas: "dp . menu" "dp . menu";
padding: 0.8rem 1rem;
padding: 0.8rem 1.5rem;
align-items: center;
}
.contact:focus {
@ -574,7 +568,7 @@ sm-button[variant=primary] .icon {
}
.contact .name {
font-size: 1rem;
font-weight: 500;
font-weight: 400;
text-transform: capitalize;
}
.contact .address {
@ -604,23 +598,20 @@ sm-button[variant=primary] .icon {
}
.mail-card.unread::before,
.contact.unread::before {
.contact.unread .initial::before {
content: "";
position: absolute;
width: 0.2rem;
height: 100%;
padding: 0.3rem;
border-radius: 1rem;
top: 0;
left: 0;
background: #00C853;
background: var(--accent-color);
}
.mail-card.unread,
.contact.unread {
overflow: hidden;
font-weight: 600;
}
.mail-card.unread h4,
.contact.unread h4 {
.mail-card.unread h4, .mail-card.unread h5, .mail-card.unread p,
.contact.unread h4,
.contact.unread h5,
.contact.unread p {
font-weight: 700;
}
@ -840,6 +831,7 @@ sm-button[variant=primary] .icon {
}
#contacts, #mails {
overflow-y: hidden;
position: relative;
grid-template-rows: max-content 1fr;
height: calc(100vh - 3.5rem);
@ -890,14 +882,41 @@ sm-button[variant=primary] .icon {
}
#chat header .initial {
margin-right: 1rem;
width: 1.6em;
height: 1.6em;
}
#chat header h4 {
font-weight: 500;
opacity: 0.8;
font-size: 0.9rem;
}
#chat header h5 {
opacity: 0.7;
font-weight: 400;
#chat #scroll_to_bottom {
position: fixed;
right: 0;
bottom: 4rem;
width: 2.6rem;
height: 2.6rem;
padding: 0.9rem;
border-radius: 4rem;
z-index: 1;
margin: 1.5rem;
stroke-width: 8;
cursor: pointer;
transform: scale(0);
transition: transform 0.3s;
}
#chat footer #toggle_emoji {
align-self: center;
padding: 0.6rem;
width: 2.6rem;
height: 2.6rem;
border-radius: 2rem;
cursor: pointer;
}
#chat footer #toggle_emoji path {
fill: rgba(var(--text-color), 0.5);
}
#chat footer #toggle_emoji.active path {
fill: var(--accent-color);
}
#chat footer .flex {
align-items: flex-end;
@ -906,6 +925,7 @@ sm-button[variant=primary] .icon {
#chat footer sm-textarea::part(textarea) {
background: rgba(var(--text-color), 0.1);
padding-right: 3rem;
border-radius: 2rem;
}
#chat #send_message_button {
position: absolute;
@ -944,14 +964,23 @@ sm-button[variant=primary] .icon {
#chat .message .message-body {
overflow-wrap: break-word;
word-wrap: break-word;
word-break: break-all;
word-break: break-word;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
white-space: pre-wrap;
box-shadow: 0 1px 0.1rem #00000020;
padding: 0.6em 1em;
line-height: 1.5;
}
#chat .message .message-body a {
color: inherit;
}
#chat .message .time {
white-space: nowrap;
font-size: 0.8em;
opacity: 0.8;
margin-top: 0.3rem;
}
#chat .sent {
margin-left: auto;
@ -1004,13 +1033,57 @@ sm-button[variant=primary] .icon {
}
#chat .unconfirmed {
opacity: 0.7;
transform-origin: left;
animation: slide-up 0.3s forwards;
}
@keyframes slide-up {
from {
transform: translate(-2rem, 2rem) scale(0.8);
}
to {
transform: none;
}
}
#chat_container {
flex: 1;
padding: 0 1rem;
}
#emoji_picker {
display: grid;
background: rgba(var(--text-color), 0.06);
border-radius: 1rem;
margin: 0 1rem;
grid-template-columns: repeat(auto-fill, minmax(3rem, 1fr));
box-shadow: 0 0.2rem 0.8rem rgba(0, 0, 0, 0.3);
padding: 1rem;
overflow-y: auto;
flex-wrap: wrap;
max-height: min(16rem, 30vh);
}
.emoji {
font-size: 1.6rem;
cursor: pointer;
padding: 0.4rem;
border-radius: 0.6rem;
user-select: none;
}
.big-emoji::after {
display: none;
}
.big-emoji .message-body {
background: none !important;
padding: 0 !important;
font-size: 2.6rem;
}
.emoji:hover {
background: rgba(var(--text-color), 0.1);
}
#new_conversation, #no_mails {
height: 100%;
justify-content: center;
@ -1054,12 +1127,12 @@ sm-button[variant=primary] .icon {
display: none;
}
sm-tab-panels {
overflow: hidden auto;
#dm_container {
transition: 0.3s;
}
sm-tab-header {
--accent-color: rgba(var(--text-color), 0.7);
sm-tab-panels {
overflow: hidden auto;
}
#inbox_mail_container,
@ -1174,13 +1247,7 @@ sm-tab-header {
}
#sing_in {
grid-template-rows: 16rem 1fr;
max-height: 90vh;
background: url(sign-in-back.svg) no-repeat center 6rem;
background-size: 50%;
}
#sing_in .left {
border-radius: 0.5rem 0.5rem 0 0;
}
#landing_illustration {
@ -1211,7 +1278,7 @@ sm-tab-header {
}
::-webkit-scrollbar-thumb {
background: rgba(var(--text-color), 0.2);
background: rgba(var(--text-color), 0.3);
}
::-webkit-scrollbar-thumb:hover {
background: rgba(var(--text-color), 0.5);
@ -1250,6 +1317,10 @@ sm-tab-header {
color: var(--accent-color);
}
#sign_in_popup .popup-header {
padding-top: 1.5rem;
}
#main_navbar {
flex-direction: column;
position: relative;
@ -1303,7 +1374,7 @@ sm-tab-header {
}
#chat .message .message-body {
max-width: 50ch;
max-width: 65ch;
}
#chat_page, #mail_page {
@ -1362,7 +1433,7 @@ sm-tab-header {
padding: 0.5rem 1.5rem;
}
#chat #chat_container {
padding: 1rem 1.5rem;
padding: 1rem 5rem;
}
}
@media (hover: hover) {

2
css/main.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -23,6 +23,10 @@ body{
--error-color: red;
color: rgba(var(--text-color), 1);
background: rgba(var(--foreground-color), 1);
#scroll_to_bottom{
background: rgba(var(--foreground-color), 1);
box-shadow: 0 0.3rem 0.4rem rgba(0, 0, 0, 0.2);
}
}
body[data-theme='dark']{
--secondary-color: #FDB956;
@ -30,11 +34,16 @@ body[data-theme='dark']{
--text-color-light: 170, 170, 170;
--foreground-color: 20, 20, 20;
.initial{
color: rgba(var(--text-color), 1) !important;
box-shadow: 0 0.1rem 0.1rem #00000016, 0 0.1rem 0.3rem #00000040;
}
.message{
color: rgba(var(--text-color), 1);
}
#scroll_to_bottom{
background: linear-gradient(rgba(var(--text-color), 0.1), rgba(var(--text-color), 0.1)), rgba(var(--foreground-color), 1);
box-shadow: 0 0.4rem 0.4rem rgba(0, 0, 0, 0.3);
}
}
p{
line-height: 1.6;
@ -141,9 +150,8 @@ textarea{
}
}
a:any-link{
text-decoration: none;
word-wrap: break-word;
color: var(--accent-color);
text-transform: capitalize;
font-weight: 500;
}
.solid-background{
@ -304,13 +312,12 @@ sm-button[variant="primary"]{
width: 100%;
padding: 0 1.5rem;
height: 100%;
align-items: flex-end;
align-items: center;
.logo-section{
padding: 1.5rem;
display: flex;
}
.title-font{
text-transform: capitalize;
line-height: 1.2;
font-weight: 700;
font-size: 2.5rem;
@ -322,6 +329,7 @@ sm-button[variant="primary"]{
z-index: 1;
h4{
color: rgba(var(--foreground-color), 1);
font-weight: 500;
}
sm-button{
margin: 1.5rem 0 2rem 0;
@ -350,11 +358,6 @@ sm-button[variant="primary"]{
&::part(popup-body){
padding: 0;
}
#sign_in{
.left{
background-size: 60%;
}
}
}
.sign-in-box{
width: 100%;
@ -487,6 +490,7 @@ sm-button[variant="primary"]{
}
}
.initial{
position: relative;
justify-content: center;
font-size: 1.2rem;
width: 2.4rem;
@ -496,17 +500,6 @@ sm-button[variant="primary"]{
border-radius: 2rem;
text-transform: uppercase;
}
.chat{
animation: slide-up 0.3s forwards;
}
@keyframes slide-up{
from{
transform: translateY(1rem);
}
to{
transform: none;
}
}
.contact{
position: relative;
display: grid;
@ -514,7 +507,7 @@ sm-button[variant="primary"]{
grid-template-columns: auto 1fr auto;
grid-template-areas: 'dp . menu'
'dp . menu';
padding: 0.8rem 1rem;
padding: 0.8rem 1.5rem;
align-items: center;
&:focus{
background: rgba(var(--text-color), 0.06);
@ -525,7 +518,7 @@ sm-button[variant="primary"]{
}
.name{
font-size: 1rem;
font-weight: 500;
font-weight: 400;
text-transform: capitalize;
}
.address{
@ -553,22 +546,20 @@ sm-button[variant="primary"]{
align-self: center;
}
.mail-card.unread::before,
.contact.unread::before{
.contact.unread .initial::before{
content: '';
position: absolute;
width: 0.2rem;
height: 100%;
padding: 0.3rem;
border-radius: 1rem;
top: 0;
left: 0;
background: #00C853;
background: var(--accent-color);
}
.mail-card.unread,
.contact.unread{
overflow: hidden;
h4{
h4, h5 ,p{
font-weight: 700;
}
font-weight: 600;
}
.mail-card{
position: relative;
@ -780,6 +771,7 @@ sm-button[variant="primary"]{
}
}
#contacts, #mails{
overflow-y: hidden;
position: relative;
grid-template-rows: max-content 1fr;
height: calc(100vh - 3.5rem);
@ -826,17 +818,44 @@ sm-button[variant="primary"]{
}
.initial{
margin-right: 1rem;
width: 1.6em;
height: 1.6em;
}
h4{
font-weight: 500;
opacity: 0.8;
}
h5{
opacity: 0.7;
font-weight: 400;
font-size: 0.9rem;
}
}
#scroll_to_bottom{
position: fixed;
right: 0;
bottom: 4rem;
width: 2.6rem;
height: 2.6rem;
padding: 0.9rem;
border-radius: 4rem;
z-index: 1;
margin: 1.5rem;
stroke-width: 8;
cursor: pointer;
transform: scale(0);
transition: transform 0.3s;
}
footer{
#toggle_emoji{
align-self: center;
padding: 0.6rem;
width: 2.6rem;
height: 2.6rem;
border-radius: 2rem;
cursor: pointer;
path{
fill: rgba(var(--text-color), 0.5);
}
&.active path{
fill: var(--accent-color);
}
}
.flex{
align-items: flex-end;
padding: 1rem;
@ -844,6 +863,7 @@ sm-button[variant="primary"]{
sm-textarea::part(textarea){
background: rgba(var(--text-color), 0.1);
padding-right: 3rem;
border-radius: 2rem;
}
}
#send_message_button{
@ -882,14 +902,23 @@ sm-button[variant="primary"]{
.message-body{
overflow-wrap: break-word;
word-wrap: break-word;
word-break: break-all;
word-break: break-word;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
white-space: pre-wrap;
box-shadow: 0 1px 0.1rem #00000020;
padding: 0.6em 1em;
line-height: 1.5;
a{
color: inherit;
}
}
.time{
white-space: nowrap;
font-size: 0.8em;
opacity: 0.8;
margin-top: 0.3rem;
}
}
.sent{
@ -945,12 +974,54 @@ sm-button[variant="primary"]{
}
.unconfirmed{
opacity: 0.7;
transform-origin: left;
animation: slide-up 0.3s forwards;
}
}
@keyframes slide-up{
from{
transform: translate(-2rem, 2rem) scale(0.8);
}
to{
transform: none;
}
}
#chat_container{
flex: 1;
padding: 0 1rem;
}
#emoji_picker{
display: grid;
background: rgba(var(--text-color), 0.06);
border-radius: 1rem;
margin: 0 1rem;
grid-template-columns: repeat(auto-fill, minmax(3rem, 1fr));
box-shadow: 0 0.2rem 0.8rem rgba(0, 0, 0, 0.3);
padding: 1rem;
overflow-y: auto;
flex-wrap: wrap;
max-height: min(16rem, 30vh);
}
.emoji{
font-size: 1.6rem;
cursor: pointer;
padding: 0.4rem;
border-radius: 0.6rem;
user-select: none;
}
.big-emoji{
&::after{
display: none;
}
.message-body{
background: none !important;
padding: 0 !important;
font-size: 2.6rem;
}
}
.emoji:hover{
background: rgba(var(--text-color), 0.1);
}
#new_conversation, #no_mails{
height: 100%;
justify-content: center;
@ -990,12 +1061,12 @@ sm-button[variant="primary"]{
#dm_container:not(:empty) ~ .empty-state{
display: none;
}
#dm_container{
transition: 0.3s;
}
sm-tab-panels{
overflow: hidden auto;
}
sm-tab-header{
--accent-color: rgba(var(--text-color), 0.7);
}
#inbox_mail_container,
#sent_mail_container
@ -1103,13 +1174,7 @@ sm-tab-header{
height: 100%;
}
#sing_in{
grid-template-rows: 16rem 1fr;
max-height: 90vh;
background: url(sign-in-back.svg) no-repeat center 6rem;
background-size: 50%;
.left{
border-radius: 0.5rem 0.5rem 0 0;
}
}
#landing_illustration{
grid-area: illustration;
@ -1141,7 +1206,7 @@ sm-tab-header{
}
::-webkit-scrollbar-thumb{
background: rgba(var(--text-color), 0.2);
background: rgba(var(--text-color), 0.3);
&:hover{
background: rgba(var(--text-color), 0.5);
}
@ -1175,6 +1240,11 @@ sm-tab-header{
}
}
}
#sign_in_popup{
.popup-header{
padding-top: 1.5rem;
}
}
#main_navbar{
flex-direction: column;
position: relative;
@ -1226,7 +1296,7 @@ sm-tab-header{
#chat{
.message{
.message-body{
max-width: 50ch ;
max-width: 65ch ;
}
}
}
@ -1280,7 +1350,7 @@ sm-tab-header{
padding: 0.5rem 1.5rem;
}
#chat_container{
padding: 1rem 1.5rem;
padding: 1rem 5rem;
}
}
}

View File

@ -48,14 +48,12 @@
<div class="left">
<h4>
FLO Messenger
<div class="line"></div>
</h4>
<h1 class="title-font">
Messages or Emails?<br>
Why Not Both!
Truely Secure,
Private and Reliable.
</h1>
<sm-button variant="primary" onclick="showPopup('sign_in_popup')">Sign In / Sign Up</sm-button>
<p class="light-text">New here? Sign up and get your FLO private key.</p>
<sm-button variant="primary" onclick="showPopup('sign_in_popup')">Sign In / Up</sm-button>
</div>
<div id="landing_illustration" class="right">
<img src="assets/message-background.svg" alt="">
@ -63,16 +61,14 @@
</div>
</div>
<sm-popup id="sign_in_popup">
<header class="popup-header" slot="header">
<svg class="icon" onclick="this.closest('sm-popup').hide()" viewBox="0 0 64 64">
<title>close</title>
<line x1="64" y1="0" x2="0" y2="64" />
<line x1="64" y1="64" x2="0" y2="0" />
</svg>
</header>
<div id="sign_in" class="grid">
<div class="left">
<header class="popup-header" slot="header">
<svg class="icon" onclick="this.closest('sm-popup').hide()" viewBox="0 0 64 64">
<title>close</title>
<line x1="64" y1="0" x2="0" y2="64" />
<line x1="64" y1="64" x2="0" y2="0" />
</svg>
</header>
</div>
<div class="sign-in-box flex direction-column">
<sm-tab-header target="user_entry">
<sm-tab>Sign In</sm-tab>
@ -359,6 +355,11 @@
</svg>
</sm-input>
</header>
<div id="selected_contacts">
<h4>Selected group members</h4>
<div id="selected_contacts_container">
</div>
</div>
<div id="contacts_container" class="flex"></div>
</div>
</div>
@ -368,23 +369,25 @@
<title>Go to main page</title>
<polyline points="48.01 0.35 16.35 32 48.01 63.65"/>
</svg>
<div id="receiver_initial" onclick="goto('chats')" class="initial flex align-center"></div>
<div class="flex rest direction-column">
<h4 id="receiver_name"></h4>
<h5 id="receiver_floID" class="text-overflow"></h5>
</div>
<div id="receiver_initial" class="initial flex align-center"></div>
<h4 id="receiver_name"></h4>
</header>
<h5 id="warn_no_encryption">Messages are not encrypted until receiver replies</h5>
<section id="chat_container" class="flex direction-column">
</section>
</section>
<svg id="scroll_to_bottom" onclick="scrollToBottom()" class="icon" viewBox="0 0 64 64">
<title></title>
<polyline points="63.65 15.99 32 47.66 0.35 15.99"/>
</svg>
<footer class="grid">
<div id="emoji_picker" class="hide-completely"></div>
<div class="flex">
<svg id="toggle_emoji" onclick="toggleEmoji(this)" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path d="M32,0A32,32,0,1,0,64,32,32,32,0,0,0,32,0ZM43.84,17.51a4.92,4.92,0,1,1-4.92,4.92A4.92,4.92,0,0,1,43.84,17.51Zm-23.62-.06a5,5,0,1,1-5,5A5,5,0,0,1,20.22,17.45ZM32,54.42A19.68,19.68,0,0,1,12.31,34.73H51.69A19.68,19.68,0,0,1,32,54.42Z"/></svg>
<sm-textarea id="type_message" placeholder="Type a message" class="rest"></sm-textarea>
<svg xmlns="http://www.w3.org/2000/svg" id="send_message_button" class="icon" viewBox="0 0 64 64">
<path d="M63.34,31,3.07,4.71A2.19,2.19,0,0,0,.18,7.58L8.94,28.29,42.18,32,8.94,35.71.18,56.42a2.19,2.19,0,0,0,2.89,2.87L63.34,33A1.09,1.09,0,0,0,63.34,31Z"/>
</svg>
</div>
<div id="emoji_container"></div>
</footer>
</div>
</section>
@ -920,7 +923,7 @@
await floDapps.clearCredentials()
setTimeout(() => {
onLoadStartUp()
notifications.clearAll()
getRef('notification_drawer').clearAll()
}, 1000);
}
}
@ -976,7 +979,7 @@
getRef('loading_page').classList.remove("hide-completely")
//clear Rendered Elements
let elementsToReset = ['inbox_mail_container', 'sent_mail_container', 'contacts_container', 'chat_container',
'receiver_floID', 'receiver_name', 'mail_contact_list'
'receiver_name', 'mail_contact_list'
]
//, "backup_info"
elementsToReset.forEach(e => clearElement(getRef(e)))
@ -1037,7 +1040,8 @@
activeChatPage = getRef('contacts'),
activeMailPage = getRef('mails'),
activeChat,
activeMail
activeMail,
frag = document.createDocumentFragment()
const mainPage = document.querySelector('main')
@ -1127,10 +1131,10 @@
card.querySelector('.address').textContent = floID
let initial = card.querySelector('.initial')
initial.textContent = name ? name.charAt(0) : 'U'
let randomColor = randomHsl(90, 40)
//cardContainer.setAttribute("text-color", randomColor.primary)
cardContainer.setAttribute("background-color", randomColor.primary)
initial.setAttribute(`style`, `background-color: ${randomColor.primary};`)
let randomColor = randomHsl(70, 30)
cardContainer.setAttribute("text-color", randomColor.primary)
cardContainer.setAttribute("background-color", randomColor.light)
initial.setAttribute(`style`, `background-color: ${randomColor.light}; color: ${randomColor.primary};`)
if(type === 'contact'){
cardContainer.classList.add('contact')
let duplicateCard = card.cloneNode(true);
@ -1157,7 +1161,13 @@
cardContainer.classList.add('unconfirmed')
cardContainer.classList.add(category)
cardContainer.children[0].textContent = message
if(isValidUrl(message))
cardContainer.children[0].innerHTML = `<a href="${message}" target="_blank">${message}</a>`
else{
if(message.length === 2 && isEmoji(message))
cardContainer.classList.add('big-emoji')
cardContainer.children[0].textContent = message
}
cardContainer.children[1].textContent = finalHours
if(currentFloID !== floID){
currentDate = null
@ -1167,15 +1177,34 @@
let dateCard = document.createElement('h5')
dateCard.classList.add('date-card')
dateCard.textContent = new Date().getFullYear() !== year ? `${time.slice(4, 10)} ${year}` : time.slice(4, 10)
getRef('chat_container').appendChild(dateCard)
currentDate = `${time.slice(4, 10)} ${year}`
let frag = document.createDocumentFragment()
frag.append(dateCard, card)
return frag
}
getRef('chat_container').appendChild(card)
else
return card;
},
}
let currentDate, currentFloID
const isValidUrl = (url) => {
try {
new URL(url);
} catch (e) {
return false;
}
return true;
};
const isEmoji = (txt) => {
if(/(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/.test(txt))
return true
else
return false
}
function renderDirectUI(data) {
console.log(data)
renderMessages(data.messages);
@ -1193,6 +1222,13 @@
function renderGroupUI(data){
console.log(data)
}
window.addEventListener('focus', e => {
console.log('focused')
})
window.addEventListener('blur', e => {
console.log('blured')
})
document.addEventListener('keyup', e => {
if(e.target.closest('#send_mail_to')){
@ -1247,6 +1283,16 @@
}
})
let prevScroll
getRef('chat_container').addEventListener('scroll', function() {
if((this.scrollHeight > this.clientHeight) && (prevScroll - this.scrollTop >= 100)){
getRef('scroll_to_bottom').classList.add('no-transformations')
}
else{
getRef('scroll_to_bottom').classList.remove('no-transformations')
}
})
getRef('send_mail_to').addEventListener('input', function() {
getRef('mail_contact_list').classList.remove('hide-completely')
if(this.value.trim !== ''){
@ -1310,29 +1356,48 @@
showPopup('compose_mail_popup')
}
if(e.target.closest('#chat')){
let floID = getRef("receiver_floID").textContent;
messenger.removeMark(floID, "unread");
messenger.removeMark(currentReceiver, "unread");
}
//detect click on chat cards
if (!e.target.closest("sm-menu") && e.target.closest(".contact")){
const contact = e.target.closest(".contact")
if(activeChat === contact && window.innerWidth > 640) return
getRef('chat_page_button').setAttribute('data-notifications', '0')
getRef('chat').classList.remove('hide-completely')
e.target.closest(".contact").classList.remove('unread')
viewConversation(e.target.closest(".contact"))
contact.classList.remove('unread')
viewConversation(contact)
if(activeChat)
activeChat.classList.remove('active')
e.target.closest(".contact").classList.add('active')
activeChat = e.target.closest(".contact")
contact.classList.add('active')
activeChat = contact
if(activeChatPage.id === 'contacts'){
getRef('chat').classList.remove('hide-on-mobile')
getRef('contacts').classList.add('hide-on-mobile')
activeChatPage = getRef('chat')
getRef('main_navbar').classList.add('hide-on-mobile')
}
}
}
//Detect emoji clicks
if(e.target.closest('.emoji')){
getRef('type_message').value += e.target.closest('.emoji').textContent
getRef('type_message').focusIn()
}
})
const emojis = ["😀", "😃", "😄", "😁", "😆", "😅", "😂", "🤣", "😊", "😇", "🙂", "🙃", "😉", "😌", "😍", "🥰", "😘", "😗", "😙", "😚", "😋", "😛", "😝", "😜", "🤪", "🤨", "🧐", "🤓", "😎", "🤩", "🥳", "😏", "😒", "😞", "😔", "😟", "😕", "🙁", "☹️", "😣", "😖", "😫", "😩", "🥺", "😢", "😭", "😤", "😠", "😡", "🤬", "🤯", "😳", "🥵", "🥶", "😱", "😨", "😰", "😥", "😓", "🤗", "🤔", "🤭", "🤫", "🤥", "😶", "😐", "😑", "😬", "🙄", "😯", "😦", "😧", "😮", "😲", "🥱", "😴", "🤤", "😪", "😵", "🤐", "🥴", "🤢", "🤮", "🤧", "😷", "🤒", "🤕", "🤑", "🤠", "😈", "👿", "👹", "👺", "🤡", "💩", "👻", "💀", "☠️", "👽", "👾", "🤖", "🎃", "😺", "😸", "😹", "😻", "😼", "😽", "🙀", "😿", "😾"];
let renderedEmojis = ''
emojis.forEach(emoji => {
renderedEmojis += `<span class="emoji">${emoji}</span>`
})
getRef('emoji_picker').innerHTML = renderedEmojis
function toggleEmoji(button){
button.classList.toggle('active')
getRef('emoji_picker').classList.toggle('hide-completely')
}
function copyToClipboard(target, message, parent){
let copyText, copyTarget = target;
if(typeof target === 'string'){
@ -1384,7 +1449,7 @@
getRef('all_contacts').classList.toggle('no-transformations')
}
/*function updateHeight(){
function updateHeight(){
if(window.innerWidth < 640){
getRef('chat').style.height = window.innerHeight + 'px'
getRef('landing_page').style.height = window.innerHeight + 'px'
@ -1394,9 +1459,6 @@
getRef('landing_page').style.height = '100vh'
}
}
window.addEventListener('resize', e => {
requestAnimationFrame(updateHeight)
})*/
function goto(page){
if(page === 'chats'){
@ -1460,7 +1522,7 @@
}
})
getRef('contacts_container').addEventListener('click', function (e) {
getRef('dm_container').addEventListener('click', function (e) {
let floID;
if (e.target.closest(".send-mail-option")){
showPopup('compose_mail_popup')
@ -1567,18 +1629,30 @@
})
function sendMessage() {
let receiver = getRef("receiver_floID").textContent;
let receiver = currentReceiver
let container;
let message = getRef('type_message').value;
getRef('type_message').value = ''
if(message.trim() === '') return
let time = Date.now()
render.messageBubble(receiver, message, time, 'sent', true)
getRef('chat_container').scrollTo({left: 0, top: getRef('chat_container').scrollHeight, behavior: 'smooth'})
const cloneContact = activeChat.cloneNode(true)
activeChat.remove()
activeChat = cloneContact
getRef('dm_container').prepend(cloneContact)
getRef('chat_container').append(render.messageBubble(receiver, message, time, 'sent', true))
scrollToBottom(true)
if(activeChat !== getRef('dm_container').children[0]){
const contact = getRef('dm_container').querySelector(`.chat[flo-id="${activeChat.getAttribute('flo-id')}"]`)
const cloneContact = contact.cloneNode(true)
contact.remove()
activeChat = cloneContact
getRef('dm_container').prepend(cloneContact)
animateTo(getRef('dm_container').children[0], [
{transform: 'translateY(1rem)'},
{transform: 'none'},
],
{
easing: 'ease',
duration: 300
}
)
}
messenger.sendMessage(message, receiver).then(data => {
getRef(`${receiver}_${time}`).classList.remove('unconfirmed')
}).catch(error => notify(error, "error"));
@ -1625,38 +1699,54 @@
data[d].forEach(mark => element.classList.add(mark))
}
}
function scrollToBottom(smooth = false){
getRef('chat_container').scrollTo({top: getRef('chat_container').scrollHeight, behaviour: smooth ? 'smooth': ''})
}
function renderMessages(data, markUnread = true, unconfirmed = false) {
for (let m in data) {
let {floID, message, time, category} = data[m]
render.messageBubble(floID, message, time, category, unconfirmed)
if (markUnread){
const contact = getRef('contacts').querySelector(`.chat[flo-id='${floID}']`)
contact.classList.add("unread");
const cloneContact = contact.cloneNode(true)
contact.remove()
getRef('dm_container').prepend(cloneContact)
frag.append(render.messageBubble(floID, message, time, category, unconfirmed))
if (markUnread && activeChat !== getRef('dm_container').children[0]){
const contact = getRef('dm_container').querySelector(`.chat[flo-id='${floID}']`)
contact.classList.add("unread");
const cloneContact = contact.cloneNode(true)
contact.remove()
getRef('dm_container').prepend(cloneContact)
animateTo(getRef('dm_container').children[0], [
{transform: 'translateY(1rem)'},
{transform: 'none'},
],
{
easing: 'ease',
duration: 300
}
)
}
}
}
getRef('chat_container').scrollTo(0, getRef('chat_container').scrollHeight)
getRef('chat_container').append(frag)
scrollToBottom()
}
let currentReceiver
async function viewConversation(contact) {
getRef('chat_container').innerHTML = ''
let floID = contact.getAttribute("flo-id"),
name = contact.getAttribute('name'),
textColor = contact.getAttribute('text-color'),
backgroundColor = contact.getAttribute('background-color')
let currentConversation = getRef("receiver_floID").textContent;
currentReceiver = floID
getRef("receiver_initial").textContent = floGlobals.contacts[floID] ? floGlobals.contacts[floID].charAt(0) : name.charAt(0) || ' ';
getRef("receiver_initial").setAttribute('style', `color: ${textColor}; background-color: ${backgroundColor};`)
getRef("receiver_name").textContent = floGlobals.contacts[floID] || name || ' ';
getRef("receiver_floID").textContent = floID;
if (floGlobals.pubKeys[floID])
getRef("warn_no_encryption").classList.add("hide-completely");
else
getRef("warn_no_encryption").classList.remove("hide-completely");
renderMessages(await messenger.getChat(floID), false)
getRef('chat_container').scrollTo(0, getRef('chat_container').scrollHeight)
scrollToBottom()
prevScroll = getRef('chat_container').scrollTop
messenger.removeMark(floID, "unread");
}
@ -1799,6 +1889,7 @@
}
const windowSizeObserver = new ResizeObserver(entries => {
updateHeight()
if(entries[0].borderBoxSize[0].inlineSize > 640){
getRef('settings_sidebar').style = ''
getRef('settings_panel').style = ''
@ -8747,7 +8838,6 @@ Bitcoin.Util = {
}
})();
</script>
<script id="floCrypto" version="2.0.0">
/* FLO Crypto Operators*/
const floCrypto = {

View File

@ -662,8 +662,11 @@ customElements.define('sm-textarea',
}
set value(val) {
this.shadowRoot.querySelector('textarea').value = val;
this.fireEvent()
this.checkInput()
this.fireEvent()
}
focusIn() {
this.shadowRoot.querySelector('textarea').focus()
}
fireEvent() {
let event = new Event('input', {
@ -2996,21 +2999,12 @@ customElements.define('sm-menu', class extends HTMLElement {
slot.addEventListener('slotchange', e => {
this.availableOptions = slot.assignedElements()
this.containerDimensions = this.optionList.getBoundingClientRect()
this.menuDimensions = menu.getBoundingClientRect()
});
window.addEventListener('mousedown', e => {
if (!this.contains(e.target) && e.button !== 2) {
this.collapse()
}
})
if (this.hasAttribute('set-context') && this.getAttribute('set-context') === 'true') {
this.parentNode.setAttribute('oncontextmenu', 'return false')
this.parentNode.addEventListener('mouseup', e => {
if (e.button === 2) {
this.expand()
}
})
}
}
})