tweb/src/components/sortedUserList.ts

140 lines
4.9 KiB
TypeScript
Raw Permalink Normal View History

/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
2023-03-10 10:08:06 +01:00
import type LazyLoadQueue from './lazyLoadQueue';
import appDialogsManager, {AppDialogsManager, DialogDom, DialogElement, DialogElementSize} from '../lib/appManagers/appDialogsManager';
2022-08-04 08:49:54 +02:00
import {getHeavyAnimationPromise} from '../hooks/useHeavyAnimationCheck';
import isInDOM from '../helpers/dom/isInDOM';
import positionElementByIndex from '../helpers/dom/positionElementByIndex';
import replaceContent from '../helpers/dom/replaceContent';
import {fastRaf} from '../helpers/schedulers';
import SortedList, {SortedElementBase} from '../helpers/sortedList';
import safeAssign from '../helpers/object/safeAssign';
import {AppManagers} from '../lib/appManagers/managers';
import getUserStatusString from './wrappers/getUserStatusString';
2023-03-02 16:51:37 +01:00
import getChatMembersString from './wrappers/getChatMembersString';
2023-03-10 10:08:06 +01:00
import wrapParticipantRank from './wrappers/participantRank';
import getParticipantRank from '../lib/appManagers/utils/chats/getParticipantRank';
import {Middleware, MiddlewareHelper} from '../helpers/middleware';
2023-01-06 20:27:29 +01:00
interface SortedUser extends SortedElementBase<PeerId> {
dom: DialogDom,
dialogElement: DialogElement
2021-09-17 18:50:29 +02:00
}
export default class SortedUserList extends SortedList<SortedUser> {
2021-07-20 18:11:58 +02:00
protected static SORT_INTERVAL = 30e3;
public list: HTMLUListElement;
2023-03-10 10:08:06 +01:00
public ranks: Map<PeerId, ReturnType<typeof getParticipantRank>> = new Map();
2022-08-04 08:49:54 +02:00
protected lazyLoadQueue: LazyLoadQueue;
2022-11-27 14:09:10 +01:00
protected avatarSize: DialogElementSize = 'abitbigger';
2021-07-20 18:11:58 +02:00
protected rippleEnabled = true;
protected autonomous = true;
2021-12-11 17:37:08 +01:00
protected createChatListOptions: Parameters<AppDialogsManager['createChatList']>[0];
protected onListLengthChange: () => void;
protected managers: AppManagers;
2021-07-20 18:11:58 +02:00
constructor(options: Partial<{
lazyLoadQueue: SortedUserList['lazyLoadQueue'],
avatarSize: SortedUserList['avatarSize'],
rippleEnabled: SortedUserList['rippleEnabled'],
2021-12-11 17:37:08 +01:00
createChatListOptions: SortedUserList['createChatListOptions'],
autonomous: SortedUserList['autonomous'],
2022-01-16 03:45:41 +01:00
onListLengthChange: SortedUserList['onListLengthChange'],
getIndex: SortedUserList['getIndex'],
onUpdate: SortedUserList['onUpdate']
2022-04-25 16:54:30 +02:00
}> & {
managers: SortedUserList['managers'],
middleware: Middleware
2022-04-25 16:54:30 +02:00
}) {
2021-09-17 18:50:29 +02:00
super({
2023-03-02 16:51:37 +01:00
getIndex: options.getIndex || ((element) => element.id.isAnyChat() ? 0 : this.managers.appUsersManager.getUserStatusForSort(element.id)),
onDelete: (element) => {
element.dialogElement.remove();
this.onListLengthChange?.();
},
onUpdate: options.onUpdate || (async(element) => {
2023-03-02 16:51:37 +01:00
if(element.id.isAnyChat()) {
2023-12-05 12:58:30 +01:00
const status = await getChatMembersString(element.id.toChatId(), this.managers);
2023-03-02 16:51:37 +01:00
replaceContent(element.dom.lastMessageSpan, status);
} else {
const status = getUserStatusString(await this.managers.appUsersManager.getUser(element.id));
replaceContent(element.dom.lastMessageSpan, status);
}
2022-01-16 03:45:41 +01:00
}),
onSort: (element, idx) => {
const willChangeLength = element.dom.listEl.parentElement !== this.list;
positionElementByIndex(element.dom.listEl, this.list, idx);
if(willChangeLength && this.onListLengthChange) {
this.onListLengthChange();
}
},
2021-09-17 18:50:29 +02:00
onElementCreate: (base) => {
const dialogElement = appDialogsManager.addDialogNew({
peerId: base.id,
2021-09-17 18:50:29 +02:00
container: false,
avatarSize: this.avatarSize,
autonomous: this.autonomous,
2021-09-17 18:50:29 +02:00
meAsSaved: false,
rippleEnabled: this.rippleEnabled,
2023-01-06 20:27:29 +01:00
wrapOptions: {
lazyLoadQueue: this.lazyLoadQueue,
middleware: this.middlewareHelper.get()
},
withStories: true
2021-09-17 18:50:29 +02:00
});
const rank = this.ranks.get(base.id);
if(rank) {
2023-03-10 10:08:06 +01:00
dialogElement.titleRight.replaceChildren(wrapParticipantRank(rank));
}
(base as SortedUser).dom = dialogElement.dom;
(base as SortedUser).dialogElement = dialogElement;
2021-09-17 18:50:29 +02:00
return base as SortedUser;
},
updateElementWith: fastRaf,
updateListWith: async(callback) => {
2023-03-02 16:51:37 +01:00
if(!Array.from(this.elements.values()).some((element) => element.id.isUser())) {
return callback(false);
}
2021-09-17 18:50:29 +02:00
if(!isInDOM(this.list)) {
return callback(false);
}
2022-08-04 08:49:54 +02:00
2021-09-17 18:50:29 +02:00
await getHeavyAnimationPromise();
2022-08-04 08:49:54 +02:00
2021-09-17 18:50:29 +02:00
if(!isInDOM(this.list)) {
return callback(false);
}
callback(true);
},
middleware: options.middleware
2021-09-17 18:50:29 +02:00
});
2021-07-20 18:11:58 +02:00
safeAssign(this, options);
2021-12-11 17:37:08 +01:00
this.list = appDialogsManager.createChatList(this.createChatListOptions);
let timeout: number;
const doTimeout = () => {
timeout = window.setTimeout(() => {
2021-09-17 18:50:29 +02:00
this.updateList((good) => {
if(good) {
doTimeout();
}
});
}, SortedUserList.SORT_INTERVAL);
};
doTimeout();
}
}