- Fixed same FLO contacts showing different color initials
- Fixed issue where user couldn't send message to newly added contact
- chat scrolling perfomance improvements
This commit is contained in:
sairaj mote 2021-01-17 03:16:45 +05:30
parent 3c268f0791
commit 332dfe16ad
5 changed files with 201 additions and 136 deletions

View File

@ -9,7 +9,7 @@
:root { :root {
scroll-behavior: smooth; scroll-behavior: smooth;
font-size: clamp(16px, 1.2vmax, 48px); font-size: clamp(1rem, 1.2vmax, 3rem);
} }
html, body { html, body {
@ -17,7 +17,7 @@ html, body {
} }
body { body {
--accent-color:#d60739; --accent-color:#5b00d3;
--secondary-color: #ffac2e; --secondary-color: #ffac2e;
--text-color: 17, 17, 17; --text-color: 17, 17, 17;
--text-color-light: 100, 100, 100; --text-color-light: 100, 100, 100;
@ -33,7 +33,7 @@ body #scroll_to_bottom {
} }
body[data-theme=dark] { body[data-theme=dark] {
--accent-color: rgb(214 7 57); --accent-color:#923eff;
--secondary-color: #d60739; --secondary-color: #d60739;
--text-color: 240, 240, 240; --text-color: 240, 240, 240;
--text-color-light: 170, 170, 170; --text-color-light: 170, 170, 170;
@ -562,7 +562,7 @@ sm-button[variant=primary] .icon {
gap: 0 1rem; gap: 0 1rem;
padding: 0.8rem 1.5rem; padding: 0.8rem 1.5rem;
align-items: center; align-items: center;
min-height: max-content; flex-shrink: 0;
} }
.contact.chat { .contact.chat {
grid-template-columns: auto 1fr auto; grid-template-columns: auto 1fr auto;
@ -647,10 +647,6 @@ sm-button[variant=primary] .icon {
color: rgba(var(--text-color), 0.8); color: rgba(var(--text-color), 0.8);
margin: 1rem 0; margin: 1rem 0;
justify-self: center; justify-self: center;
align-self: flex-start;
}
.date-card {
align-self: center; align-self: center;
} }
@ -665,6 +661,10 @@ sm-button[variant=primary] .icon {
background: var(--accent-color); background: var(--accent-color);
} }
.mail-card.unread .time,
.contact.unread .time {
color: var(--accent-color);
}
.mail-card.unread h4, .mail-card.unread h5, .mail-card.unread p, .mail-card.unread h4, .mail-card.unread h5, .mail-card.unread p,
.contact.unread h4, .contact.unread h4,
.contact.unread h5, .contact.unread h5,
@ -867,17 +867,18 @@ sm-button[variant=primary] .icon {
bottom: 0; bottom: 0;
left: 0; left: 0;
right: 0; right: 0;
height: 100%;
width: 100%;
z-index: 1; z-index: 1;
padding-bottom: 1.5rem; padding-bottom: 1.5rem;
background: rgba(var(--foreground-color), 1); background: rgba(var(--foreground-color), 1);
transition: transform 0.3s; transition: transform 0.3s;
transform: translateX(-100%); transform: translateX(-110%);
} }
#contacts #all_contacts .header { #contacts #all_contacts .header {
padding-bottom: 1rem; padding-bottom: 1rem;
} }
#contacts #contacts_container {
height: calc(100vh - 7.3rem);
}
#selected_contacts { #selected_contacts {
padding: 1.5rem; padding: 1.5rem;
@ -891,6 +892,12 @@ sm-button[variant=primary] .icon {
margin-bottom: 0; margin-bottom: 0;
} }
#selected_contacts_container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(6rem, 1fr));
gap: 1rem;
}
#contacts, #mails { #contacts, #mails {
position: relative; position: relative;
grid-template-rows: max-content 1fr; grid-template-rows: max-content 1fr;
@ -909,6 +916,17 @@ sm-button[variant=primary] .icon {
#contacts .header sm-tab::part(tab), #mails .header sm-tab::part(tab), #settings_page .header sm-tab::part(tab) { #contacts .header sm-tab::part(tab), #mails .header sm-tab::part(tab), #settings_page .header sm-tab::part(tab) {
padding: 0.8rem 1rem; padding: 0.8rem 1rem;
} }
#contacts .header .expanding-search, #mails .header .expanding-search, #settings_page .header .expanding-search {
position: absolute;
width: 100%;
padding: 0.7rem 1.5rem;
background: linear-gradient(rgba(var(--text-color), 0.06), rgba(var(--text-color), 0.06)), rgba(var(--foreground-color), 1);
clip-path: circle(0% at calc(100% - 4rem) center);
transition: clip-path 0.3s;
}
#contacts .header .expanding-search.expand, #mails .header .expanding-search.expand, #settings_page .header .expanding-search.expand {
clip-path: circle(100%);
}
#contacts .header sm-input, #mails .header sm-input, #settings_page .header sm-input { #contacts .header sm-input, #mails .header sm-input, #settings_page .header sm-input {
margin: 0; margin: 0;
width: 100%; width: 100%;
@ -920,7 +938,7 @@ sm-button[variant=primary] .icon {
} }
#contacts .header sm-input::part(input), #mails .header sm-input::part(input), #settings_page .header sm-input::part(input) { #contacts .header sm-input::part(input), #mails .header sm-input::part(input), #settings_page .header sm-input::part(input) {
border-radius: 3rem; border-radius: 3rem;
padding: 0.5rem 1rem; padding: 0.3rem 0.8rem;
} }
#contacts .header h4, #mails .header h4, #settings_page .header h4 { #contacts .header h4, #mails .header h4, #settings_page .header h4 {
text-transform: capitalize; text-transform: capitalize;
@ -1234,14 +1252,6 @@ sm-button[variant=primary] .icon {
overflow-y: auto; overflow-y: auto;
} }
#dm_container,
#contacts_container,
#inbox_mail_container,
#sent_mail_container {
height: auto;
min-height: 100%;
}
#dm_container:empty { #dm_container:empty {
display: none; display: none;
} }

