Browse Source

Fix 0.5 pixel shift in chat

Fix vertical centering in badges
master
morethanwords 4 years ago
parent
commit
6a813a6275
  1. 6
      src/components/appSelectPeers.ts
  2. 2
      src/components/chat/search.ts
  3. 2
      src/components/dialogsContextMenu.ts
  4. 2
      src/components/sidebarLeft/index.ts
  5. 4
      src/components/sidebarLeft/tabs/includedChats.ts
  6. 2
      src/index.hbs
  7. 50
      src/lib/appManagers/appDialogsManager.ts
  8. 50
      src/scss/partials/_badge.scss
  9. 4
      src/scss/partials/_chat.scss
  10. 3
      src/scss/partials/_chatTopbar.scss
  11. 67
      src/scss/partials/_chatlist.scss
  12. 4
      src/scss/partials/_leftSidebar.scss
  13. 43
      src/scss/style.scss

6
src/components/appSelectPeers.ts

@ -100,7 +100,7 @@ export default class AppSelectPeers {
if(!target) return; if(!target) return;
const peerId = target.dataset.key; const peerId = target.dataset.key;
const li = this.chatsContainer.querySelector('[data-peerid="' + peerId + '"]') as HTMLElement; const li = this.chatsContainer.querySelector('[data-peer-id="' + peerId + '"]') as HTMLElement;
if(!li) { if(!li) {
this.remove(+peerId || peerId); this.remove(+peerId || peerId);
} else { } else {
@ -117,13 +117,13 @@ export default class AppSelectPeers {
this.scrollable.setVirtualContainer(this.list); this.scrollable.setVirtualContainer(this.list);
this.chatsContainer.addEventListener('click', (e) => { this.chatsContainer.addEventListener('click', (e) => {
const target = findUpAttribute(e.target, 'data-peerId') as HTMLElement; const target = findUpAttribute(e.target, 'data-peer-id') as HTMLElement;
cancelEvent(e); cancelEvent(e);
if(!target) return; if(!target) return;
if(this.freezed) return; if(this.freezed) return;
let key: any = target.getAttribute('data-peerId'); let key: any = target.dataset.peerId;
key = +key || key; key = +key || key;
if(!this.multiSelect) { if(!this.multiSelect) {

2
src/components/chat/search.ts

@ -128,7 +128,7 @@ export default class ChatSearch {
selectResult = (elem: HTMLElement) => { selectResult = (elem: HTMLElement) => {
if(this.setPeerPromise) return this.setPeerPromise; if(this.setPeerPromise) return this.setPeerPromise;
const peerId = +elem.getAttribute('data-peerId'); const peerId = +elem.dataset.peerId;
const lastMsgId = +elem.dataset.mid || undefined; const lastMsgId = +elem.dataset.mid || undefined;
const index = whichChild(elem); const index = whichChild(elem);

2
src/components/dialogsContextMenu.ts

@ -139,7 +139,7 @@ export default class DialogsContextMenu {
this.filterId = appDialogsManager.filterId; this.filterId = appDialogsManager.filterId;
this.selectedId = +li.getAttribute('data-peerId'); this.selectedId = +li.dataset.peerId;
this.dialog = appMessagesManager.getDialogByPeerId(this.selectedId)[0]; this.dialog = appMessagesManager.getDialogByPeerId(this.selectedId)[0];
this.buttons.forEach(button => { this.buttons.forEach(button => {

2
src/components/sidebarLeft/index.ts

@ -367,7 +367,7 @@ export class AppSidebarLeft extends SidebarSlider {
return; return;
} }
const peerId = +target.getAttribute('data-peerId'); const peerId = +target.getAttribute('data-peer-id');
appStateManager.getState().then(state => { appStateManager.getState().then(state => {
const recentSearch = state.recentSearch || []; const recentSearch = state.recentSearch || [];
if(recentSearch[0] != peerId) { if(recentSearch[0] != peerId) {

4
src/components/sidebarLeft/tabs/includedChats.ts

@ -175,7 +175,7 @@ export default class AppIncludedChatsTab extends SliderSuperTab {
let html = ''; let html = '';
for(const key in details) { for(const key in details) {
html += `<button class="folder-category-button btn-primary btn-transparent tgico-${details[key].ico}" data-peerId="${key}">${details[key].text}${this.checkbox()}</button>`; html += `<button class="folder-category-button btn-primary btn-transparent tgico-${details[key].ico}" data-peer-id="${key}">${details[key].text}${this.checkbox()}</button>`;
} }
categories.innerHTML = html; categories.innerHTML = html;
@ -219,7 +219,7 @@ export default class AppIncludedChatsTab extends SliderSuperTab {
for(const flag in filter.pFlags) { for(const flag in filter.pFlags) {
// @ts-ignore // @ts-ignore
if(details.hasOwnProperty(flag) && !!filter.pFlags[flag]) { if(details.hasOwnProperty(flag) && !!filter.pFlags[flag]) {
(categories.querySelector(`[data-peerId="${flag}"]`) as HTMLElement).click(); (categories.querySelector(`[data-peer-id="${flag}"]`) as HTMLElement).click();
} }
} }
} }

2
src/index.hbs

@ -146,7 +146,7 @@
<div class="folders-tabs-scrollable menu-horizontal-scrollable hide"> <div class="folders-tabs-scrollable menu-horizontal-scrollable hide">
<nav class="menu-horizontal" id="folders-tabs"> <nav class="menu-horizontal" id="folders-tabs">
<ul> <ul>
<li class="rp"><span>All<span class="badge badge-20 badge-blue"></span><i></i></span></li> <li class="rp"><span>All<div class="badge badge-20 badge-blue"></div><i></i></span></li>
</ul> </ul>
</nav> </nav>
</div> </div>

50
src/lib/appManagers/appDialogsManager.ts

@ -265,8 +265,8 @@ export class AppDialogsManager {
const dialog = appMessagesManager.getDialogByPeerId(user.id)[0]; const dialog = appMessagesManager.getDialogByPeerId(user.id)[0];
//console.log('updating user:', user, dialog); //console.log('updating user:', user, dialog);
if(dialog && !appUsersManager.isBot(dialog.peerId) && dialog.peerId != rootScope.myId) { if(dialog && !appUsersManager.isBot(dialog.peerId) && dialog.peerId !== rootScope.myId) {
const online = user.status?._ == 'userStatusOnline'; const online = user.status?._ === 'userStatusOnline';
const dom = this.getDialogDom(dialog.peerId); const dom = this.getDialogDom(dialog.peerId);
if(dom) { if(dom) {
@ -348,13 +348,13 @@ export class AppDialogsManager {
//const perf = performance.now(); //const perf = performance.now();
for(const element of this.lastActiveElements) { for(const element of this.lastActiveElements) {
if(+element.getAttribute('data-peerid') !== peerId) { if(+element.dataset.peerId !== peerId) {
element.classList.remove('active'); element.classList.remove('active');
this.lastActiveElements.delete(element); this.lastActiveElements.delete(element);
} }
} }
const elements = Array.from(document.querySelectorAll(`[data-autonomous="0"] li[data-peerid="${peerId}"]`)) as HTMLElement[]; const elements = Array.from(document.querySelectorAll(`[data-autonomous="0"] li[data-peer-id="${peerId}"]`)) as HTMLElement[];
elements.forEach(element => { elements.forEach(element => {
element.classList.add('active'); element.classList.add('active');
this.lastActiveElements.add(element); this.lastActiveElements.add(element);
@ -367,7 +367,7 @@ export class AppDialogsManager {
if(!this.filtersRendered[filter.id]) { if(!this.filtersRendered[filter.id]) {
this.addFilter(filter); this.addFilter(filter);
return; return;
} else if(filter.id == this.filterId) { // это нет тут смысла вызывать, так как будет dialogs_multiupdate } else if(filter.id === this.filterId) { // это нет тут смысла вызывать, так как будет dialogs_multiupdate
//this.validateForFilter(); //this.validateForFilter();
const folder = appMessagesManager.dialogsStorage.getFolder(filter.id); const folder = appMessagesManager.dialogsStorage.getFolder(filter.id);
this.validateForFilter(); this.validateForFilter();
@ -442,7 +442,7 @@ export class AppDialogsManager {
id = +tabContent.dataset.filterId || 0; id = +tabContent.dataset.filterId || 0;
if(this.filterId == id) return; if(this.filterId === id) return;
this.chatLists[id].innerHTML = ''; this.chatLists[id].innerHTML = '';
this.scroll.setVirtualContainer(this.chatLists[id]); this.scroll.setVirtualContainer(this.chatLists[id]);
@ -492,9 +492,9 @@ export class AppDialogsManager {
get topOffsetIndex() { get topOffsetIndex() {
if(!this.scroll.loadedAll['top']) { if(!this.scroll.loadedAll['top']) {
const element = this.chatList.firstElementChild; const element = this.chatList.firstElementChild as HTMLElement;
if(element) { if(element) {
const peerId = +element.getAttribute('data-peerId'); const peerId = +element.dataset.peerId;
const dialog = appMessagesManager.getDialogByPeerId(peerId)[0]; const dialog = appMessagesManager.getDialogByPeerId(peerId)[0];
return dialog.index; return dialog.index;
} }
@ -584,7 +584,7 @@ export class AppDialogsManager {
const span = document.createElement('span'); const span = document.createElement('span');
const titleSpan = document.createElement('span'); const titleSpan = document.createElement('span');
titleSpan.innerHTML = RichTextProcessor.wrapEmojiText(filter.title); titleSpan.innerHTML = RichTextProcessor.wrapEmojiText(filter.title);
const unreadSpan = document.createElement('span'); const unreadSpan = document.createElement('div');
unreadSpan.classList.add('badge', 'badge-20', 'badge-blue'); unreadSpan.classList.add('badge', 'badge-20', 'badge-blue');
const i = document.createElement('i'); const i = document.createElement('i');
span.append(titleSpan, unreadSpan, i); span.append(titleSpan, unreadSpan, i);
@ -643,18 +643,18 @@ export class AppDialogsManager {
let offsetIndex = 0; let offsetIndex = 0;
if(side == 'top') { if(side == 'top') {
const element = this.chatList.firstElementChild; const element = this.chatList.firstElementChild as HTMLElement;
if(element) { if(element) {
const peerId = +element.getAttribute('data-peerId'); const peerId = +element.dataset.peerId;
const index = storage.findIndex(dialog => dialog.peerId == peerId); const index = storage.findIndex(dialog => dialog.peerId == peerId);
const needIndex = Math.max(0, index - loadCount); const needIndex = Math.max(0, index - loadCount);
loadCount = index - needIndex; loadCount = index - needIndex;
offsetIndex = storage[needIndex].index + 1; offsetIndex = storage[needIndex].index + 1;
} }
} else { } else {
const element = this.chatList.lastElementChild; const element = this.chatList.lastElementChild as HTMLElement;
if(element) { if(element) {
const peerId = +element.getAttribute('data-peerId'); const peerId = +element.dataset.peerId;
const dialog = storage.find(dialog => dialog.peerId == peerId); const dialog = storage.find(dialog => dialog.peerId == peerId);
offsetIndex = dialog.index; offsetIndex = dialog.index;
} }
@ -786,7 +786,7 @@ export class AppDialogsManager {
sliced.forEach(el => { sliced.forEach(el => {
el.remove(); el.remove();
const peerId = +el.getAttribute('data-peerId'); const peerId = +el.dataset.peerId;
delete this.doms[peerId]; delete this.doms[peerId];
}); });
@ -848,7 +848,7 @@ export class AppDialogsManager {
if(elem) { if(elem) {
if(onFound) onFound(); if(onFound) onFound();
let peerId = +elem.getAttribute('data-peerId'); let peerId = +elem.dataset.peerId;
let lastMsgId = +elem.dataset.mid || undefined; let lastMsgId = +elem.dataset.mid || undefined;
appImManager.setPeer(peerId, lastMsgId); appImManager.setPeer(peerId, lastMsgId);
@ -861,7 +861,7 @@ export class AppDialogsManager {
list.addEventListener('dblclick', (e) => { list.addEventListener('dblclick', (e) => {
const li = findUpTag(e.target, 'LI'); const li = findUpTag(e.target, 'LI');
if(li) { if(li) {
const peerId = +li.getAttribute('data-peerId'); const peerId = +li.dataset.peerId;
this.log('debug dialog:', appMessagesManager.getDialogByPeerId(peerId)); this.log('debug dialog:', appMessagesManager.getDialogByPeerId(peerId));
} }
}); });
@ -879,16 +879,16 @@ export class AppDialogsManager {
this.reorderDialogsTimeout = 0; this.reorderDialogsTimeout = 0;
let offset = 0; let offset = 0;
if(this.topOffsetIndex) { if(this.topOffsetIndex) {
const element = this.chatList.firstElementChild; const element = this.chatList.firstElementChild as HTMLElement;
if(element) { if(element) {
const peerId = +element.getAttribute('data-peerId'); const peerId = +element.dataset.peerId;
const firstDialog = appMessagesManager.getDialogByPeerId(peerId); const firstDialog = appMessagesManager.getDialogByPeerId(peerId);
offset = firstDialog[1]; offset = firstDialog[1];
} }
} }
const dialogs = appMessagesManager.dialogsStorage.getFolder(this.filterId); const dialogs = appMessagesManager.dialogsStorage.getFolder(this.filterId);
const currentOrder = (Array.from(this.chatList.children) as HTMLElement[]).map(el => +el.getAttribute('data-peerId')); const currentOrder = (Array.from(this.chatList.children) as HTMLElement[]).map(el => +el.dataset.peerId);
dialogs.forEach((dialog, index) => { dialogs.forEach((dialog, index) => {
const dom = this.getDialogDom(dialog.peerId); const dom = this.getDialogDom(dialog.peerId);
@ -936,7 +936,7 @@ export class AppDialogsManager {
lastMessage = appMessagesManager.getMessageByPeer(dialog.peerId, dialog.top_message); lastMessage = appMessagesManager.getMessageByPeer(dialog.peerId, dialog.top_message);
} }
if(lastMessage._ == 'messageEmpty' || (lastMessage._ == 'messageService' && !lastMessage.rReply)) { if(lastMessage._ === 'messageEmpty' || (lastMessage._ === 'messageService' && !lastMessage.rReply)) {
dom.lastMessageSpan.innerHTML = ''; dom.lastMessageSpan.innerHTML = '';
dom.lastTimeSpan.innerHTML = ''; dom.lastTimeSpan.innerHTML = '';
delete dom.listEl.dataset.mid; delete dom.listEl.dataset.mid;
@ -1071,7 +1071,7 @@ export class AppDialogsManager {
} else dom.statusSpan.classList.remove('tgico-check', 'tgico-checks'); } else dom.statusSpan.classList.remove('tgico-check', 'tgico-checks');
dom.unreadMessagesSpan.innerText = ''; dom.unreadMessagesSpan.innerText = '';
dom.unreadMessagesSpan.classList.remove('tgico-pinnedchat'); dom.unreadMessagesSpan.classList.remove('tgico-pinnedchat', 'tgico');
const filter = appMessagesManager.filtersStorage.filters[this.filterId]; const filter = appMessagesManager.filtersStorage.filters[this.filterId];
let isPinned: boolean; let isPinned: boolean;
@ -1088,7 +1088,7 @@ export class AppDialogsManager {
} else { } else {
dom.unreadMessagesSpan.classList.remove('unread'); dom.unreadMessagesSpan.classList.remove('unread');
if(isPinned) { if(isPinned) {
dom.unreadMessagesSpan.classList.add('tgico-pinnedchat'); dom.unreadMessagesSpan.classList.add('tgico-pinnedchat', 'tgico');
} }
} }
} }
@ -1222,7 +1222,7 @@ export class AppDialogsManager {
const li = document.createElement('li'); const li = document.createElement('li');
li.append(paddingDiv); li.append(paddingDiv);
li.setAttribute('data-peerId', '' + peerId); li.dataset.peerId = '' + peerId;
const statusSpan = document.createElement('span'); const statusSpan = document.createElement('span');
statusSpan.classList.add('message-status'); statusSpan.classList.add('message-status');
@ -1230,8 +1230,8 @@ export class AppDialogsManager {
const lastTimeSpan = document.createElement('span'); const lastTimeSpan = document.createElement('span');
lastTimeSpan.classList.add('message-time'); lastTimeSpan.classList.add('message-time');
const unreadMessagesSpan = document.createElement('span'); const unreadMessagesSpan = document.createElement('div');
unreadMessagesSpan.classList.add('dialog-subtitle-badge'); unreadMessagesSpan.className = 'dialog-subtitle-badge badge badge-24';
const titleP = document.createElement('p'); const titleP = document.createElement('p');
titleP.classList.add('dialog-title'); titleP.classList.add('dialog-title');

50
src/scss/partials/_badge.scss

@ -0,0 +1,50 @@
.badge {
border-radius: .75rem;
font-weight: 500;
color: white;
font-size: .875rem;
transition: background-color .2s ease-in-out;
&:not(.tgico):empty {
display: none;
}
&-20 {
height: 1.25rem;
min-width: 1.25rem;
line-height: 1.25rem !important;
padding: 0 5.75px;
html.is-safari & {
line-height: 22px !important;
}
}
&-24 {
height: 1.5rem;
min-width: 1.5rem;
line-height: 1.5rem !important;
padding: 0 7.75px;
&.tgico {
font-size: 1.5rem;
width: 1.5rem;
}
}
&.tgico {
padding: 0;
}
&-green {
background-color: $color-green;
}
&-blue {
background-color: $color-blue;
}
&-gray {
background-color: #c5c9cc;
}
}

4
src/scss/partials/_chat.scss

@ -462,6 +462,10 @@ $chat-helper-size: 39px;
} }
} }
@include respond-to(not-handhelds) {
border-left: 1px solid #DADCE0;
}
@include respond-to(floating-left-sidebar) { @include respond-to(floating-left-sidebar) {
position: fixed !important; position: fixed !important;
left: 0; left: 0;

3
src/scss/partials/_chatTopbar.scss

@ -27,9 +27,6 @@
} }
@include respond-to(not-handhelds) { @include respond-to(not-handhelds) {
border-left: 1px solid #DADCE0;
border-right: 1px solid #DADCE0;
.menu-search { .menu-search {
display: none; display: none;
} }

67
src/scss/partials/_chatlist.scss

@ -1,12 +1,6 @@
.chatlist-container { .chatlist-container {
position: relative; position: relative;
/* .scrollable {
html.is-mac & {
overflow-y: scroll;
}
} */
.search-group-recent.search-group { .search-group-recent.search-group {
@include respond-to(handhelds) { @include respond-to(handhelds) {
padding: 2px 0 0; padding: 2px 0 0;
@ -15,27 +9,16 @@
ul { ul {
margin: 0; margin: 0;
//padding: 0 .5rem;
/* display: grid;
grid-auto-columns: 1fr; */
display: flex; display: flex;
flex-direction: column; flex-direction: column;
/* grid-gap: 4px; */
width: 100%; width: 100%;
user-select: none; user-select: none;
-webkit-user-select: none; /* disable selection/Copy of UIWebView */ -webkit-user-select: none; /* disable selection/Copy of UIWebView */
-webkit-touch-callout: none; /* disable the IOS popup when long-press on a link */ -webkit-touch-callout: none; /* disable the IOS popup when long-press on a link */
/* html.is-mac & {
transform: translateZ(0);
} */
} }
li { li {
//padding: 0 0 2px 0;
//padding-bottom: 4px; - DO MAKETA JS3
//overflow: hidden;
background-color: #fff; background-color: #fff;
@include respond-to(handhelds) { @include respond-to(handhelds) {
@ -50,12 +33,12 @@
color: #a3a3a3; color: #a3a3a3;
font-size: 1.125rem; font-size: 1.125rem;
margin-left: .125rem; margin-left: .125rem;
animation: fade-in-opacity .2s ease forwards; animation: fade-in-opacity .2s ease-in-out forwards;
} }
} }
&.backwards .user-title:after { &.backwards .user-title:after {
animation: fade-in-backwards-opacity .2s ease forwards; animation: fade-in-backwards-opacity .2s ease-in-out forwards;
} }
} }
} }
@ -64,9 +47,6 @@
height: 72px; height: 72px;
max-height: 72px; max-height: 72px;
border-radius: $border-radius-medium; border-radius: $border-radius-medium;
//align-items: center;
/* display: grid;
grid-template-columns: 64px calc(100% - 64px - 6.5px); */
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
flex-direction: row; flex-direction: row;
@ -104,34 +84,18 @@
} }
} }
.pinned-delimiter {
display: flex;
padding: 8px 0 4px;
span {
margin: 0;
width: 100%;
height: 1px;
background-color: #DADCE0;
}
}
p { p {
margin: 0; margin: 0;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
flex-direction: row; flex-direction: row;
//align-items: center;
align-items: flex-start; align-items: flex-start;
//height: 1.7rem; // hot-fix height: 27px;
height: 27px; // maybe new hot-fix
} }
.dialog { .dialog {
&-title { &-title {
&-details { &-details {
/* font-size: .9rem; */
//font-size: .8rem;
font-size: .75rem; font-size: .75rem;
padding: 1px 0px 0px 0px; padding: 1px 0px 0px 0px;
flex: 0 0 auto; flex: 0 0 auto;
@ -141,13 +105,6 @@
&-subtitle { &-subtitle {
&-badge { &-badge {
font-size: .9rem;
&.tgico-pinnedchat {
width: 24px;
font-size: 1.5rem;
}
&:not(:empty), &.tgico-pinnedchat { &:not(:empty), &.tgico-pinnedchat {
margin-left: .5rem; margin-left: .5rem;
} }
@ -250,28 +207,12 @@
} }
} }
.unread, .tgico-pinnedchat { .dialog-subtitle-badge {
height: 24px;
text-align: center;
line-height: 24px;
color: #fff;
border-radius: 12px;
margin-top: 4px; margin-top: 4px;
margin-right: -3px; margin-right: -3px;
flex: 0 0 auto; flex: 0 0 auto;
} }
.unread {
min-width: 24px;
padding: 0 7.75px; // ! fix initial width due to font-size: .9rem;
font-weight: 500;
transition: .2s background-color;
}
.unread:empty {
visibility: hidden;
}
.unread, li.is-muted.backwards .unread { .unread, li.is-muted.backwards .unread {
background: $color-green; background: $color-green;
} }

4
src/scss/partials/_leftSidebar.scss

@ -3,8 +3,8 @@
flex-direction: column; flex-direction: column;
flex: 1; flex: 1;
min-width: 18rem; min-width: 18rem;
// ! -.5 because of border-left and border-right on whole page // ! -1 because of border-left and border-right on whole page
max-width: calc(#{$large-screen} / 4); max-width: calc(#{$large-screen} / 4 - 1px);
@include respond-to(handhelds) { @include respond-to(handhelds) {
width: 100%; width: 100%;

43
src/scss/style.scss

@ -135,6 +135,7 @@ $chat-padding-handhelds: .5rem;
@import "partials/ico"; @import "partials/ico";
@import "partials/input"; @import "partials/input";
@import "partials/button"; @import "partials/button";
@import "partials/badge";
@import "partials/checkbox"; @import "partials/checkbox";
@import "partials/chatlist"; @import "partials/chatlist";
@import "partials/chat"; @import "partials/chat";
@ -1068,48 +1069,6 @@ middle-ellipsis-element {
} }
} }
.badge {
border-radius: .75rem;
font-weight: 500;
color: white;
font-size: .9rem; // ! this will fix vertical center
transition: background-color .2s ease-in-out;
&:empty {
display: none;
}
&-20 {
height: 1.25rem;
min-width: 1.25rem;
line-height: 1.25rem !important;
padding: 0 5.75px;
html.is-safari & {
line-height: 22px !important;
}
}
&-24 {
height: 1.5rem;
min-width: 1.5rem;
line-height: 1.5rem !important;
padding: 0 7.75px;
}
&-green {
background-color: $color-green;
}
&-blue {
background-color: $color-blue;
}
&-gray {
background-color: #c5c9cc;
}
}
.row { .row {
min-height: 3.375rem; min-height: 3.375rem;
margin-top: .5rem; margin-top: .5rem;

Loading…
Cancel
Save