Browse Source

Hide empty contacts placeholder in main chat list

master
morethanwords 3 years ago
parent
commit
a7b3ea31f6
  1. 4
      src/components/chat/topbar.ts
  2. 23
      src/components/sortedUserList.ts
  3. 72
      src/lib/appManagers/appDialogsManager.ts

4
src/components/chat/topbar.ts

@ -312,7 +312,7 @@ export default class ChatTopbar {
this.appSidebarRight.toggleSidebar(true); this.appSidebarRight.toggleSidebar(true);
} }
}, },
verify: () => this.appPeersManager.isContact(this.peerId) verify: () => this.peerId.isUser() && !this.appPeersManager.isContact(this.peerId)
}, { }, {
icon: 'forward', icon: 'forward',
text: 'ShareContact', text: 'ShareContact',
@ -351,7 +351,7 @@ export default class ChatTopbar {
selfPresence: 'ChatYourSelf' selfPresence: 'ChatYourSelf'
}); });
}, },
verify: () => rootScope.myId !== this.peerId && this.appPeersManager.isContact(this.peerId) verify: () => rootScope.myId !== this.peerId && this.peerId.isUser() && this.appPeersManager.isContact(this.peerId)
}, { }, {
icon: 'lock', icon: 'lock',
text: 'BlockUser', text: 'BlockUser',

23
src/components/sortedUserList.ts

@ -26,28 +26,43 @@ export default class SortedUserList extends SortedList<SortedUser> {
protected lazyLoadQueue: LazyLoadQueueIntersector; protected lazyLoadQueue: LazyLoadQueueIntersector;
protected avatarSize = 48; protected avatarSize = 48;
protected rippleEnabled = true; protected rippleEnabled = true;
protected autonomous = true;
protected new: boolean;
protected onListLengthChange: () => void;
constructor(options: Partial<{ constructor(options: Partial<{
lazyLoadQueue: SortedUserList['lazyLoadQueue'], lazyLoadQueue: SortedUserList['lazyLoadQueue'],
avatarSize: SortedUserList['avatarSize'], avatarSize: SortedUserList['avatarSize'],
rippleEnabled: SortedUserList['rippleEnabled'], rippleEnabled: SortedUserList['rippleEnabled'],
new: boolean new: SortedUserList['new'],
autonomous: SortedUserList['autonomous'],
onListLengthChange: SortedUserList['onListLengthChange']
}> = {}) { }> = {}) {
super({ super({
getIndex: (id) => appUsersManager.getUserStatusForSort(id), getIndex: (id) => appUsersManager.getUserStatusForSort(id),
onDelete: (element) => element.dom.listEl.remove(), onDelete: (element) => {
element.dom.listEl.remove();
this.onListLengthChange && this.onListLengthChange();
},
onUpdate: (element) => { onUpdate: (element) => {
const status = appUsersManager.getUserStatusString(element.id); const status = appUsersManager.getUserStatusString(element.id);
replaceContent(element.dom.lastMessageSpan, status); replaceContent(element.dom.lastMessageSpan, status);
}, },
onSort: (element, idx) => positionElementByIndex(element.dom.listEl, this.list, idx), onSort: (element, idx) => {
const willChangeLength = element.dom.listEl.parentElement !== this.list;
positionElementByIndex(element.dom.listEl, this.list, idx);
if(willChangeLength && this.onListLengthChange) {
this.onListLengthChange();
}
},
onElementCreate: (base) => { onElementCreate: (base) => {
const {dom} = appDialogsManager.addDialogNew({ const {dom} = appDialogsManager.addDialogNew({
dialog: base.id, dialog: base.id,
container: false, container: false,
drawStatus: false, drawStatus: false,
avatarSize: this.avatarSize, avatarSize: this.avatarSize,
autonomous: true, autonomous: this.autonomous,
meAsSaved: false, meAsSaved: false,
rippleEnabled: this.rippleEnabled, rippleEnabled: this.rippleEnabled,
lazyLoadQueue: this.lazyLoadQueue lazyLoadQueue: this.lazyLoadQueue

72
src/lib/appManagers/appDialogsManager.ts

@ -19,7 +19,6 @@ import { IS_SAFARI } from "../../environment/userAgent";
import { logger, LogTypes } from "../logger"; import { logger, LogTypes } from "../logger";
import { RichTextProcessor } from "../richtextprocessor"; import { RichTextProcessor } from "../richtextprocessor";
import rootScope from "../rootScope"; import rootScope from "../rootScope";
import apiUpdatesManager from "./apiUpdatesManager";
import appPeersManager from './appPeersManager'; import appPeersManager from './appPeersManager';
import appImManager from "./appImManager"; import appImManager from "./appImManager";
import appMessagesManager, { Dialog, MyMessage } from "./appMessagesManager"; import appMessagesManager, { Dialog, MyMessage } from "./appMessagesManager";
@ -43,7 +42,7 @@ import replaceContent from "../../helpers/dom/replaceContent";
import ConnectionStatusComponent from "../../components/connectionStatus"; import ConnectionStatusComponent from "../../components/connectionStatus";
import appChatsManager from "./appChatsManager"; import appChatsManager from "./appChatsManager";
import { renderImageFromUrlPromise } from "../../helpers/dom/renderImageFromUrl"; import { renderImageFromUrlPromise } from "../../helpers/dom/renderImageFromUrl";
import { fastRaf, fastRafConventional, fastRafPromise } from "../../helpers/schedulers"; import { fastRafConventional, fastRafPromise } from "../../helpers/schedulers";
import SortedUserList from "../../components/sortedUserList"; import SortedUserList from "../../components/sortedUserList";
import { IS_TOUCH_SUPPORTED } from "../../environment/touchSupport"; import { IS_TOUCH_SUPPORTED } from "../../environment/touchSupport";
import handleTabSwipe from "../../helpers/dom/handleTabSwipe"; import handleTabSwipe from "../../helpers/dom/handleTabSwipe";
@ -78,19 +77,23 @@ interface SortedDialog extends SortedElementBase {
} }
class SortedDialogList extends SortedList<SortedDialog> { class SortedDialogList extends SortedList<SortedDialog> {
constructor(public list: HTMLUListElement, public indexKey: ReturnType<DialogsStorage['getDialogIndexKey']>) { constructor(
public list: HTMLUListElement,
public indexKey: ReturnType<DialogsStorage['getDialogIndexKey']>,
public onListLengthChange?: () => void
) {
super({ super({
getIndex: (id) => appMessagesManager.getDialogOnly(id)[this.indexKey], getIndex: (id) => appMessagesManager.getDialogOnly(id)[this.indexKey],
onDelete: (element) => { onDelete: (element) => {
element.dom.listEl.remove(); element.dom.listEl.remove();
appDialogsManager.onListLengthChange(); this.onListLengthChange && this.onListLengthChange();
}, },
onSort: (element, idx) => { onSort: (element, idx) => {
const willChangeLength = element.dom.listEl.parentElement !== this.list; const willChangeLength = element.dom.listEl.parentElement !== this.list;
positionElementByIndex(element.dom.listEl, this.list, idx); positionElementByIndex(element.dom.listEl, this.list, idx);
if(willChangeLength) { if(willChangeLength) {
appDialogsManager.onListLengthChange(); this.onListLengthChange && this.onListLengthChange();
} }
}, },
onElementCreate: (base, batch) => { onElementCreate: (base, batch) => {
@ -166,7 +169,7 @@ export class AppDialogsManager {
private initedListeners = false; private initedListeners = false;
public onListLengthChange: () => Promise<void>; private onListLengthChange: () => Promise<void>;
private loadedDialogsAtLeastOnce = false; private loadedDialogsAtLeastOnce = false;
constructor() { constructor() {
@ -176,6 +179,8 @@ export class AppDialogsManager {
this.folders.menuScrollContainer = this.folders.menu.parentElement; this.folders.menuScrollContainer = this.folders.menu.parentElement;
this.onListLengthChange = debounce(this._onListLengthChange, 100, false, true);
const bottomPart = document.createElement('div'); const bottomPart = document.createElement('div');
bottomPart.classList.add('connection-status-bottom'); bottomPart.classList.add('connection-status-bottom');
bottomPart.append(this.folders.container); bottomPart.append(this.folders.container);
@ -322,8 +327,6 @@ export class AppDialogsManager {
setTimeout(() => { setTimeout(() => {
lottieLoader.loadLottieWorkers(); lottieLoader.loadLottieWorkers();
}, 200); }, 200);
this.onListLengthChange = debounce(this._onListLengthChange, 100, false, true);
} }
public get chatList() { public get chatList() {
@ -362,6 +365,10 @@ export class AppDialogsManager {
this.setFilterUnreadCount(folder.id); this.setFilterUnreadCount(folder.id);
}); });
rootScope.addEventListener('contacts_update', (userId) => {
this.processContact && this.processContact(userId.toPeerId());
});
rootScope.addEventListener('dialog_flush', ({peerId}) => { rootScope.addEventListener('dialog_flush', ({peerId}) => {
const dialog = appMessagesManager.getDialogOnly(peerId); const dialog = appMessagesManager.getDialogOnly(peerId);
if(dialog) { if(dialog) {
@ -665,7 +672,11 @@ export class AppDialogsManager {
scrollable.onScrolledBottom = this.onChatsScroll; scrollable.onScrolledBottom = this.onChatsScroll;
scrollable.setVirtualContainer(list); scrollable.setVirtualContainer(list);
const sortedDialogList = new SortedDialogList(list, appMessagesManager.dialogsStorage ? appMessagesManager.dialogsStorage.getDialogIndexKey(filterId) : 'index'); const sortedDialogList = new SortedDialogList(
list,
appMessagesManager.dialogsStorage ? appMessagesManager.dialogsStorage.getDialogIndexKey(filterId) : 'index',
this.onListLengthChange
);
this.scrollables[filterId] = scrollable; this.scrollables[filterId] = scrollable;
this.sortedLists[filterId] = sortedDialogList; this.sortedLists[filterId] = sortedDialogList;
@ -970,6 +981,16 @@ export class AppDialogsManager {
part.classList.add('with-placeholder'); part.classList.add('with-placeholder');
} }
private removeContactsPlaceholder() {
const chatList = this.chatList;
const parts = chatList.parentElement.parentElement;
const bottom = chatList.parentElement.nextElementSibling as HTMLElement;
parts.classList.remove('with-contacts');
bottom.innerHTML = '';
this.loadContacts = undefined;
this.processContact = undefined;
}
private _onListLengthChange = () => { private _onListLengthChange = () => {
if(!this.loadedDialogsAtLeastOnce) { if(!this.loadedDialogsAtLeastOnce) {
return; return;
@ -987,10 +1008,7 @@ export class AppDialogsManager {
const hasContacts = !!bottom.childElementCount; const hasContacts = !!bottom.childElementCount;
if(count >= 10) { if(count >= 10) {
if(hasContacts) { if(hasContacts) {
parts.classList.remove('with-contacts'); this.removeContactsPlaceholder();
bottom.innerHTML = '';
this.loadContacts = undefined;
this.processContact = undefined;
} }
return; return;
@ -1007,10 +1025,23 @@ export class AppDialogsManager {
section.container.classList.add('hide'); section.container.classList.add('hide');
appUsersManager.getContactsPeerIds(undefined, undefined, 'online').then(contacts => { appUsersManager.getContactsPeerIds(undefined, undefined, 'online').then(contacts => {
const sortedUserList = new SortedUserList({avatarSize: 42, new: true}); let ready = false;
const onListLengthChange = () => {
if(ready) {
section.container.classList.toggle('hide', !sortedUserList.list.childElementCount);
}
};
const sortedUserList = new SortedUserList({
avatarSize: 42,
new: true,
autonomous: false,
onListLengthChange
});
this.loadContacts = () => { this.loadContacts = () => {
const pageCount = windowSize.windowH / 60 | 0; const pageCount = windowSize.windowH / 60 | 0;
const arr = contacts.splice(0, pageCount).filter(this.verifyUserIdForContacts); const arr = contacts.splice(0, pageCount).filter(this.verifyPeerIdForContacts);
arr.forEach((peerId) => { arr.forEach((peerId) => {
sortedUserList.add(peerId); sortedUserList.add(peerId);
@ -1028,7 +1059,7 @@ export class AppDialogsManager {
return; return;
} }
const good = this.verifyUserIdForContacts(peerId); const good = this.verifyPeerIdForContacts(peerId);
const added = sortedUserList.has(peerId); const added = sortedUserList.has(peerId);
if(!added && good) sortedUserList.add(peerId); if(!added && good) sortedUserList.add(peerId);
else if(added && !good) sortedUserList.delete(peerId); else if(added && !good) sortedUserList.delete(peerId);
@ -1038,15 +1069,16 @@ export class AppDialogsManager {
list.classList.add('chatlist-new'); list.classList.add('chatlist-new');
this.setListClickListener(list); this.setListClickListener(list);
section.content.append(list); section.content.append(list);
section.container.classList.remove('hide');
ready = true;
onListLengthChange();
}); });
bottom.append(section.container); bottom.append(section.container);
}; };
private verifyUserIdForContacts = (peerId: PeerId) => { private verifyPeerIdForContacts = (peerId: PeerId) => {
const dialog = appMessagesManager.getDialogOnly(peerId); return peerId.isContact() && !appMessagesManager.getDialogOnly(peerId);
return !dialog;
}; };
public onChatsRegularScroll = () => { public onChatsRegularScroll = () => {

Loading…
Cancel
Save