2
css/main.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -8,13 +8,13 @@
} }
:root{ :root{
scroll-behavior: smooth; scroll-behavior: smooth;
font-size: clamp(16px, 1.2vmax, 48px); font-size: clamp(1rem, 1.2vmax, 3rem);
} }
html, body{ html, body{
height: 100%; height: 100%;
} }
body{ body{
--accent-color:#d60739; --accent-color:#5b00d3;
--secondary-color: #ffac2e; --secondary-color: #ffac2e;
--text-color: 17, 17, 17; --text-color: 17, 17, 17;
--text-color-light: 100, 100, 100; --text-color-light: 100, 100, 100;
@ -29,7 +29,7 @@ body{
} }
} }
body[data-theme='dark']{ body[data-theme='dark']{
--accent-color: rgb(214 7 57); --accent-color:#923eff;
--secondary-color: #d60739; --secondary-color: #d60739;
--text-color: 240, 240, 240; --text-color: 240, 240, 240;
--text-color-light: 170, 170, 170; --text-color-light: 170, 170, 170;
@ -511,7 +511,7 @@ sm-button[variant="primary"]{
gap: 0 1rem; gap: 0 1rem;
padding: 0.8rem 1.5rem; padding: 0.8rem 1.5rem;
align-items: center; align-items: center;
min-height: max-content; flex-shrink: 0;
&.chat{ &.chat{
grid-template-columns: auto 1fr auto; grid-template-columns: auto 1fr auto;
grid-template-areas: 'dp . menu' grid-template-areas: 'dp . menu'
@ -599,9 +599,6 @@ sm-button[variant="primary"]{
color: rgba(var(--text-color), 0.8); color: rgba(var(--text-color), 0.8);
margin: 1rem 0; margin: 1rem 0;
justify-self: center; justify-self: center;
align-self: flex-start;
}
.date-card{
align-self: center; align-self: center;
} }
.mail-card.unread::before, .mail-card.unread::before,
@ -616,6 +613,9 @@ sm-button[variant="primary"]{
} }
.mail-card.unread, .mail-card.unread,
.contact.unread{ .contact.unread{
.time{
color: var(--accent-color);
}
h4, h5 ,p{ h4, h5 ,p{
font-weight: 700; font-weight: 700;
} }
@ -809,17 +809,18 @@ sm-button[variant="primary"]{
bottom: 0; bottom: 0;
left: 0; left: 0;
right: 0; right: 0;
height: 100%;
width: 100%;
z-index: 1; z-index: 1;
padding-bottom: 1.5rem; padding-bottom: 1.5rem;
background: rgba(var(--foreground-color), 1); background: rgba(var(--foreground-color), 1);
transition: transform 0.3s; transition: transform 0.3s;
transform: translateX(-100%); transform: translateX(-110%);
.header{ .header{
padding-bottom: 1rem; padding-bottom: 1rem;
} }
} }
#contacts_container{
height: calc(100vh - 7.3rem);
}
} }
#selected_contacts{ #selected_contacts{
padding: 1.5rem; padding: 1.5rem;
@ -832,6 +833,11 @@ sm-button[variant="primary"]{
margin-bottom: 0; margin-bottom: 0;
} }
} }
#selected_contacts_container{
display: grid;
grid-template-columns: repeat(auto-fill, minmax(6rem, 1fr));
gap: 1rem;
}
#contacts, #mails{ #contacts, #mails{
position: relative; position: relative;
grid-template-rows: max-content 1fr; grid-template-rows: max-content 1fr;
@ -848,6 +854,17 @@ sm-button[variant="primary"]{
sm-tab::part(tab){ sm-tab::part(tab){
padding: 0.8rem 1rem; padding: 0.8rem 1rem;
} }
.expanding-search{
position: absolute;
width: 100%;
padding: 0.7rem 1.5rem;
background: linear-gradient(rgba(var(--text-color), 0.06), rgba(var(--text-color), 0.06)), rgba(var(--foreground-color), 1);
clip-path: circle(0% at calc(100% - 4rem) center);
transition: clip-path 0.3s;
&.expand{
clip-path: circle(100%);
}
}
sm-input{ sm-input{
margin: 0; margin: 0;
width: 100%; width: 100%;
@ -859,7 +876,7 @@ sm-button[variant="primary"]{
} }
sm-input::part(input){ sm-input::part(input){
border-radius: 3rem; border-radius: 3rem;
padding: 0.5rem 1rem; padding: 0.3rem 0.8rem;
} }
h4{ h4{
text-transform: capitalize; text-transform: capitalize;
@ -1174,13 +1191,6 @@ sm-button[variant="primary"]{
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
} }
#dm_container,
#contacts_container,
#inbox_mail_container,
#sent_mail_container{
height: auto;
min-height: 100%;
}
#dm_container:empty{ #dm_container:empty{
display: none; display: none;
} }

