tweb/src/components/chat/topbar.ts

759 lines
27 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import type { AppNotificationsManager } from "../../lib/appManagers/appNotificationsManager";
import type { AppChatsManager, Channel } from "../../lib/appManagers/appChatsManager";
import type { AppMessagesManager } from "../../lib/appManagers/appMessagesManager";
import type { AppPeersManager } from "../../lib/appManagers/appPeersManager";
import type { AppSidebarRight } from "../sidebarRight";
import type { AppProfileManager } from "../../lib/appManagers/appProfileManager";
import type { AppUsersManager } from "../../lib/appManagers/appUsersManager";
import type Chat from "./chat";
import { RIGHT_COLUMN_ACTIVE_CLASSNAME } from "../sidebarRight";
import mediaSizes, { ScreenSize } from "../../helpers/mediaSizes";
import { IS_SAFARI } from "../../environment/userAgent";
import rootScope from "../../lib/rootScope";
import AvatarElement from "../avatar";
import Button from "../button";
import ButtonIcon from "../buttonIcon";
import ButtonMenuToggle from "../buttonMenuToggle";
import ChatAudio from "./audio";
import ChatPinnedMessage from "./pinnedMessage";
import { ButtonMenuItemOptions } from "../buttonMenu";
import ListenerSetter from "../../helpers/listenerSetter";
import appStateManager from "../../lib/appManagers/appStateManager";
import PopupDeleteDialog from "../popups/deleteDialog";
import appNavigationController from "../appNavigationController";
import { LEFT_COLUMN_ACTIVE_CLASSNAME } from "../sidebarLeft";
import PeerTitle from "../peerTitle";
import { i18n } from "../../lib/langPack";
import findUpClassName from "../../helpers/dom/findUpClassName";
import blurActiveElement from "../../helpers/dom/blurActiveElement";
import { cancelEvent } from "../../helpers/dom/cancelEvent";
import { attachClickEvent } from "../../helpers/dom/clickEvent";
import findUpTag from "../../helpers/dom/findUpTag";
import { toast, toastNew } from "../toast";
import replaceContent from "../../helpers/dom/replaceContent";
import { ChatFull } from "../../layer";
import PopupPickUser from "../popups/pickUser";
import PopupPeer from "../popups/peer";
import generateVerifiedIcon from "../generateVerifiedIcon";
import { fastRaf } from "../../helpers/schedulers";
import AppEditContactTab from "../sidebarRight/tabs/editContact";
import appMediaPlaybackController from "../appMediaPlaybackController";
import { NULL_PEER_ID } from "../../lib/mtproto/mtproto_config";
export default class ChatTopbar {
public container: HTMLDivElement;
private btnBack: HTMLButtonElement;
private chatInfo: HTMLDivElement;
private avatarElement: AvatarElement;
private title: HTMLDivElement;
private subtitle: HTMLDivElement;
private chatUtils: HTMLDivElement;
private btnJoin: HTMLButtonElement;
private btnPinned: HTMLButtonElement;
private btnMute: HTMLButtonElement;
private btnSearch: HTMLButtonElement;
private btnMore: HTMLButtonElement;
private chatAudio: ChatAudio;
public pinnedMessage: ChatPinnedMessage;
private setUtilsRAF: number;
public peerId: PeerId;
private wasPeerId: PeerId;
private setPeerStatusInterval: number;
public listenerSetter: ListenerSetter;
private menuButtons: (ButtonMenuItemOptions & {verify: () => boolean})[] = [];
constructor(private chat: Chat,
private appSidebarRight: AppSidebarRight,
private appMessagesManager: AppMessagesManager,
private appPeersManager: AppPeersManager,
private appChatsManager: AppChatsManager,
private appNotificationsManager: AppNotificationsManager,
private appProfileManager: AppProfileManager,
private appUsersManager: AppUsersManager
) {
this.listenerSetter = new ListenerSetter();
}
public construct() {
//this.chat.log.error('Topbar construction');
this.container = document.createElement('div');
this.container.classList.add('sidebar-header', 'topbar');
this.container.dataset.floating = '0';
this.btnBack = ButtonIcon('left sidebar-close-button', {noRipple: true});
// * chat info section
this.chatInfo = document.createElement('div');
this.chatInfo.classList.add('chat-info');
const person = document.createElement('div');
person.classList.add('person');
const content = document.createElement('div');
content.classList.add('content');
const top = document.createElement('div');
top.classList.add('top');
this.title = document.createElement('div');
this.title.classList.add('user-title');
top.append(this.title);
const bottom = document.createElement('div');
bottom.classList.add('bottom');
if(this.subtitle) {
bottom.append(this.subtitle);
}
content.append(top, bottom);
if(this.avatarElement) {
person.append(this.avatarElement);
}
person.append(content);
this.chatInfo.append(person);
// * chat utils section
this.chatUtils = document.createElement('div');
this.chatUtils.classList.add('chat-utils');
this.chatAudio = new ChatAudio(this, this.chat, this.appMessagesManager);
if(this.menuButtons.length) {
this.btnMore = ButtonMenuToggle({listenerSetter: this.listenerSetter}, 'bottom-left', this.menuButtons, (e) => {
cancelEvent(e);
this.menuButtons.forEach(button => {
button.element.classList.toggle('hide', !button.verify());
});
// delete button
this.menuButtons[this.menuButtons.length - 1].element.lastChild.replaceWith(i18n(this.appPeersManager.getDeleteButtonText(this.peerId)));
});
}
this.chatUtils.append(...[
// this.chatAudio ? this.chatAudio.divAndCaption.container : null,
this.pinnedMessage ? this.pinnedMessage.pinnedMessageContainer.divAndCaption.container : null,
this.btnJoin,
this.btnPinned,
this.btnMute,
this.btnSearch,
this.btnMore
].filter(Boolean));
this.container.append(this.btnBack, this.chatInfo, this.chatUtils);
if(this.chatAudio) {
// this.container.append(this.chatAudio.divAndCaption.container, this.chatUtils);
this.container.append(this.chatAudio.divAndCaption.container);
}
// * construction end
// * fix topbar overflow section
this.listenerSetter.add(window)('resize', this.onResize);
this.listenerSetter.add(mediaSizes)('changeScreen', this.onChangeScreen);
attachClickEvent(this.container, (e) => {
const container: HTMLElement = findUpClassName(e.target, 'pinned-container');
blurActiveElement();
if(container) {
cancelEvent(e);
if(findUpClassName(e.target, 'progress-line')) {
return;
}
const mid = +container.dataset.mid;
if(container.classList.contains('pinned-message')) {
//if(!this.pinnedMessage.locked) {
this.pinnedMessage.followPinnedMessage(mid);
//}
} else {
const peerId = container.dataset.peerId.toPeerId();
const searchContext = appMediaPlaybackController.getSearchContext();
this.chat.appImManager.setInnerPeer(
peerId,
mid,
searchContext.isScheduled ? 'scheduled' : (searchContext.threadId ? 'discussion' : undefined),
searchContext.threadId
);
}
} else {
if(mediaSizes.activeScreen === ScreenSize.medium && document.body.classList.contains(LEFT_COLUMN_ACTIVE_CLASSNAME)) {
onBtnBackClick();
} else if(findUpTag(e.target, 'AVATAR-ELEMENT')) {
this.appSidebarRight.toggleSidebar(!document.body.classList.contains(RIGHT_COLUMN_ACTIVE_CLASSNAME));
} else {
this.appSidebarRight.toggleSidebar(true);
}
}
}, {listenerSetter: this.listenerSetter});
const onBtnBackClick = (e?: Event) => {
if(e) {
cancelEvent(e);
}
//const item = appNavigationController.findItemByType('chat');
// * return manually to chat by arrow, since can't get back to
if(mediaSizes.activeScreen === ScreenSize.medium && document.body.classList.contains(LEFT_COLUMN_ACTIVE_CLASSNAME)) {
this.chat.appImManager.setPeer(this.peerId);
} else {
const isFirstChat = this.chat.appImManager.chats.indexOf(this.chat) === 0;
appNavigationController.back(isFirstChat ? 'im' : 'chat');
/* return;
if(mediaSizes.activeScreen === ScreenSize.medium && !appNavigationController.findItemByType('chat')) {
this.chat.appImManager.setPeer(0);
blurActiveElement();
} else {
appNavigationController.back('chat');
} */
}
};
attachClickEvent(this.btnBack, onBtnBackClick, {listenerSetter: this.listenerSetter});
}
public constructUtils() {
this.menuButtons = [{
icon: 'search',
text: 'Search',
onClick: () => {
this.chat.initSearch()
},
verify: () => mediaSizes.isMobile
}, /* {
icon: 'pinlist',
text: 'Pinned Messages',
onClick: () => this.openPinned(false),
verify: () => mediaSizes.isMobile
}, */{
icon: 'mute',
text: 'ChatList.Context.Mute',
onClick: () => {
this.appMessagesManager.mutePeer(this.peerId);
},
verify: () => this.chat.type === 'chat' && rootScope.myId !== this.peerId && !this.appNotificationsManager.isPeerLocalMuted(this.peerId, false)
}, {
icon: 'unmute',
text: 'ChatList.Context.Unmute',
onClick: () => {
this.appMessagesManager.mutePeer(this.peerId);
},
verify: () => this.chat.type === 'chat' && rootScope.myId !== this.peerId && this.appNotificationsManager.isPeerLocalMuted(this.peerId, false)
}, {
icon: 'comments',
text: 'ViewDiscussion',
onClick: () => {
this.appProfileManager.getChannelFull(this.peerId.toChatId()).then(channelFull => {
if(channelFull.linked_chat_id) {
this.chat.appImManager.setInnerPeer(channelFull.linked_chat_id.toPeerId(true));
}
});
},
verify: () => {
const chatFull = this.appProfileManager.chatsFull[this.peerId.toChatId()];
return this.chat.type === 'chat' && this.appPeersManager.isBroadcast(this.peerId) && !!(chatFull as ChatFull.channelFull)?.linked_chat_id;
}
}, {
icon: 'select',
text: 'Chat.Menu.SelectMessages',
onClick: () => {
const selection = this.chat.selection;
selection.toggleSelection(true, true);
appStateManager.getState().then(state => {
if(state.chatContextMenuHintWasShown) {
return;
}
const original = selection.toggleByElement.bind(selection);
selection.toggleByElement = (bubble) => {
appStateManager.pushToState('chatContextMenuHintWasShown', true);
toast(i18n('Chat.Menu.Hint'));
selection.toggleByElement = original;
selection.toggleByElement(bubble);
};
});
},
verify: () => !this.chat.selection.isSelecting && !!Object.keys(this.chat.bubbles.bubbles).length
}, {
icon: 'select',
text: 'Chat.Menu.ClearSelection',
onClick: () => {
this.chat.selection.cancelSelection();
},
verify: () => this.chat.selection.isSelecting
}, {
icon: 'adduser',
text: 'AddContact',
onClick: () => {
if(!this.appSidebarRight.isTabExists(AppEditContactTab)) {
const tab = new AppEditContactTab(this.appSidebarRight);
tab.peerId = this.peerId;
tab.open();
this.appSidebarRight.toggleSidebar(true);
}
},
verify: () => this.appPeersManager.isContact(this.peerId)
}, {
icon: 'forward',
text: 'ShareContact',
onClick: () => {
const contactPeerId = this.peerId;
new PopupPickUser({
peerTypes: ['dialogs', 'contacts'],
onSelect: (peerId) => {
return new Promise((resolve, reject) => {
new PopupPeer('', {
titleLangKey: 'SendMessageTitle',
descriptionLangKey: 'SendContactToGroupText',
descriptionLangArgs: [new PeerTitle({peerId, dialog: true}).element],
buttons: [{
langKey: 'Send',
callback: () => {
resolve();
this.appMessagesManager.sendOther(peerId, this.appUsersManager.getContactMediaInput(contactPeerId));
this.chat.appImManager.setInnerPeer(peerId);
}
}, {
langKey: 'Cancel',
callback: () => {
reject();
},
isCancel: true,
}],
peerId,
overlayClosable: true
}).show();
});
},
placeholder: 'ShareModal.Search.Placeholder',
chatRightsAction: 'send_messages',
selfPresence: 'ChatYourSelf'
});
},
verify: () => rootScope.myId !== this.peerId && this.appPeersManager.isContact(this.peerId)
}, {
icon: 'lock',
text: 'BlockUser',
onClick: () => {
new PopupPeer('', {
peerId: this.peerId,
titleLangKey: 'BlockUser',
descriptionLangKey: 'AreYouSureBlockContact2',
descriptionLangArgs: [new PeerTitle({peerId: this.peerId}).element],
buttons: [{
langKey: 'BlockUser',
isDanger: true,
callback: () => {
this.appUsersManager.toggleBlock(this.peerId, true).then(value => {
if(value) {
toastNew({langPackKey: 'UserBlocked'});
}
});
}
}]
}).show();
},
verify: () => {
const userId = this.peerId.toUserId();
const userFull = this.appProfileManager.usersFull[userId];
return this.appPeersManager.isUser(this.peerId) && this.peerId !== rootScope.myId && userFull && !userFull.pFlags?.blocked;
}
}, {
icon: 'lockoff',
text: 'Unblock',
onClick: () => {
this.appUsersManager.toggleBlock(this.peerId, false).then(value => {
if(value) {
toastNew({langPackKey: 'UserUnblocked'});
}
});
},
verify: () => {
const userFull = this.appProfileManager.usersFull[this.peerId.toUserId()];
return this.appPeersManager.isUser(this.peerId) && !!userFull?.pFlags?.blocked;
}
}, {
icon: 'delete danger',
text: 'Delete',
onClick: () => {
new PopupDeleteDialog(this.peerId/* , 'leave' */);
},
verify: () => this.chat.type === 'chat' && !!this.appMessagesManager.getDialogOnly(this.peerId)
}];
this.btnSearch = ButtonIcon('search');
attachClickEvent(this.btnSearch, (e) => {
cancelEvent(e);
this.chat.initSearch();
}, {listenerSetter: this.listenerSetter});
}
public constructPeerHelpers() {
this.avatarElement = new AvatarElement();
this.avatarElement.setAttribute('dialog', '1');
//this.avatarElement.setAttribute('clickable', '');
this.avatarElement.classList.add('avatar-42', 'person-avatar');
this.subtitle = document.createElement('div');
this.subtitle.classList.add('info');
this.pinnedMessage = new ChatPinnedMessage(this, this.chat, this.appMessagesManager, this.appPeersManager);
this.btnJoin = Button('btn-primary btn-color-primary chat-join hide');
this.btnPinned = ButtonIcon('pinlist');
this.btnMute = ButtonIcon('mute');
attachClickEvent(this.btnPinned, (e) => {
cancelEvent(e);
blurActiveElement();
this.openPinned(true);
}, {listenerSetter: this.listenerSetter});
attachClickEvent(this.btnMute, (e) => {
cancelEvent(e);
blurActiveElement();
this.appMessagesManager.mutePeer(this.peerId);
}, {listenerSetter: this.listenerSetter});
attachClickEvent(this.btnJoin, (e) => {
cancelEvent(e);
blurActiveElement();
const middleware = this.chat.bubbles.getMiddleware();
this.btnJoin.setAttribute('disabled', 'true');
const chatId = this.peerId.toChatId();
let promise: Promise<any>;
if(this.appChatsManager.isChannel(chatId)) {
promise = this.appChatsManager.joinChannel(chatId);
} else {
promise = this.appChatsManager.addChatUser(chatId, rootScope.myId);
}
promise.finally(() => {
if(!middleware()) {
return;
}
this.btnJoin.removeAttribute('disabled');
});
}, {listenerSetter: this.listenerSetter});
this.listenerSetter.add(rootScope)('chat_update', (chatId) => {
if(this.peerId === chatId.toPeerId(true)) {
const chat = this.appChatsManager.getChat(chatId) as Channel/* | Chat */;
this.btnJoin.classList.toggle('hide', !(chat as Channel)?.pFlags?.left);
this.setUtilsWidth();
}
});
this.listenerSetter.add(rootScope)('dialog_notify_settings', (dialog) => {
if(dialog.peerId === this.peerId) {
this.setMutedState();
}
});
this.listenerSetter.add(rootScope)('peer_typings', ({peerId}) => {
if(this.peerId === peerId) {
this.setPeerStatus();
}
});
this.listenerSetter.add(rootScope)('user_update', (userId) => {
if(this.peerId === userId) {
this.setPeerStatus();
}
});
if(this.pinnedMessage) {
this.chat.addEventListener('setPeer', (mid, isTopMessage) => {
const middleware = this.chat.bubbles.getMiddleware();
appStateManager.getState().then((state) => {
if(!middleware()) return;
this.pinnedMessage.hidden = !!state.hiddenPinnedMessages[this.chat.peerId];
if(isTopMessage) {
this.pinnedMessage.unsetScrollDownListener();
this.pinnedMessage.testMid(mid, 0); // * because slider will not let get bubble by document.elementFromPoint
} else if(!this.pinnedMessage.locked) {
this.pinnedMessage.handleFollowingPinnedMessage();
this.pinnedMessage.testMid(mid);
}
});
});
}
this.setPeerStatusInterval = window.setInterval(this.setPeerStatus, 60e3);
return this;
}
public constructPinnedHelpers() {
this.listenerSetter.add(rootScope)('peer_pinned_messages', (e) => {
const {peerId, mids, pinned} = e;
if(peerId !== this.peerId) return;
if(mids) {
this.setTitle();
}
});
}
public constructDiscussionHelpers() {
this.pinnedMessage = new ChatPinnedMessage(this, this.chat, this.appMessagesManager, this.appPeersManager);
}
public openPinned(byCurrent: boolean) {
this.chat.appImManager.setInnerPeer(this.peerId, byCurrent ? +this.pinnedMessage.pinnedMessageContainer.divAndCaption.container.dataset.mid : 0, 'pinned');
}
private onResize = () => {
this.setUtilsWidth(true);
this.setFloating();
};
private onChangeScreen = (from: ScreenSize, to: ScreenSize) => {
this.container.classList.toggle('is-pinned-floating', mediaSizes.isMobile);
// this.chatAudio && this.chatAudio.divAndCaption.container.classList.toggle('is-floating', to === ScreenSize.mobile);
this.pinnedMessage && this.pinnedMessage.pinnedMessageContainer.divAndCaption.container.classList.toggle('is-floating', to === ScreenSize.mobile);
this.onResize();
};
public destroy() {
//this.chat.log.error('Topbar destroying');
this.listenerSetter.removeAll();
window.clearInterval(this.setPeerStatusInterval);
if(this.pinnedMessage) {
this.pinnedMessage.destroy(); // * возможно это можно не делать
}
delete this.chatAudio;
delete this.pinnedMessage;
}
public setPeer(peerId: PeerId) {
this.wasPeerId = this.peerId;
this.peerId = peerId;
this.container.style.display = peerId ? '' : 'none';
}
public finishPeerChange(isTarget: boolean, isJump: boolean, lastMsgId: number) {
const peerId = this.peerId;
if(this.avatarElement) {
this.avatarElement.setAttribute('peer', '' + peerId);
this.avatarElement.update();
}
const isBroadcast = this.appPeersManager.isBroadcast(peerId);
this.btnMute && this.btnMute.classList.toggle('hide', !isBroadcast);
if(this.appPeersManager.isAnyChat(peerId)) {
if(this.btnJoin) {
const chatId = peerId.toChatId();
replaceContent(this.btnJoin, i18n(this.appChatsManager.isChannel(chatId) ? 'Chat.Subscribe' : 'ChannelJoin'));
this.btnJoin.classList.toggle('hide', !this.appChatsManager.getChat(chatId)?.pFlags?.left);
}
}
this.setUtilsWidth();
const middleware = this.chat.bubbles.getMiddleware();
if(this.pinnedMessage) { // * replace with new one
if(this.chat.type === 'chat') {
if(this.wasPeerId !== undefined) { // * change
const newPinnedMessage = new ChatPinnedMessage(this, this.chat, this.appMessagesManager, this.appPeersManager);
this.pinnedMessage.pinnedMessageContainer.divAndCaption.container.replaceWith(newPinnedMessage.pinnedMessageContainer.divAndCaption.container);
this.pinnedMessage.destroy();
//this.pinnedMessage.pinnedMessageContainer.toggle(true);
this.pinnedMessage = newPinnedMessage;
}
appStateManager.getState().then((state) => {
if(!middleware()) return;
this.pinnedMessage.hidden = !!state.hiddenPinnedMessages[peerId];
if(!isTarget) {
this.pinnedMessage.setCorrectIndex(0);
}
});
} else if(this.chat.type === 'discussion') {
this.pinnedMessage.pinnedMid = this.chat.threadId;
this.pinnedMessage.count = 1;
this.pinnedMessage.pinnedIndex = 0;
this.pinnedMessage._setPinnedMessage();
}
}
fastRaf(() => {
this.setTitle();
this.setPeerStatus(true);
this.setMutedState();
});
}
public setTitle(count?: number) {
let titleEl: HTMLElement;
if(this.chat.type === 'pinned') {
if(count === undefined) titleEl = i18n('Loading');
else titleEl = i18n('PinnedMessagesCount', [count]);
if(count === undefined) {
this.appMessagesManager.getSearchCounters(this.peerId, [{_: 'inputMessagesFilterPinned'}], false).then(result => {
const count = result[0].count;
this.setTitle(count);
// ! костыль х2, это нужно делать в другом месте
if(!count) {
this.chat.appImManager.setPeer(NULL_PEER_ID); // * close tab
// ! костыль, это скроет закреплённые сообщения сразу, вместо того, чтобы ждать пока анимация перехода закончится
const originalChat = this.chat.appImManager.chat;
if(originalChat.topbar.pinnedMessage) {
originalChat.topbar.pinnedMessage.pinnedMessageContainer.toggle(true);
}
}
});
}
} else if(this.chat.type === 'scheduled') {
if(this.peerId === rootScope.myId) {
//title = [count > 1 ? count : false, 'Reminders'].filter(Boolean).join(' ');
titleEl = i18n('Reminders');
} else {
titleEl = i18n('ScheduledMessages');
//title = [count > 1 ? count : false, 'Scheduled Messages'].filter(Boolean).join(' ');
}
if(count === undefined) {
this.appMessagesManager.getScheduledMessages(this.peerId).then(mids => {
this.setTitle(mids.length);
});
}
} else if(this.chat.type === 'discussion') {
if(count === undefined) titleEl = i18n('Loading');
else titleEl = i18n('Chat.Title.Comments', [count]);
if(count === undefined) {
Promise.all([
this.appMessagesManager.getHistory(this.peerId, 0, 1, 0, this.chat.threadId),
Promise.resolve()
]).then(() => {
const count = this.appMessagesManager.getHistoryStorage(this.peerId, this.chat.threadId).count;
if(count === null) {
setTimeout(() => {
this.setTitle();
}, 30);
} else {
this.setTitle(count);
}
});
}
} else if(this.chat.type === 'chat') {
titleEl = new PeerTitle({
peerId: this.peerId,
dialog: true,
}).element;
}
replaceContent(this.title, titleEl);
if(this.chat.type === 'chat') {
const peer = this.appPeersManager.getPeer(this.peerId);
if(peer?.pFlags?.verified) {
this.title.append(generateVerifiedIcon());
}
}
}
public setMutedState() {
if(!this.btnMute) return;
const peerId = this.peerId;
let muted = this.appNotificationsManager.isPeerLocalMuted(peerId, false);
if(this.appPeersManager.isBroadcast(peerId)) { // not human
this.btnMute.classList.remove('tgico-mute', 'tgico-unmute');
this.btnMute.classList.add(muted ? 'tgico-unmute' : 'tgico-mute');
this.btnMute.style.display = '';
} else {
this.btnMute.style.display = 'none';
}
}
// ! У МЕНЯ ПРОСТО СГОРЕЛО, САФАРИ КОНЧЕННЫЙ БРАУЗЕР - ЕСЛИ НЕ СКРЫВАТЬ БЛОК, ТО ПРИ ПЕРЕВОРОТЕ ЭКРАНА НА АЙФОНЕ БЛОК БУДЕТ НЕПРАВИЛЬНО ШИРИНЫ, ДАЖЕ БЕЗ ЭТОЙ ФУНКЦИИ!
public setUtilsWidth = (resize = false) => {
//return;
if(this.setUtilsRAF) window.cancelAnimationFrame(this.setUtilsRAF);
if(IS_SAFARI && resize) {
this.chatUtils.classList.add('hide');
}
//mutationObserver.disconnect();
this.setUtilsRAF = window.requestAnimationFrame(() => {
//mutationRAF = window.requestAnimationFrame(() => {
//setTimeout(() => {
if(IS_SAFARI && resize) {
this.chatUtils.classList.remove('hide');
}
/* this.chatInfo.style.removeProperty('--utils-width');
void this.chatInfo.offsetLeft; // reflow */
const width = /* chatUtils.scrollWidth */this.chatUtils.getBoundingClientRect().width;
this.chat.log('utils width:', width);
this.chatInfo.style.setProperty('--utils-width', width + 'px');
//this.chatInfo.classList.toggle('have-utils-width', !!width);
//}, 0);
this.setUtilsRAF = 0;
//mutationObserver.observe(chatUtils, observeOptions);
//});
});
};
public setFloating = () => {
const containers = [this.chatAudio, this.pinnedMessage && this.pinnedMessage.pinnedMessageContainer].filter(Boolean);
const count = containers.reduce((acc, container) => {
const isFloating = container.divAndCaption.container.classList.contains('is-floating');
this.container.classList.toggle(`is-pinned-${container.className}-floating`, isFloating);
return acc + +isFloating;
}, 0);
this.container.dataset.floating = '' + count;
};
public setPeerStatus = (needClear = false) => {
if(!this.subtitle) return;
const peerId = this.peerId;
this.chat.appImManager.setPeerStatus(this.peerId, this.subtitle, needClear, false, () => peerId === this.peerId);
};
}