View File

@ -342,21 +342,33 @@
<line y1="53.34" x2="64" y2="53.34"/> <line y1="53.34" x2="64" y2="53.34"/>
</svg> </svg>
<h4>Chat</h4> <h4>Chat</h4>
<sm-menu align-options="right"> <svg class="icon" onclick="toggleSearch('chat_search_field')" viewBox="0 0 64 64">
<sm-menu-option onclick="showPopup('add_contact_popup')">Add a contact</sm-menu-option>
<sm-menu-option onclick="initGroupCreation()">Create new group</sm-menu-option>
</sm-menu>
</div>
<sm-input id="search_chats" type="search" placeholder="Search">
<svg slot="icon" class="icon" viewBox="0 0 64 64">
<title>Search</title> <title>Search</title>
<path d="M25.69,1A24.7,24.7,0,0,1,43.15,43.15,24.7,24.7,0,0,1,8.23,8.22,24.53,24.53,0,0,1,25.69,1m0-1A25.7,25.7,0,1,0,43.85,7.51,25.64,25.64,0,0,0,25.69,0Z"/> <path d="M25.69,1A24.7,24.7,0,0,1,43.15,43.15,24.7,24.7,0,0,1,8.23,8.22,24.53,24.53,0,0,1,25.69,1m0-1A25.7,25.7,0,1,0,43.85,7.51,25.64,25.64,0,0,0,25.69,0Z"/>
<line x1="63.65" y1="63.66" x2="43.36" y2="43.37"/> <line x1="63.65" y1="63.66" x2="43.36" y2="43.37"/>
</svg> </svg>
</sm-input> <sm-menu align-options="right">
<sm-menu-option onclick="initGroupCreation()">Create new group</sm-menu-option>
</sm-menu>
</div>
<div id="chat_search_field" class="expanding-search flex align-center">
<svg xmlns="http://www.w3.org/2000/svg" class="icon back" onclick="toggleSearch('chat_search_field')" viewBox="0 0 64 64">
<title>back-arrow</title>
<line x1="1" y1="32" x2="64" y2="32"/>
<polyline points="29.64 60.97 0.65 32 29.64 3.03"/>
</svg>
<sm-input id="search_chats" type="search" placeholder="Search">
<svg slot="icon" class="icon" viewBox="0 0 64 64">
<title>Search</title>
<path d="M25.69,1A24.7,24.7,0,0,1,43.15,43.15,24.7,24.7,0,0,1,8.23,8.22,24.53,24.53,0,0,1,25.69,1m0-1A25.7,25.7,0,1,0,43.85,7.51,25.64,25.64,0,0,0,25.69,0Z"/>
<line x1="63.65" y1="63.66" x2="43.36" y2="43.37"/>
</svg>
</sm-input>
</div>
<sm-tab-header target="chat_panels"> <sm-tab-header target="chat_panels">
<sm-tab>Direct</sm-tab> <sm-tab>Direct</sm-tab>
<sm-tab>Groups</sm-tab> <sm-tab>Groups</sm-tab>
<sm-tab>Notes</sm-tab>
</sm-tab-header> </sm-tab-header>
</header> </header>
<sm-button variant="primary" id="new_message_button" onclick="showContacts()" class="fab round"> <sm-button variant="primary" id="new_message_button" onclick="showContacts()" class="fab round">
@ -393,6 +405,11 @@
<polyline points="29.64 60.97 0.65 32 29.64 3.03"/> <polyline points="29.64 60.97 0.65 32 29.64 3.03"/>
</svg> </svg>
<h4>Contacts</h4> <h4>Contacts</h4>
<svg class="icon" onclick="toggleSearch('contacts_search_field')" viewBox="0 0 64 64">
<title>Search</title>
<path d="M25.69,1A24.7,24.7,0,0,1,43.15,43.15,24.7,24.7,0,0,1,8.23,8.22,24.53,24.53,0,0,1,25.69,1m0-1A25.7,25.7,0,1,0,43.85,7.51,25.64,25.64,0,0,0,25.69,0Z"/>
<line x1="63.65" y1="63.66" x2="43.36" y2="43.37"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" id="show_contact_popup_button" onclick="showPopup('add_contact_popup')" class="icon justify-right" viewBox="0 0 64 64"> <svg xmlns="http://www.w3.org/2000/svg" id="show_contact_popup_button" onclick="showPopup('add_contact_popup')" class="icon justify-right" viewBox="0 0 64 64">
<title>Add contact</title> <title>Add contact</title>
<path d="M21.7,5.73c6.88,0,11.78,4.64,11.78,12.44S29.58,32.6,22,32.6,10.59,26,10.59,18.25,15.48,5.81,22.36,5.81"/> <path d="M21.7,5.73c6.88,0,11.78,4.64,11.78,12.44S29.58,32.6,22,32.6,10.59,26,10.59,18.25,15.48,5.81,22.36,5.81"/>
@ -401,13 +418,20 @@
<line x1="64" y1="22" x2="44.64" y2="22"/> <line x1="64" y1="22" x2="44.64" y2="22"/>
</svg> </svg>
</div> </div>
<sm-input id="search_contacts" type="search" placeholder="Search Contacts"> <div id="contacts_search_field" class="expanding-search flex align-center">
<svg slot="icon" class="icon" viewBox="0 0 64 64"> <svg xmlns="http://www.w3.org/2000/svg" class="icon back" onclick="toggleSearch('contacts_search_field')" viewBox="0 0 64 64">
<title>Search</title> <title>back-arrow</title>
<path d="M25.69,1A24.7,24.7,0,0,1,43.15,43.15,24.7,24.7,0,0,1,8.23,8.22,24.53,24.53,0,0,1,25.69,1m0-1A25.7,25.7,0,1,0,43.85,7.51,25.64,25.64,0,0,0,25.69,0Z"/> <line x1="1" y1="32" x2="64" y2="32"/>
<line x1="63.65" y1="63.66" x2="43.36" y2="43.37"/> <polyline points="29.64 60.97 0.65 32 29.64 3.03"/>
</svg> </svg>
</sm-input> <sm-input id="search_contacts" type="search" placeholder="Search Contacts">
<svg slot="icon" class="icon" viewBox="0 0 64 64">
<title>Search</title>
<path d="M25.69,1A24.7,24.7,0,0,1,43.15,43.15,24.7,24.7,0,0,1,8.23,8.22,24.53,24.53,0,0,1,25.69,1m0-1A25.7,25.7,0,1,0,43.85,7.51,25.64,25.64,0,0,0,25.69,0Z"/>
<line x1="63.65" y1="63.66" x2="43.36" y2="43.37"/>
</svg>
</sm-input>
</div>
</header> </header>
<div id="selected_contacts" class="hide-completely"> <div id="selected_contacts" class="hide-completely">
<h4>Add group members</h4> <h4>Add group members</h4>
@ -415,7 +439,7 @@
</div> </div>
<sm-button>Create</sm-button> <sm-button>Create</sm-button>
</div> </div>
<div id="contacts_container" class="flex"></div> <div id="contacts_container"></div>
</div> </div>
</div> </div>
<div id="chat" class="flex direction-column hide-on-mobile hide-completely"> <div id="chat" class="flex direction-column hide-on-mobile hide-completely">
@ -763,6 +787,14 @@
return selectedColors[Math.floor(Math.random() * selectedColors.length)] return selectedColors[Math.floor(Math.random() * selectedColors.length)]
} }
const contactsInfo = {}
function contactColor(floID){
if(!contactsInfo[floID]){
contactsInfo[floID] = randomColor()
}
return contactsInfo[floID]
}
function clearElements(array = []) { function clearElements(array = []) {
array.forEach(item => { array.forEach(item => {
getRef(item).innerHTML = `` getRef(item).innerHTML = ``
@ -865,7 +897,7 @@
if(dateDiff === 0) if(dateDiff === 0)
return `${finalHours}`; return `${finalHours}`;
else if(dateDiff === 1) else if(dateDiff === 1)
return `yesterday`; return `Yesterday`;
else if(dateDiff > 1 && dateDiff < 8) else if(dateDiff > 1 && dateDiff < 8)
return currentTime[0]; return currentTime[0];
else else
@ -873,7 +905,6 @@
} }
else else
return ` ${date} ${month}`; return ` ${date} ${month}`;
} }
else else
return `${month} ${year}`; return `${month} ${year}`;
@ -1086,7 +1117,7 @@
//display loading screen //display loading screen
getRef('loading_page').classList.remove("hide-completely") getRef('loading_page').classList.remove("hide-completely")
//clear Rendered Elements //clear Rendered Elements
let elementsToReset = ['inbox_mail_container', 'sent_mail_container', 'contacts_container', 'chat_container', let elementsToReset = ['inbox_mail_container', 'sent_mail_container', 'contacts_container', 'dm_container', 'chat_container',
'receiver_name', 'mail_contact_list' 'receiver_name', 'mail_contact_list'
] ]
//, "backup_info" //, "backup_info"
@ -1211,15 +1242,15 @@
card.querySelector('.mail-content').textContent = content card.querySelector('.mail-content').textContent = content
return card return card
}, },
async contactCard(floID, name, type){ async contactCard(floID, name, type, prepend = false){
let card = getRef('contact_template').content.cloneNode(true), let card = getRef('contact_template').content.cloneNode(true),
cardContainer = card.firstElementChild cardContainer = card.firstElementChild
cardContainer.setAttribute("name", name || 'Unknown') cardContainer.setAttribute("name", name || 'Unknown')
cardContainer.setAttribute("flo-id", floID) cardContainer.setAttribute("flo-id", floID)
cardContainer.querySelector('.name').textContent = name || 'Unknown' cardContainer.querySelector('.name').textContent = name || 'Unknown'
let initial = card.querySelector('.initial') let initial = card.querySelector('.initial')
initial.textContent = name ? name.charAt(0) : 'U' initial.textContent = name ? name.charAt(0) : 'U'
let color = randomColor() let color = contactColor(floID)
//cardContainer.setAttribute("text-color", randomColor.primary) //cardContainer.setAttribute("text-color", randomColor.primary)
cardContainer.setAttribute("background-color", color) cardContainer.setAttribute("background-color", color)
initial.setAttribute(`style`, `background-color: ${color};`) initial.setAttribute(`style`, `background-color: ${color};`)
@ -1230,15 +1261,25 @@
getRef('mail_contact_list').append(duplicateCard); getRef('mail_contact_list').append(duplicateCard);
} }
else{ else{
//render chat card for newly added contact
messenger.getChat(floID).then(chat => { cardContainer.classList.add('chat')
const lastMessage = Object.values(chat).pop() if(prepend){
cardContainer.innerHTML += ` cardContainer.innerHTML += `
<h5 class="last-message"></h5>
<h5 class="time"></h5>`
getRef('dm_container').prepend(card);
getRef('dm_container').children[0].click()
}
else{
messenger.getChat(floID).then(chat => {
const lastMessage = Object.values(chat).pop()
cardContainer.innerHTML += `
<h5 class="last-message">${lastMessage.message}</h5> <h5 class="last-message">${lastMessage.message}</h5>
<h5 class="time">${getFormatedTime(lastMessage.time, true)}</h5>` <h5 class="time">${getFormatedTime(lastMessage.time, true)}</h5>`
}) })
cardContainer.classList.add('chat') .catch(error => console.log(error))
getRef('dm_container').append(card); getRef('dm_container').append(card);
}
} }
}, },
messageBubble(floID, message, timestamp, category, unconfirmed = false){ messageBubble(floID, message, timestamp, category, unconfirmed = false){
@ -1423,7 +1464,7 @@
chatScrollInfo['scrolledUp'] = false chatScrollInfo['scrolledUp'] = false
getRef('scroll_to_bottom').classList.remove('no-transformations') getRef('scroll_to_bottom').classList.remove('no-transformations')
} }
}) }, {passive: true})
getRef('send_mail_to').addEventListener('input', function() { getRef('send_mail_to').addEventListener('input', function() {
getRef('mail_contact_list').classList.remove('hide-completely') getRef('mail_contact_list').classList.remove('hide-completely')
@ -1512,8 +1553,11 @@
recentEmojis.push(clickedEmoji) recentEmojis.push(clickedEmoji)
localStorage.recentEmojis = recentEmojis.join(' ') localStorage.recentEmojis = recentEmojis.join(' ')
renderRecentEmojis() renderRecentEmojis()
if(window.innerWidth > 640) if(window.innerWidth > 640){
getRef('type_message').focusIn() setTimeout(() => {
getRef('type_message').focusIn()
}, 0);
}
} }
}) })
@ -1635,6 +1679,8 @@
button.classList.toggle('active') button.classList.toggle('active')
getRef('emoji_picker').classList.toggle('hide-completely') getRef('emoji_picker').classList.toggle('hide-completely')
getRef('scroll_to_bottom').setAttribute('style', `top: calc(${getRef('chat_container').getBoundingClientRect().height}px - 1.5rem`) getRef('scroll_to_bottom').setAttribute('style', `top: calc(${getRef('chat_container').getBoundingClientRect().height}px - 1.5rem`)
if(!chatScrollInfo.scrolledUp)
scrollToBottom()
} }
function copyToClipboard(element, message, parent = '.copy-row'){ function copyToClipboard(element, message, parent = '.copy-row'){
@ -1860,21 +1906,27 @@
let time = Date.now() let time = Date.now()
getRef('chat_container').append(render.messageBubble(receiver, message, time, 'sent', true)) getRef('chat_container').append(render.messageBubble(receiver, message, time, 'sent', true))
scrollToBottom(true) scrollToBottom(true)
if(activeChat['chatCard'] !== getRef('dm_container').children[0]){ const contact = getRef('dm_container').querySelector(`.chat[flo-id="${receiver}"]`)
const contact = getRef('dm_container').querySelector(`.chat[flo-id="${activeChat.receiver}"]`) if(contact){
const cloneContact = contact.cloneNode(true) if(activeChat['chatCard'] !== getRef('dm_container').children[0]){
contact.remove() const cloneContact = contact.cloneNode(true)
activeChat['chatCard'] = cloneContact contact.remove()
getRef('dm_container').prepend(cloneContact) activeChat['chatCard'] = cloneContact
animateTo(getRef('dm_container').children[0], [ getRef('dm_container').prepend(cloneContact)
{transform: 'translateY(1rem)'}, animateTo(getRef('dm_container').children[0], [
{transform: 'none'}, {transform: 'translateY(1rem)'},
], {transform: 'none'},
{ ],
easing: 'ease', {
duration: 300 easing: 'ease',
} duration: 300
) }
)
}
}
else{
messenger.addChat(receiver)
render.contactCard(receiver, floGlobals.contacts[receiver], 'chat', true)
} }
messenger.sendMessage(message, receiver).then(data => { messenger.sendMessage(message, receiver).then(data => {
getRef(`${receiver}_${time}`).classList.remove('unconfirmed') getRef(`${receiver}_${time}`).classList.remove('unconfirmed')
@ -1945,6 +1997,7 @@
startIndex = (activeChat['allMessages'].length - 20) > 0 ? activeChat['allMessages'].length - 20 : 0 startIndex = (activeChat['allMessages'].length - 20) > 0 ? activeChat['allMessages'].length - 20 : 0
endIndex = activeChat['allMessages'].length endIndex = activeChat['allMessages'].length
messages = activeChat['allMessages'] messages = activeChat['allMessages']
renderedDates.clear()
} }
else if(lazyLoad){ else if(lazyLoad){
messages = activeChat['allMessages'] messages = activeChat['allMessages']
@ -2280,6 +2333,11 @@
} }
}) })
function toggleSearch(target){
getRef(target).classList.toggle('expand')
if(getRef(target).classList.contains('expand'))
getRef(target).children[1].focusIn()
}
</script> </script>
@ -11734,8 +11792,7 @@ Bitcoin.Util = {
chats: {}, chats: {},
groups: {}, groups: {},
gkeys: {}, gkeys: {},
appendix: {}, appendix: {}
contactsInfo: {}
} }
compactIDB.initDB(`${floGlobals.application}_${myFloID}`, obj).then(result => { compactIDB.initDB(`${floGlobals.application}_${myFloID}`, obj).then(result => {
console.info(result) console.info(result)

View File

@ -235,7 +235,7 @@ border: none;
-ms-flex-align: center; -ms-flex-align: center;
align-items: center; align-items: center;
position: relative; position: relative;
gap: 1rem; gap: 0.5rem;
padding: 0.7rem 1rem; padding: 0.7rem 1rem;
border-radius: 0.3rem; border-radius: 0.3rem;
-webkit-transition: opacity 0.3s; -webkit-transition: opacity 0.3s;
@ -666,8 +666,8 @@ customElements.define('sm-textarea',
this.checkInput() this.checkInput()
this.fireEvent() this.fireEvent()
} }
focusIn() { focusIn = () => {
this.shadowRoot.querySelector('textarea').focus() this.textarea.focus()
} }
fireEvent() { fireEvent() {
let event = new Event('input', { let event = new Event('input', {
@ -2047,31 +2047,27 @@ customElements.define('sm-popup', class extends HTMLElement {
} }
handleTouchStart = (e) => { handleTouchStart = (e) => {
this.isPressed = true this.touchStartY = e.changedTouches[0].clientY
this.popupHeader.setPointerCapture(e.pointerId)
this.touchStartY = e.clientY
this.popup.style.transition = 'transform 0.1s' this.popup.style.transition = 'transform 0.1s'
this.touchStartTime = e.timeStamp this.touchStartTime = e.timeStamp
} }
handleTouchMove = (e) => { handleTouchMove = (e) => {
if(!this.isPressed) return e.preventDefault()
if (this.touchStartY < e.clientY) { if (this.touchStartY < e.changedTouches[0].clientY) {
this.offset = e.clientY - this.touchStartY; this.offset = e.changedTouches[0].clientY - this.touchStartY;
this.touchEndAnimataion = window.requestAnimationFrame(() => this.movePopup()) this.touchEndAnimataion = window.requestAnimationFrame(() => this.movePopup())
} }
/*else { /*else {
this.offset = this.touchStartY - e.clientY; this.offset = this.touchStartY - e.changedTouches[0].clientY;
this.popup.style.transform = `translateY(-${this.offset}px)` this.popup.style.transform = `translateY(-${this.offset}px)`
}*/ }*/
} }
handleTouchEnd = (e) => { handleTouchEnd = (e) => {
this.isPressed = false
this.popupHeader.releasePointerCapture(e.pointerId)
this.touchEndTime = e.timeStamp this.touchEndTime = e.timeStamp
cancelAnimationFrame(this.touchEndAnimataion) cancelAnimationFrame(this.touchEndAnimataion)
this.touchEndY = e.clientY this.touchEndY = e.changedTouches[0].clientY
this.popup.style.transition = 'transform 0.3s' this.popup.style.transition = 'transform 0.3s'
if (this.touchEndTime - this.touchStartTime > 200) { if (this.touchEndTime - this.touchStartTime > 200) {
if (this.touchEndY - this.touchStartY > this.threshold) { if (this.touchEndY - this.touchStartY > this.threshold) {
@ -2112,7 +2108,6 @@ customElements.define('sm-popup', class extends HTMLElement {
this.touchEndTime = 0 this.touchEndTime = 0
this.touchEndAnimataion; this.touchEndAnimataion;
this.threshold this.threshold
this.isPressed = false
if (this.hasAttribute('open')) if (this.hasAttribute('open'))
this.show() this.show()
@ -2133,14 +2128,14 @@ customElements.define('sm-popup', class extends HTMLElement {
this.inputFields = this.querySelectorAll('sm-input', 'sm-checkbox', 'textarea', 'sm-textarea', 'radio') this.inputFields = this.querySelectorAll('sm-input', 'sm-checkbox', 'textarea', 'sm-textarea', 'radio')
}) })
this.popupHeader.addEventListener('pointerdown', (e) => {this.handleTouchStart(e)}, {passive: true}) this.popupHeader.addEventListener('touchstart', (e) => {this.handleTouchStart(e)})
this.popupHeader.addEventListener('pointermove', (e) => {this.handleTouchMove(e)}, {passive: true}) this.popupHeader.addEventListener('touchmove', (e) => {this.handleTouchMove(e)})
this.popupHeader.addEventListener('pointerup', (e) => {this.handleTouchEnd(e)}, {passive: true}) this.popupHeader.addEventListener('touchend', (e) => {this.handleTouchEnd(e)})
} }
disconnectedCallback() { disconnectedCallback() {
this.popupHeader.removeEventListener('pointerdown', this.handleTouchStart, {passive: true}) this.popupHeader.removeEventListener('touchstart', this.handleTouchStart)
this.popupHeader.removeEventListener('pointermove', this.handleTouchMove, {passive: true}) this.popupHeader.removeEventListener('touchmove', this.handleTouchMove)
this.popupHeader.removeEventListener('pointerup', this.handleTouchEnd, {passive: true}) this.popupHeader.removeEventListener('touchend', this.handleTouchEnd)
} }
}) })
@ -2607,32 +2602,28 @@ customElements.define('sm-notifications', class extends HTMLElement {
} }
handleTouchStart = (e) => { handleTouchStart = (e) => {
this.isPressed = true
this.notification = e.target.closest('.notification') this.notification = e.target.closest('.notification')
this.notification.setPointerCapture(e.pointerId) this.touchStartX = e.changedTouches[0].clientX
this.touchStartX = e.clientX
this.notification.style.transition = 'initial' this.notification.style.transition = 'initial'
this.touchStartTime = e.timeStamp this.touchStartTime = e.timeStamp
} }
handleTouchMove = (e) => { handleTouchMove = (e) => {
if (!this.isPressed) return; e.preventDefault()
if (this.touchStartX < e.clientX) { if (this.touchStartX < e.changedTouches[0].clientX) {
this.offset = e.clientX - this.touchStartX; this.offset = e.changedTouches[0].clientX - this.touchStartX;
this.touchEndAnimataion = requestAnimationFrame(this.moveNotification) this.touchEndAnimataion = requestAnimationFrame(this.movePopup)
} else { } else {
this.offset = -(this.touchStartX - e.clientX); this.offset = -(this.touchStartX - e.changedTouches[0].clientX);
this.touchEndAnimataion = requestAnimationFrame(this.moveNotification) this.touchEndAnimataion = requestAnimationFrame(this.movePopup)
} }
} }
handleTouchEnd = (e) => { handleTouchEnd = (e) => {
this.isPressed = false
this.notification.releasePointerCapture(e.pointerId)
this.notification.style.transition = 'transform 0.3s, opacity 0.3s' this.notification.style.transition = 'transform 0.3s, opacity 0.3s'
this.touchEndTime = e.timeStamp this.touchEndTime = e.timeStamp
cancelAnimationFrame(this.touchEndAnimataion) cancelAnimationFrame(this.touchEndAnimataion)
this.touchEndX = e.clientX this.touchEndX = e.changedTouches[0].clientX
if (this.touchEndTime - this.touchStartTime > 200) { if (this.touchEndTime - this.touchStartTime > 200) {
if (this.touchEndX - this.touchStartX > this.threshold) { if (this.touchEndX - this.touchStartX > this.threshold) {
this.removeNotification(this.notification) this.removeNotification(this.notification)
@ -2650,7 +2641,7 @@ customElements.define('sm-notifications', class extends HTMLElement {
} }
} }
moveNotification = () => { movePopup = () => {
this.notification.style.transform = `translateX(${this.offset}px)` this.notification.style.transform = `translateX(${this.offset}px)`
} }
@ -2688,22 +2679,22 @@ customElements.define('sm-notifications', class extends HTMLElement {
this.notificationPanel.prepend(notification) this.notificationPanel.prepend(notification)
if (window.innerWidth > 640) { if (window.innerWidth > 640) {
notification.animate([{ notification.animate([{
transform: `translateX(1rem)`, transform: `translateX(1rem)`,
opacity: '0' opacity: '0'
}, },
{ {
transform: 'translateX(0)', transform: 'translateX(0)',
opacity: '1' opacity: '1'
} }
], this.animationOptions).onfinish = () => { ], this.animationOptions).onfinish = () => {
notification.setAttribute('style', `transform: none;`); notification.setAttribute('style', `transform: none;`);
} }
} else { } else {
notification.setAttribute('style', `transform: translateY(0); opacity: 1`) notification.setAttribute('style', `transform: translateY(0); opacity: 1`)
} }
notification.addEventListener('pointerdown', e => { this.handleTouchStart(e) }, { passive: true }) notification.addEventListener('touchstart', this.handleTouchStart)
notification.addEventListener('pointermove', e => { this.handleTouchMove(e) }, {passive: true}) notification.addEventListener('touchmove', this.handleTouchMove)
notification.addEventListener('pointerup', e => { this.handleTouchEnd(e) }, {passive: true}) notification.addEventListener('touchend', this.handleTouchEnd)
} }
removeNotification = (notification, toLeft) => { removeNotification = (notification, toLeft) => {
@ -2750,6 +2741,7 @@ customElements.define('sm-notifications', class extends HTMLElement {
fill: "forwards", fill: "forwards",
easing: "ease" easing: "ease"
} }
this.fontSize = Number(window.getComputedStyle(document.body).getPropertyValue('font-size').match(/\d+/)[0])
this.notification this.notification
this.offset this.offset
this.touchStartX = 0 this.touchStartX = 0
@ -2758,7 +2750,6 @@ customElements.define('sm-notifications', class extends HTMLElement {
this.touchEndTime = 0 this.touchEndTime = 0
this.threshold = this.notificationPanel.getBoundingClientRect().width * 0.3 this.threshold = this.notificationPanel.getBoundingClientRect().width * 0.3
this.touchEndAnimataion; this.touchEndAnimataion;
this.isPressed = false
this.notificationPanel.addEventListener('click', e => { this.notificationPanel.addEventListener('click', e => {
if (e.target.closest('.close'))( if (e.target.closest('.close'))(
@ -2785,18 +2776,15 @@ customElements.define('sm-notifications', class extends HTMLElement {
}) })
}) })
observer.observe(this.notificationPanel, { observer.observe(this.notificationPanel, {
attributes: true,
childList: true, childList: true,
subtree: true subtree: true
}) })
} }
disconnectedCallback() {
notification.removeEventListener('pointerdown', e => { this.handleTouchStart(e) }, { passive: true })
notification.removeEventListener('pointermove', e => { this.handleTouchMove(e) }, {passive: true})
notification.removeEventListener('pointerup', e => { this.handleTouchEnd(e) }, {passive: true})
}
}) })
// sm-menu // sm-menu
const smMenu = document.createElement('template') const smMenu = document.createElement('template')
smMenu.innerHTML = ` smMenu.innerHTML = `