parent
4609f6cac5
commit
8e4b9687ce
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 496 KiB |
|
@ -204,7 +204,7 @@ export default class AppSearch {
|
|||
appDialogsManager.addDialogAndSetLastMessage({
|
||||
peerId,
|
||||
container: this.scrollable/* searchGroup.list */,
|
||||
avatarSize: 54,
|
||||
avatarSize: 'bigger',
|
||||
meAsSaved: false,
|
||||
message,
|
||||
query,
|
||||
|
|
|
@ -73,6 +73,7 @@ import SwipeHandler from './swipeHandler';
|
|||
import wrapDocument from './wrappers/document';
|
||||
import wrapPhoto from './wrappers/photo';
|
||||
import wrapVideo from './wrappers/video';
|
||||
import noop from '../helpers/noop';
|
||||
|
||||
// const testScroll = false;
|
||||
|
||||
|
@ -610,7 +611,7 @@ export default class AppSearchSuper {
|
|||
const {dom} = appDialogsManager.addDialogNew({
|
||||
peerId: message.peerId,
|
||||
container: searchGroup.list,
|
||||
avatarSize: 54,
|
||||
avatarSize: 'bigger',
|
||||
loadPromises
|
||||
});
|
||||
|
||||
|
@ -625,7 +626,7 @@ export default class AppSearchSuper {
|
|||
});
|
||||
|
||||
loadPromises.push(setLastMessagePromise);
|
||||
return Promise.all(loadPromises);
|
||||
return Promise.all(loadPromises).then(noop);
|
||||
}
|
||||
|
||||
private async processPhotoVideoFilter({message, promises, middleware}: ProcessSearchSuperResult) {
|
||||
|
@ -705,10 +706,8 @@ export default class AppSearchSuper {
|
|||
let url: string, display_url: string, sliced: string;
|
||||
|
||||
if(!entity) {
|
||||
// this.log.error('NO ENTITY:', message);
|
||||
const match = matchUrl(message.message);
|
||||
if(!match) {
|
||||
// this.log.error('NO ENTITY AND NO MATCH:', message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -748,7 +747,7 @@ export default class AppSearchSuper {
|
|||
}
|
||||
|
||||
const previewDiv = document.createElement('div');
|
||||
previewDiv.classList.add('preview', 'row-media', 'row-media-big');
|
||||
previewDiv.classList.add('preview');
|
||||
|
||||
// this.log('wrapping webpage', webpage);
|
||||
|
||||
|
@ -808,19 +807,7 @@ export default class AppSearchSuper {
|
|||
noRipple: true
|
||||
});
|
||||
|
||||
/* const mediaDiv = document.createElement('div');
|
||||
mediaDiv.classList.add('row-media'); */
|
||||
|
||||
row.container.append(previewDiv);
|
||||
|
||||
/* ripple(div);
|
||||
div.append(previewDiv);
|
||||
div.insertAdjacentHTML('beforeend', `
|
||||
<div class="title">${title}${titleAdditionHTML}</div>
|
||||
<div class="subtitle">${subtitle}</div>
|
||||
<div class="url">${url}</div>
|
||||
${sender}
|
||||
`); */
|
||||
row.applyMediaElement(previewDiv, 'big');
|
||||
|
||||
if(row.container.innerText.trim().length) {
|
||||
return {message, element: row.container};
|
||||
|
@ -923,6 +910,10 @@ export default class AppSearchSuper {
|
|||
const method = append ? 'append' : 'prepend';
|
||||
elemsToAppend.forEach((details) => {
|
||||
const {element, message} = details;
|
||||
if(!message) {
|
||||
debugger;
|
||||
}
|
||||
|
||||
const monthContainer = this.getMonthContainerByTimestamp(this.groupByMonth ? message.date : 0, inputFilter);
|
||||
element.classList.add('search-super-item');
|
||||
element.dataset.mid = '' + message.mid;
|
||||
|
@ -982,12 +973,12 @@ export default class AppSearchSuper {
|
|||
const {dom} = appDialogsManager.addDialogNew({
|
||||
peerId: peerId,
|
||||
container: group.list,
|
||||
avatarSize: 48,
|
||||
avatarSize: 'abitbigger',
|
||||
autonomous: group.autonomous
|
||||
});
|
||||
|
||||
return {dom, peerId};
|
||||
}).forEach(async({dom, peerId}) => {
|
||||
}).filter(Boolean).forEach(async({dom, peerId}) => {
|
||||
const peer = await this.managers.appPeersManager.getPeer(peerId);
|
||||
if(showMembersCount && (peer.participants_count || peer.participants)) {
|
||||
const regExp = new RegExp(`(${escapeRegExp(query)}|${escapeRegExp(cleanSearchText(query))})`, 'gi');
|
||||
|
@ -1006,7 +997,7 @@ export default class AppSearchSuper {
|
|||
username = '@' + username;
|
||||
}
|
||||
|
||||
dom.lastMessageSpan.innerHTML = '<i>' + username + '</i>';
|
||||
dom.lastMessageSpan.textContent = username;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1024,7 +1015,7 @@ export default class AppSearchSuper {
|
|||
};
|
||||
|
||||
return Promise.all([
|
||||
this.managers.appUsersManager.getContactsPeerIds(query, true)
|
||||
this.managers.appUsersManager.getContactsPeerIds(query, true, undefined, 10)
|
||||
.then(onLoad)
|
||||
.then((contacts) => {
|
||||
if(contacts) {
|
||||
|
@ -1084,7 +1075,7 @@ export default class AppSearchSuper {
|
|||
peerId: peerId,
|
||||
container: this.searchGroups.recent.list,
|
||||
meAsSaved: true,
|
||||
avatarSize: 48,
|
||||
avatarSize: 'abitbigger',
|
||||
autonomous: true
|
||||
});
|
||||
|
||||
|
@ -1113,14 +1104,16 @@ export default class AppSearchSuper {
|
|||
// console.log('got top categories:', categories);
|
||||
if(peers.length) {
|
||||
peers.forEach((peer) => {
|
||||
appDialogsManager.addDialogNew({
|
||||
const {dom} = appDialogsManager.addDialogNew({
|
||||
peerId: peer.id,
|
||||
container: this.searchGroups.people.list,
|
||||
onlyFirstName: true,
|
||||
avatarSize: 54,
|
||||
avatarSize: 'bigger',
|
||||
autonomous: false,
|
||||
noIcons: this.searchGroups.people.noIcons
|
||||
});
|
||||
|
||||
dom.subtitleEl.remove();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import type {ChatRights} from '../lib/appManagers/appChatsManager';
|
||||
import type {Dialog} from '../lib/appManagers/appMessagesManager';
|
||||
import appDialogsManager from '../lib/appManagers/appDialogsManager';
|
||||
import appDialogsManager, {DialogElementSize as DialogElementSize} from '../lib/appManagers/appDialogsManager';
|
||||
import rootScope from '../lib/rootScope';
|
||||
import Scrollable from './scrollable';
|
||||
import {FocusDirection} from '../helpers/fastSmoothScroll';
|
||||
|
@ -77,7 +77,7 @@ export default class AppSelectPeers {
|
|||
private chatRightsAction: ChatRights;
|
||||
private multiSelect = true;
|
||||
private rippleEnabled = true;
|
||||
private avatarSize = 48;
|
||||
private avatarSize: DialogElementSize = 'abitbigger';
|
||||
private exceptSelf = false;
|
||||
private filterPeerTypeBy: IsPeerType[];
|
||||
|
||||
|
@ -94,6 +94,8 @@ export default class AppSelectPeers {
|
|||
|
||||
private managers: AppManagers;
|
||||
|
||||
private design: 'round' | 'square' = 'round';
|
||||
|
||||
constructor(options: {
|
||||
appendTo: AppSelectPeers['appendTo'],
|
||||
onChange?: AppSelectPeers['onChange'],
|
||||
|
@ -110,11 +112,12 @@ export default class AppSelectPeers {
|
|||
exceptSelf?: AppSelectPeers['exceptSelf'],
|
||||
filterPeerTypeBy?: AppSelectPeers['filterPeerTypeBy'],
|
||||
sectionNameLangPackKey?: AppSelectPeers['sectionNameLangPackKey'],
|
||||
managers: AppSelectPeers['managers']
|
||||
managers: AppSelectPeers['managers'],
|
||||
design?: AppSelectPeers['design']
|
||||
}) {
|
||||
safeAssign(this, options);
|
||||
|
||||
this.container.classList.add('selector');
|
||||
this.container.classList.add('selector', 'selector-' + this.design);
|
||||
|
||||
const f = (this.renderResultsFunc || this.renderResults).bind(this);
|
||||
this.renderResultsFunc = async(peerIds) => {
|
||||
|
@ -313,7 +316,7 @@ export default class AppSelectPeers {
|
|||
}
|
||||
|
||||
// в десктопе - сначала без группы, потом архивные, потом контакты без сообщений
|
||||
const pageCount = windowSize.height / 72 * 1.25 | 0;
|
||||
const pageCount = windowSize.height / 56 * 1.25 | 0;
|
||||
|
||||
const tempId = this.getTempId('dialogs');
|
||||
const promise = this.managers.appMessagesManager.getConversations(this.query, this.offsetIndex, pageCount, this.folderId, true);
|
||||
|
@ -420,7 +423,7 @@ export default class AppSelectPeers {
|
|||
}
|
||||
|
||||
// if(this.cachedContacts.length) {
|
||||
const pageCount = windowSize.height / 72 * 1.25 | 0;
|
||||
const pageCount = windowSize.height / 56 * 1.25 | 0;
|
||||
const arr = this.cachedContacts.splice(0, pageCount);
|
||||
this.renderResultsFunc(arr);
|
||||
// }
|
||||
|
|
|
@ -289,7 +289,11 @@ export default class BubbleGroups {
|
|||
removeAndUnmountBubble(bubble: HTMLElement) {
|
||||
const item = this.getItemByBubble(bubble);
|
||||
if(!item) {
|
||||
return;
|
||||
if(bubble.parentElement) {
|
||||
bubble.remove(); // * can be a placeholder
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const items = this.itemsArr;
|
||||
|
@ -320,6 +324,8 @@ export default class BubbleGroups {
|
|||
}
|
||||
|
||||
this.mountUnmountGroups(Array.from(modifiedGroups));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
mountUnmountGroups(groups: BubbleGroup[]) {
|
||||
|
|
|
@ -2046,23 +2046,15 @@ export default class ChatBubbles {
|
|||
// return;
|
||||
|
||||
if(this.isHeavyAnimationInProgress) {
|
||||
if(this.sliceViewportDebounced) {
|
||||
this.sliceViewportDebounced.clearTimeout();
|
||||
}
|
||||
this.sliceViewportDebounced?.clearTimeout();
|
||||
|
||||
// * В таком случае, кнопка не будет моргать если чат в самом низу, и правильно отработает случай написания нового сообщения и проскролла вниз
|
||||
if(this.scrolledDown && !ignoreHeavyAnimation) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if(this.chat.topbar.pinnedMessage) {
|
||||
this.chat.topbar.pinnedMessage.setCorrectIndexThrottled(this.scrollable.lastScrollDirection);
|
||||
}
|
||||
|
||||
if(this.sliceViewportDebounced) {
|
||||
this.sliceViewportDebounced();
|
||||
}
|
||||
|
||||
this.chat.topbar.pinnedMessage?.setCorrectIndexThrottled(this.scrollable.lastScrollDirection);
|
||||
this.sliceViewportDebounced?.();
|
||||
this.setStickyDateManually();
|
||||
}
|
||||
|
||||
|
@ -2172,41 +2164,46 @@ export default class ChatBubbles {
|
|||
}
|
||||
}
|
||||
|
||||
public destroyBubble(bubble: HTMLElement, mid = +bubble.dataset.mid) {
|
||||
// this.log.warn('destroy bubble', bubble, mid);
|
||||
bubble.middlewareHelper.destroy();
|
||||
|
||||
/* const mounted = this.getMountedBubble(mid);
|
||||
if(!mounted) return; */
|
||||
|
||||
if(this.bubbles[mid] === bubble) { // have to check because can clear bubble with same id later
|
||||
delete this.bubbles[mid];
|
||||
}
|
||||
|
||||
this.skippedMids.delete(mid);
|
||||
|
||||
if(this.firstUnreadBubble === bubble) {
|
||||
this.firstUnreadBubble = null;
|
||||
}
|
||||
|
||||
this.bubbleGroups.removeAndUnmountBubble(bubble);
|
||||
if(this.observer) {
|
||||
this.observer.unobserve(bubble, this.unreadedObserverCallback);
|
||||
this.unreaded.delete(bubble);
|
||||
|
||||
this.observer.unobserve(bubble, this.viewsObserverCallback);
|
||||
this.viewsMids.delete(mid);
|
||||
|
||||
this.observer.unobserve(bubble, this.stickerEffectObserverCallback);
|
||||
}
|
||||
|
||||
// this.reactions.delete(mid);
|
||||
}
|
||||
|
||||
public deleteMessagesByIds(mids: number[], permanent = true, ignoreOnScroll?: boolean) {
|
||||
let deleted = false;
|
||||
mids.forEach((mid) => {
|
||||
const bubble = this.bubbles[mid];
|
||||
if(!bubble) return;
|
||||
|
||||
bubble.middlewareHelper.destroy();
|
||||
this.destroyBubble(bubble, mid);
|
||||
|
||||
deleted = true;
|
||||
/* const mounted = this.getMountedBubble(mid);
|
||||
if(!mounted) return; */
|
||||
|
||||
delete this.bubbles[mid];
|
||||
this.skippedMids.delete(mid);
|
||||
|
||||
if(this.firstUnreadBubble === bubble) {
|
||||
this.firstUnreadBubble = null;
|
||||
}
|
||||
|
||||
this.bubbleGroups.removeAndUnmountBubble(bubble);
|
||||
if(this.observer) {
|
||||
this.observer.unobserve(bubble, this.unreadedObserverCallback);
|
||||
this.unreaded.delete(bubble);
|
||||
|
||||
this.observer.unobserve(bubble, this.viewsObserverCallback);
|
||||
this.viewsMids.delete(mid);
|
||||
|
||||
this.observer.unobserve(bubble, this.stickerEffectObserverCallback);
|
||||
}
|
||||
|
||||
if(this.emptyPlaceholderBubble === bubble) {
|
||||
this.emptyPlaceholderBubble = undefined;
|
||||
}
|
||||
|
||||
// this.reactions.delete(mid);
|
||||
});
|
||||
|
||||
if(!deleted) {
|
||||
|
@ -2552,53 +2549,54 @@ export default class ChatBubbles {
|
|||
|
||||
public getDateContainerByTimestamp(timestamp: number) {
|
||||
const {date, dateTimestamp} = this.getDateForDateContainer(timestamp);
|
||||
if(!this.dateMessages[dateTimestamp]) {
|
||||
const bubble = this.createDateBubble(timestamp, date);
|
||||
// bubble.classList.add('is-sticky');
|
||||
const fakeBubble = this.createDateBubble(timestamp, date);
|
||||
fakeBubble.classList.add('is-fake');
|
||||
let ret = this.dateMessages[dateTimestamp];
|
||||
if(ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
const container = document.createElement('section');
|
||||
container.className = 'bubbles-date-group';
|
||||
container.append(bubble, fakeBubble);
|
||||
const bubble = this.createDateBubble(timestamp, date);
|
||||
// bubble.classList.add('is-sticky');
|
||||
const fakeBubble = this.createDateBubble(timestamp, date);
|
||||
fakeBubble.classList.add('is-fake');
|
||||
|
||||
this.dateMessages[dateTimestamp] = {
|
||||
div: bubble,
|
||||
container,
|
||||
firstTimestamp: date.getTime()
|
||||
};
|
||||
const container = document.createElement('section');
|
||||
container.className = 'bubbles-date-group';
|
||||
container.append(bubble, fakeBubble);
|
||||
|
||||
const haveTimestamps = getObjectKeysAndSort(this.dateMessages, 'asc');
|
||||
const length = haveTimestamps.length;
|
||||
let i = 0, insertBefore: HTMLElement; // there can be 'first bubble' (e.g. bot description) so can't insert by index
|
||||
for(; i < haveTimestamps.length; ++i) {
|
||||
const t = haveTimestamps[i];
|
||||
insertBefore = this.dateMessages[t].container;
|
||||
if(dateTimestamp < t) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret = this.dateMessages[dateTimestamp] = {
|
||||
div: bubble,
|
||||
container,
|
||||
firstTimestamp: date.getTime()
|
||||
};
|
||||
|
||||
if(i === length && insertBefore) {
|
||||
insertBefore = insertBefore.nextElementSibling as HTMLElement;
|
||||
}
|
||||
|
||||
if(!insertBefore) {
|
||||
this.chatInner.append(container);
|
||||
} else {
|
||||
this.chatInner.insertBefore(container, insertBefore);
|
||||
}
|
||||
|
||||
if(this.stickyIntersector) {
|
||||
this.stickyIntersector.observeStickyHeaderChanges(container);
|
||||
}
|
||||
|
||||
if(this.chatInner.parentElement) {
|
||||
this.container.classList.add('has-groups');
|
||||
const haveTimestamps = getObjectKeysAndSort(this.dateMessages, 'asc');
|
||||
const length = haveTimestamps.length;
|
||||
let i = 0, insertBefore: HTMLElement; // there can be 'first bubble' (e.g. bot description) so can't insert by index
|
||||
for(; i < haveTimestamps.length; ++i) {
|
||||
const t = haveTimestamps[i];
|
||||
insertBefore = this.dateMessages[t].container;
|
||||
if(dateTimestamp < t) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return this.dateMessages[dateTimestamp];
|
||||
if(i === length && insertBefore) {
|
||||
insertBefore = insertBefore.nextElementSibling as HTMLElement;
|
||||
}
|
||||
|
||||
if(!insertBefore) {
|
||||
this.chatInner.append(container);
|
||||
} else {
|
||||
this.chatInner.insertBefore(container, insertBefore);
|
||||
}
|
||||
|
||||
this.stickyIntersector?.observeStickyHeaderChanges(container);
|
||||
|
||||
if(this.chatInner.parentElement) {
|
||||
this.container.classList.add('has-groups');
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private destroyScrollable() {
|
||||
|
@ -2622,6 +2620,8 @@ export default class ChatBubbles {
|
|||
}
|
||||
|
||||
public cleanup(bubblesToo = false) {
|
||||
this.log('cleanup');
|
||||
|
||||
this.bubbles = {}; // clean it before so sponsored message won't be deleted faster on peer changing
|
||||
// //console.time('appImManager cleanup');
|
||||
this.setLoaded('top', false, false);
|
||||
|
@ -2707,11 +2707,7 @@ export default class ChatBubbles {
|
|||
|
||||
private cleanupPlaceholders(bubble = this.emptyPlaceholderBubble) {
|
||||
if(bubble) {
|
||||
bubble.remove();
|
||||
|
||||
if(this.emptyPlaceholderBubble === bubble) {
|
||||
this.emptyPlaceholderBubble = undefined;
|
||||
}
|
||||
this.destroyBubble(bubble);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4748,9 +4744,12 @@ export default class ChatBubbles {
|
|||
};
|
||||
}
|
||||
|
||||
public async performHistoryResult(historyResult: HistoryResult | {history: (Message.message | Message.messageService | number)[]}, reverse: boolean) {
|
||||
public async performHistoryResult(
|
||||
historyResult: HistoryResult | {history: (Message.message | Message.messageService | number)[]},
|
||||
reverse: boolean
|
||||
) {
|
||||
const log = false ? this.log.bindPrefix('perform-' + (Math.random() * 1000 | 0)) : undefined;
|
||||
log && log('start', this.chatInner.parentElement);
|
||||
log?.('start', this.chatInner.parentElement);
|
||||
|
||||
let history = historyResult.history;
|
||||
history = history.slice(); // need
|
||||
|
@ -4817,13 +4816,10 @@ export default class ChatBubbles {
|
|||
|
||||
if(this.scrollable.loadedAll.top && this.messagesQueueOnRenderAdditional) {
|
||||
this.messagesQueueOnRenderAdditional();
|
||||
|
||||
if(this.messagesQueueOnRenderAdditional) {
|
||||
this.messagesQueueOnRenderAdditional();
|
||||
}
|
||||
this.messagesQueueOnRenderAdditional?.(); // * can set it second time
|
||||
}
|
||||
|
||||
log && log('performHistoryResult end');
|
||||
log?.('performHistoryResult end');
|
||||
}
|
||||
|
||||
private onRenderScrollSet(state?: {scrollHeight: number, clientHeight: number}) {
|
||||
|
@ -5174,16 +5170,22 @@ export default class ChatBubbles {
|
|||
elements.forEach((element: any) => element.classList.add(BASE_CLASS + '-line'));
|
||||
}
|
||||
|
||||
private async processLocalMessageRender(message: Message.message | Message.messageService, animate?: boolean) {
|
||||
private async processLocalMessageRender(
|
||||
message: Message.message | Message.messageService,
|
||||
animate?: boolean,
|
||||
middleware = this.getMiddleware()
|
||||
) {
|
||||
const isSponsored = !!(message as Message.message).pFlags.sponsored;
|
||||
const middleware = this.getMiddleware();
|
||||
const m = middlewarePromise(middleware);
|
||||
return this.safeRenderMessage(message, isSponsored ? false : true, undefined, isSponsored, async(result) => {
|
||||
|
||||
const p: Parameters<ChatBubbles['safeRenderMessage']>[4] = async(result) => {
|
||||
const {bubble} = await m(result);
|
||||
if(!bubble) {
|
||||
return result;
|
||||
}
|
||||
|
||||
(bubble as any).message = message;
|
||||
|
||||
bubble.classList.add('is-group-last', 'is-group-first');
|
||||
|
||||
const updatePosition = () => {
|
||||
|
@ -5208,6 +5210,7 @@ export default class ChatBubbles {
|
|||
let text: LangPackKey, mid: number, startParam: string, callback: () => void;
|
||||
|
||||
bubble.classList.add('avoid-selection');
|
||||
bubble.style.order = '999999';
|
||||
|
||||
const sponsoredMessage = this.sponsoredMessage = (message as Message.message).sponsoredMessage;
|
||||
const peerId = getPeerId(sponsoredMessage.from_id);
|
||||
|
@ -5257,14 +5260,18 @@ export default class ChatBubbles {
|
|||
|
||||
bubble.querySelector('.bubble-content').prepend(button);
|
||||
|
||||
return result;
|
||||
appendTo = this.chatInner;
|
||||
method = 'append';
|
||||
animate = false;
|
||||
|
||||
// return result;
|
||||
} else if(isBot && message._ === 'message') {
|
||||
const b = document.createElement('b');
|
||||
b.append(i18n('BotInfoTitle'));
|
||||
elements.push(b, '\n\n');
|
||||
appendTo = this.chatInner;
|
||||
method = 'prepend';
|
||||
} else if(await m(this.managers.appPeersManager.isAnyGroup(this.peerId)) && (await m(this.managers.appPeersManager.getPeer(this.peerId))).pFlags.creator) {
|
||||
} else if(this.chat.isAnyGroup && (await m(this.managers.appPeersManager.getPeer(this.peerId))).pFlags.creator) {
|
||||
renderPromise = this.renderEmptyPlaceholder('group', bubble, message, elements);
|
||||
} else if(this.chat.type === 'scheduled') {
|
||||
renderPromise = this.renderEmptyPlaceholder('noScheduledMessages', bubble, message, elements);
|
||||
|
@ -5332,12 +5339,24 @@ export default class ChatBubbles {
|
|||
this.animateAsLadder(message.mid, additionMsgIds, false, 0, 0);
|
||||
}
|
||||
|
||||
// if(!isSponsored) {
|
||||
bubble.middlewareHelper.onDestroy(() => {
|
||||
if(this.emptyPlaceholderBubble === bubble) {
|
||||
this.emptyPlaceholderBubble = undefined;
|
||||
}
|
||||
});
|
||||
|
||||
this.emptyPlaceholderBubble = bubble;
|
||||
// }
|
||||
|
||||
return result;
|
||||
});
|
||||
};
|
||||
|
||||
return this.safeRenderMessage(
|
||||
message,
|
||||
!isSponsored,
|
||||
undefined,
|
||||
false,
|
||||
p
|
||||
);
|
||||
}
|
||||
|
||||
private generateLocalMessageId(addOffset = 0) {
|
||||
|
@ -5471,19 +5490,23 @@ export default class ChatBubbles {
|
|||
}
|
||||
|
||||
private async toggleSponsoredMessage(value: boolean) {
|
||||
const _log = this.log.bindPrefix('sponsored');
|
||||
_log('checking');
|
||||
const log = this.log.bindPrefix('sponsored');
|
||||
log('checking');
|
||||
const {mid} = this.generateLocalMessageId(SPONSORED_MESSAGE_ID_OFFSET);
|
||||
if(value) {
|
||||
const middleware = this.getMiddleware(() => {
|
||||
return this.scrollable.loadedAll.bottom && !this.bubbles[mid] && this.getSponsoredMessagePromise === promise;
|
||||
return this.scrollable.loadedAll.bottom && this.getSponsoredMessagePromise === promise;
|
||||
});
|
||||
|
||||
const promise = this.getSponsoredMessagePromise = this.managers.appChatsManager.getSponsoredMessage(this.peerId.toChatId())
|
||||
.then(async(sponsoredMessages) => {
|
||||
if(!middleware()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const sponsoredMessage = sponsoredMessages.messages[0];
|
||||
if(!sponsoredMessage) {
|
||||
_log('no message');
|
||||
log('no message');
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5502,16 +5525,18 @@ export default class ChatBubbles {
|
|||
]).then(([message]) => {
|
||||
if(!middleware()) return;
|
||||
// this.processLocalMessageRender(message);
|
||||
_log('rendering', message);
|
||||
const promise = this.performHistoryResult({history: [message]}, false);
|
||||
log('rendering', message);
|
||||
return this.performHistoryResult({history: [message]}, false);
|
||||
});
|
||||
}).finally(() => {
|
||||
this.getSponsoredMessagePromise = undefined;
|
||||
if(this.getSponsoredMessagePromise === promise) {
|
||||
this.getSponsoredMessagePromise = undefined;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
_log('clearing rendered', mid);
|
||||
this.deleteMessagesByIds([mid]);
|
||||
log('clearing rendered', mid);
|
||||
this.getSponsoredMessagePromise = undefined;
|
||||
this.deleteMessagesByIds([mid]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5565,7 +5590,7 @@ export default class ChatBubbles {
|
|||
this.chat.isRestricted ||
|
||||
!(await this.chat.getHistoryStorage()).count ||
|
||||
(
|
||||
!Object.keys(this.bubbles).length ||
|
||||
// !Object.keys(this.bubbles).length ||
|
||||
// ! WARNING ! ! ! ! ! ! REPLACE LINE ABOVE WITH THESE
|
||||
Object.keys(this.bubbles).length &&
|
||||
!this.getRenderedLength()
|
||||
|
|
|
@ -398,6 +398,7 @@ export default class Chat extends EventListenerBase<{
|
|||
public destroy() {
|
||||
// const perf = performance.now();
|
||||
|
||||
this.destroySharedMediaTab();
|
||||
this.topbar.destroy();
|
||||
this.bubbles.destroy();
|
||||
this.input.destroy();
|
||||
|
@ -523,6 +524,10 @@ export default class Chat extends EventListenerBase<{
|
|||
}
|
||||
|
||||
public destroySharedMediaTab(tab = this.sharedMediaTab) {
|
||||
if(!tab) {
|
||||
return;
|
||||
}
|
||||
|
||||
indexOfAndSplice(this.sharedMediaTabs, tab);
|
||||
tab.destroy();
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ export default class ChatContextMenu {
|
|||
}
|
||||
|
||||
this.isSelected = this.chat.selection.isMidSelected(this.peerId, this.mid);
|
||||
this.message = await this.chat.getMessage(this.mid);
|
||||
this.message = (bubble as any).message || await this.chat.getMessage(this.mid);
|
||||
this.noForwards = !isSponsored && !(await this.managers.appMessagesManager.canForward(this.message));
|
||||
this.viewerPeerId = undefined;
|
||||
this.canOpenReactedList = undefined;
|
||||
|
@ -703,7 +703,13 @@ export default class ChatContextMenu {
|
|||
let menuPadding: MenuPositionPadding;
|
||||
let reactionsMenu: ChatReactionsMenu;
|
||||
let reactionsMenuPosition: 'horizontal' | 'vertical';
|
||||
if(this.message._ === 'message' && !this.chat.selection.isSelecting && !this.message.pFlags.is_outgoing && !this.message.pFlags.is_scheduled) {
|
||||
if(
|
||||
this.message._ === 'message' &&
|
||||
!this.chat.selection.isSelecting &&
|
||||
!this.message.pFlags.is_outgoing &&
|
||||
!this.message.pFlags.is_scheduled &&
|
||||
!this.message.pFlags.local
|
||||
) {
|
||||
reactionsMenuPosition = (IS_APPLE || IS_TOUCH_SUPPORTED)/* && false */ ? 'horizontal' : 'vertical';
|
||||
reactionsMenu = this.reactionsMenu = new ChatReactionsMenu(this.managers, reactionsMenuPosition, this.middleware);
|
||||
reactionsMenu.init(await this.managers.appMessagesManager.getGroupsFirstMessage(this.message));
|
||||
|
@ -876,11 +882,11 @@ export default class ChatContextMenu {
|
|||
};
|
||||
|
||||
private onRetractVote = () => {
|
||||
this.managers.appPollsManager.sendVote(this.message, []);
|
||||
this.managers.appPollsManager.sendVote(this.message as Message.message, []);
|
||||
};
|
||||
|
||||
private onStopPoll = () => {
|
||||
this.managers.appPollsManager.stopPoll(this.message);
|
||||
this.managers.appPollsManager.stopPoll(this.message as Message.message);
|
||||
};
|
||||
|
||||
private onForwardClick = async() => {
|
||||
|
|
|
@ -8,8 +8,7 @@ import positionElementByIndex from '../../helpers/dom/positionElementByIndex';
|
|||
import replaceContent from '../../helpers/dom/replaceContent';
|
||||
import {fastRaf} from '../../helpers/schedulers';
|
||||
import SortedList, {SortedElementBase} from '../../helpers/sortedList';
|
||||
import {GroupCallParticipant} from '../../layer';
|
||||
import appDialogsManager, {DialogDom, AppDialogsManager} from '../../lib/appManagers/appDialogsManager';
|
||||
import appDialogsManager, {DialogDom, AppDialogsManager, DialogElementSize} from '../../lib/appManagers/appDialogsManager';
|
||||
import {getGroupCallParticipantMutedState} from '.';
|
||||
import GroupCallParticipantMutedIcon from './participantMutedIcon';
|
||||
import GroupCallParticipantStatusElement from './participantStatus';
|
||||
|
@ -26,7 +25,7 @@ export default class GroupCallParticipantsList extends SortedList<SortedParticip
|
|||
public list: HTMLUListElement;
|
||||
|
||||
protected lazyLoadQueue: LazyLoadQueue;
|
||||
protected avatarSize = 54;
|
||||
protected avatarSize: DialogElementSize = 'abitbigger';
|
||||
protected rippleEnabled = true;
|
||||
protected autonomous = true;
|
||||
protected createChatListOptions: Parameters<AppDialogsManager['createChatList']>[0] = {/* new: true, */dialogSize: 72};
|
||||
|
|
|
@ -442,9 +442,7 @@ export default class PeerProfile {
|
|||
public setPeer(peerId: PeerId, threadId = 0) {
|
||||
if(this.peerId === peerId && this.threadId === threadId) return;
|
||||
|
||||
if(this.init) {
|
||||
this.init();
|
||||
}
|
||||
this.init?.();
|
||||
|
||||
this.peerId = peerId;
|
||||
this.threadId = threadId;
|
||||
|
@ -460,6 +458,7 @@ export default class PeerProfile {
|
|||
}
|
||||
|
||||
public destroy() {
|
||||
this.peerId = this.threadId = undefined;
|
||||
this.clearSetMoreDetailsTimeout();
|
||||
clearInterval(this.setPeerStatusInterval);
|
||||
this.avatars?.cleanup();
|
||||
|
|
|
@ -30,5 +30,8 @@ export default class PopupForward extends PopupPickUser {
|
|||
chatRightsAction: 'send_messages',
|
||||
selfPresence: 'ChatYourSelf'
|
||||
});
|
||||
|
||||
this.scrollable = this.selector.scrollable;
|
||||
this.attachScrollableListeners(this.scrollable);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -159,12 +159,7 @@ export default class PopupElement<T extends EventListenerListeners = {}> extends
|
|||
|
||||
if(options.scrollable) {
|
||||
const scrollable = this.scrollable = new Scrollable(this.body);
|
||||
scrollable.onAdditionalScroll = () => {
|
||||
scrollable.container.classList.toggle('scrolled-top', !scrollable.scrollTop);
|
||||
scrollable.container.classList.toggle('scrolled-bottom', scrollable.isScrolledDown);
|
||||
};
|
||||
|
||||
scrollable.container.classList.add('scrolled-top', 'scrolled-bottom', 'scrollable-y-bordered');
|
||||
this.attachScrollableListeners(scrollable);
|
||||
|
||||
if(!this.body) {
|
||||
this.container.insertBefore(scrollable.container, this.header.nextSibling);
|
||||
|
@ -215,6 +210,17 @@ export default class PopupElement<T extends EventListenerListeners = {}> extends
|
|||
PopupElement.POPUPS.push(this);
|
||||
}
|
||||
|
||||
protected attachScrollableListeners(scrollable: Scrollable) {
|
||||
const cb = scrollable.onAdditionalScroll;
|
||||
scrollable.onAdditionalScroll = () => {
|
||||
cb?.();
|
||||
scrollable.container.classList.toggle('scrolled-top', !scrollable.scrollTop);
|
||||
scrollable.container.classList.toggle('scrolled-bottom', scrollable.isScrolledDown);
|
||||
};
|
||||
|
||||
scrollable.container.classList.add('scrolled-top', 'scrolled-bottom', 'scrollable-y-bordered');
|
||||
}
|
||||
|
||||
protected onContentUpdate() {
|
||||
if(this.scrollable) {
|
||||
this.scrollable.onAdditionalScroll();
|
||||
|
@ -290,6 +296,7 @@ export default class PopupElement<T extends EventListenerListeners = {}> extends
|
|||
this.element.remove();
|
||||
this.dispatchEvent<PopupListeners>('closeAfterTimeout');
|
||||
this.cleanup();
|
||||
this.scrollable?.destroy();
|
||||
|
||||
if(!this.withoutOverlay) {
|
||||
animationIntersector.checkAnimations2(false);
|
||||
|
|
|
@ -54,7 +54,7 @@ export default class PopupPickUser extends PopupElement {
|
|||
chatRightsAction: options.chatRightsAction,
|
||||
multiSelect: false,
|
||||
rippleEnabled: false,
|
||||
avatarSize: 46,
|
||||
avatarSize: 'abitbigger',
|
||||
peerId: options.peerId,
|
||||
placeholder: options.placeholder,
|
||||
selfPresence: options.selfPresence,
|
||||
|
|
|
@ -144,7 +144,7 @@ export default class PopupReactedList extends PopupElement {
|
|||
peerId: peerId,
|
||||
autonomous: true,
|
||||
container: chatlist,
|
||||
avatarSize: 54,
|
||||
avatarSize: 'abitbigger',
|
||||
rippleEnabled: false,
|
||||
meAsSaved: false
|
||||
});
|
||||
|
|
|
@ -16,12 +16,30 @@ import {attachClickEvent} from '../helpers/dom/clickEvent';
|
|||
import ListenerSetter from '../helpers/listenerSetter';
|
||||
import Button from './button';
|
||||
|
||||
type K = string | HTMLElement | DocumentFragment | true;
|
||||
|
||||
const setContent = (element: HTMLElement, content: K) => {
|
||||
if(content === true) {
|
||||
|
||||
} else if(typeof(content) === 'string') {
|
||||
setInnerHTML(element, content);
|
||||
} else {
|
||||
element.append(content);
|
||||
}
|
||||
};
|
||||
|
||||
export type RowMediaSizeType = 'small' | 'medium' | 'big' | 'abitbigger' | 'bigger';
|
||||
|
||||
export default class Row {
|
||||
public container: HTMLElement;
|
||||
public title: HTMLDivElement;
|
||||
public title: HTMLElement;
|
||||
public titleRow: HTMLElement;
|
||||
public titleRight: HTMLElement;
|
||||
public media: HTMLElement;
|
||||
|
||||
public subtitleRow: HTMLElement;
|
||||
public subtitleRight: HTMLElement;
|
||||
|
||||
public checkboxField: CheckboxField;
|
||||
public radioField: RadioField;
|
||||
|
||||
|
@ -33,17 +51,18 @@ export default class Row {
|
|||
|
||||
constructor(options: Partial<{
|
||||
icon: string,
|
||||
subtitle: string | HTMLElement | DocumentFragment,
|
||||
subtitle: K,
|
||||
subtitleLangKey: LangPackKey,
|
||||
subtitleLangArgs: any[],
|
||||
subtitleRight: K,
|
||||
radioField: Row['radioField'],
|
||||
checkboxField: Row['checkboxField'],
|
||||
checkboxFieldOptions: CheckboxFieldOptions,
|
||||
withCheckboxSubtitle: boolean,
|
||||
title: string | HTMLElement | DocumentFragment,
|
||||
title: K,
|
||||
titleLangKey: LangPackKey,
|
||||
titleRight: string | HTMLElement,
|
||||
titleRightSecondary: string | HTMLElement,
|
||||
titleRight: K,
|
||||
titleRightSecondary: K,
|
||||
clickable: boolean | ((e: Event) => void),
|
||||
navigationTab: SliderSuperTab,
|
||||
havePadding: boolean,
|
||||
|
@ -51,7 +70,8 @@ export default class Row {
|
|||
noWrap: boolean,
|
||||
listenerSetter: ListenerSetter,
|
||||
buttonRight?: HTMLElement | boolean,
|
||||
buttonRightLangKey: LangPackKey
|
||||
buttonRightLangKey: LangPackKey,
|
||||
asLink: boolean
|
||||
}> = {}) {
|
||||
if(options.checkboxFieldOptions) {
|
||||
options.checkboxField = new CheckboxField({
|
||||
|
@ -60,14 +80,28 @@ export default class Row {
|
|||
});
|
||||
}
|
||||
|
||||
this.container = document.createElement(options.radioField || options.checkboxField ? 'label' : 'div');
|
||||
const tagName = options.asLink ? 'a' : (options.radioField || options.checkboxField ? 'label' : 'div');
|
||||
this.container = document.createElement(tagName);
|
||||
this.container.classList.add('row', 'no-subtitle');
|
||||
|
||||
if(options.noWrap) {
|
||||
this.container.classList.add('no-wrap');
|
||||
}
|
||||
|
||||
if(options.subtitle) {
|
||||
if(typeof(options.subtitle) === 'string') {
|
||||
setInnerHTML(this.subtitle, options.subtitle);
|
||||
} else {
|
||||
this.subtitle.append(options.subtitle);
|
||||
const subtitle = this.subtitle;
|
||||
setContent(subtitle, options.subtitle);
|
||||
|
||||
if(options.noWrap) subtitle.classList.add('no-wrap');
|
||||
|
||||
if(options.subtitleRight) {
|
||||
this.container.append(this.subtitleRow = this.createRow());
|
||||
this.subtitleRow.classList.add('row-subtitle-row');
|
||||
const subtitleRight = this.subtitleRight = document.createElement('div');
|
||||
subtitleRight.classList.add('row-subtitle', 'row-subtitle-right');
|
||||
|
||||
setContent(subtitleRight, options.subtitleRight);
|
||||
this.subtitleRow.append(subtitle, subtitleRight);
|
||||
}
|
||||
} else if(options.subtitleLangKey) {
|
||||
this.subtitle.append(i18n(options.subtitleLangKey, options.subtitleLangArgs));
|
||||
|
@ -109,45 +143,34 @@ export default class Row {
|
|||
|
||||
if(options.title || options.titleLangKey) {
|
||||
let c: HTMLElement;
|
||||
const titleRight = options.titleRight || options.titleRightSecondary;
|
||||
if(titleRight) {
|
||||
c = document.createElement('div');
|
||||
c.classList.add('row-title-row');
|
||||
this.container.append(c);
|
||||
const titleRightContent = options.titleRight || options.titleRightSecondary;
|
||||
if(titleRightContent) {
|
||||
this.container.append(c = this.titleRow = this.createRow());
|
||||
this.titleRow.classList.add('row-title-row');
|
||||
} else {
|
||||
c = this.container;
|
||||
}
|
||||
|
||||
this.title = document.createElement('div');
|
||||
this.title.classList.add('row-title');
|
||||
this.title.setAttribute('dir', 'auto');
|
||||
this.title = this.createTitle();
|
||||
if(options.noWrap) this.title.classList.add('no-wrap');
|
||||
if(options.title) {
|
||||
if(typeof(options.title) === 'string') {
|
||||
this.title.innerHTML = options.title;
|
||||
} else {
|
||||
this.title.append(options.title);
|
||||
}
|
||||
} else {
|
||||
setContent(this.title, options.title);
|
||||
} else if(options.titleLangKey) {
|
||||
this.title.append(i18n(options.titleLangKey));
|
||||
}
|
||||
|
||||
c.append(this.title);
|
||||
|
||||
if(titleRight) {
|
||||
const titleRightEl = this.titleRight = document.createElement('div');
|
||||
titleRightEl.classList.add('row-title', 'row-title-right');
|
||||
if(titleRightContent) {
|
||||
const titleRight = this.titleRight = document.createElement('div');
|
||||
titleRight.classList.add('row-title', 'row-title-right');
|
||||
|
||||
if(options.titleRightSecondary) {
|
||||
titleRightEl.classList.add('row-title-right-secondary');
|
||||
titleRight.classList.add('row-title-right-secondary');
|
||||
}
|
||||
|
||||
if(typeof(titleRight) === 'string') {
|
||||
titleRightEl.innerHTML = titleRight;
|
||||
} else {
|
||||
titleRightEl.append(titleRight);
|
||||
}
|
||||
|
||||
c.append(titleRightEl);
|
||||
setContent(titleRight, titleRightContent);
|
||||
c.append(titleRight);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,6 +219,19 @@ export default class Row {
|
|||
return this._subtitle ?? (this._subtitle = this.createSubtitle());
|
||||
}
|
||||
|
||||
private createRow() {
|
||||
const c = document.createElement('div');
|
||||
c.classList.add('row-row');
|
||||
return c;
|
||||
}
|
||||
|
||||
private createTitle() {
|
||||
const title = document.createElement('div');
|
||||
title.classList.add('row-title');
|
||||
title.setAttribute('dir', 'auto');
|
||||
return title;
|
||||
}
|
||||
|
||||
private createSubtitle() {
|
||||
const subtitle = document.createElement('div');
|
||||
subtitle.classList.add('row-subtitle');
|
||||
|
@ -206,10 +242,15 @@ export default class Row {
|
|||
return subtitle;
|
||||
}
|
||||
|
||||
public createMedia(size?: 'small') {
|
||||
public createMedia(size?: RowMediaSizeType) {
|
||||
const media = document.createElement('div');
|
||||
return this.applyMediaElement(media, size);
|
||||
}
|
||||
|
||||
public applyMediaElement(media: HTMLElement, size?: RowMediaSizeType) {
|
||||
this.container.classList.add('row-with-padding');
|
||||
|
||||
const media = this.media = document.createElement('div');
|
||||
this.media = media;
|
||||
media.classList.add('row-media');
|
||||
|
||||
if(size) {
|
||||
|
|
|
@ -59,7 +59,8 @@ export default class AppAddMembersTab extends SliderSuperTab {
|
|||
placeholder: options.placeholder,
|
||||
exceptSelf: isPrivacy,
|
||||
filterPeerTypeBy: isPrivacy ? ['isAnyGroup', 'isUser'] : undefined,
|
||||
managers: this.managers
|
||||
managers: this.managers,
|
||||
design: 'square'
|
||||
});
|
||||
|
||||
if(options.selectedPeerIds) {
|
||||
|
|
|
@ -59,7 +59,7 @@ export default class AppBlockedUsersTab extends SliderSuperTab {
|
|||
peerId: peerId,
|
||||
container: list,
|
||||
rippleEnabled: true,
|
||||
avatarSize: 48,
|
||||
avatarSize: 'abitbigger',
|
||||
append
|
||||
});
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ export default class AppContactsTab extends SliderSuperTab {
|
|||
protected onClose() {
|
||||
this.middleware.clean();
|
||||
/* // need to clear, and left 1 page for smooth slide
|
||||
let pageCount = appPhotosManager.windowH / 72 * 1.25 | 0;
|
||||
let pageCount = appPhotosManager.windowH / 56 * 1.25 | 0;
|
||||
(Array.from(this.list.children) as HTMLElement[]).slice(pageCount).forEach((el) => el.remove()); */
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ export default class AppContactsTab extends SliderSuperTab {
|
|||
const sortedUserList = this.sortedUserList = this.createList();
|
||||
|
||||
let renderPage = () => {
|
||||
const pageCount = windowSize.height / 72 * 1.25 | 0;
|
||||
const pageCount = windowSize.height / 56 * 1.25 | 0;
|
||||
const arr = contacts.splice(0, pageCount); // надо splice!
|
||||
|
||||
arr.forEach((peerId) => {
|
||||
|
|
|
@ -317,7 +317,7 @@ export default class AppEditFolderTab extends SliderSuperTab {
|
|||
container: ul,
|
||||
rippleEnabled: false,
|
||||
meAsSaved: true,
|
||||
avatarSize: 32
|
||||
avatarSize: 'small'
|
||||
});
|
||||
dom.lastMessageSpan.parentElement.remove();
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import {i18n, i18n_} from '../../../lib/langPack';
|
|||
import {attachClickEvent} from '../../../helpers/dom/clickEvent';
|
||||
import rootScope from '../../../lib/rootScope';
|
||||
import {generateSection, SettingSection} from '..';
|
||||
import anchorCopy from '../../../helpers/dom/anchorCopy';
|
||||
|
||||
// TODO: аватарка не поменяется в этой вкладке после изменения почему-то (если поставить в другом клиенте, и потом тут проверить, для этого ещё вышел в чатлист)
|
||||
|
||||
|
@ -114,10 +115,7 @@ export default class AppEditProfileTab extends SliderSuperTab {
|
|||
const profileUrlContainer = this.profileUrlContainer = document.createElement('div');
|
||||
profileUrlContainer.classList.add('profile-url-container');
|
||||
|
||||
const profileUrlAnchor = this.profileUrlAnchor = document.createElement('a');
|
||||
profileUrlAnchor.classList.add('profile-url');
|
||||
profileUrlAnchor.href = '#';
|
||||
profileUrlAnchor.target = '_blank';
|
||||
const profileUrlAnchor = this.profileUrlAnchor = anchorCopy();
|
||||
|
||||
profileUrlContainer.append(i18n('UsernameHelpLink', [profileUrlAnchor]));
|
||||
|
||||
|
@ -173,9 +171,7 @@ export default class AppEditProfileTab extends SliderSuperTab {
|
|||
this.profileUrlContainer.style.display = 'none';
|
||||
} else {
|
||||
this.profileUrlContainer.style.display = '';
|
||||
const url = 'https://t.me/' + this.usernameInputField.value;
|
||||
this.profileUrlAnchor.innerText = url;
|
||||
this.profileUrlAnchor.href = url;
|
||||
this.profileUrlAnchor.replaceWith(this.profileUrlAnchor = anchorCopy({mePath: this.usernameInputField.value}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -163,7 +163,7 @@ export default class AppIncludedChatsTab extends SliderSuperTab {
|
|||
peerId: peerId,
|
||||
container: this.selector.scrollable,
|
||||
rippleEnabled: true,
|
||||
avatarSize: 46
|
||||
avatarSize: 'abitbigger'
|
||||
});
|
||||
|
||||
const selected = this.selector.selected.has(peerId);
|
||||
|
|
|
@ -166,7 +166,7 @@ export default class AppNewGroupTab extends SliderSuperTab {
|
|||
peerId: userId,
|
||||
container: this.list,
|
||||
rippleEnabled: false,
|
||||
avatarSize: 48
|
||||
avatarSize: 'abitbigger'
|
||||
});
|
||||
|
||||
dom.lastMessageSpan.append(getUserStatusString(await this.managers.appUsersManager.getUser(userId)));
|
||||
|
|
|
@ -52,7 +52,7 @@ export class AppSidebarRight extends SidebarSlider {
|
|||
const idx = this.historyTabIds.indexOf(previousTab);
|
||||
|
||||
if(this._selectTab.getFrom() === previousTab.container) {
|
||||
this._selectTab.setFrom(tab.container);
|
||||
this._selectTab.setFrom(tab?.container);
|
||||
}
|
||||
|
||||
if(tab) {
|
||||
|
|
|
@ -264,7 +264,7 @@ export default class AppGroupPermissionsTab extends SliderSuperTabEventable {
|
|||
peerId: getPeerId(participant.peer),
|
||||
container: list,
|
||||
rippleEnabled: true,
|
||||
avatarSize: 48,
|
||||
avatarSize: 'abitbigger',
|
||||
append
|
||||
});
|
||||
|
||||
|
|
|
@ -8,15 +8,16 @@ import {SliderSuperTab} from '../../slider';
|
|||
import appSidebarRight from '..';
|
||||
import {roundPercents} from '../../poll';
|
||||
import appDialogsManager from '../../../lib/appManagers/appDialogsManager';
|
||||
import ripple from '../../ripple';
|
||||
import {i18n} from '../../../lib/langPack';
|
||||
import setInnerHTML from '../../../helpers/dom/setInnerHTML';
|
||||
import wrapEmojiText from '../../../lib/richTextProcessor/wrapEmojiText';
|
||||
import Button from '../../button';
|
||||
import {Message, MessageMedia} from '../../../layer';
|
||||
|
||||
export default class AppPollResultsTab extends SliderSuperTab {
|
||||
private resultsDiv: HTMLElement;
|
||||
|
||||
public async init(message: any) {
|
||||
public async init(message: Message.message) {
|
||||
this.container.id = 'poll-results-container';
|
||||
this.container.classList.add('chatlist-container');
|
||||
|
||||
|
@ -24,7 +25,7 @@ export default class AppPollResultsTab extends SliderSuperTab {
|
|||
this.resultsDiv.classList.add('poll-results');
|
||||
this.scrollable.append(this.resultsDiv);
|
||||
|
||||
const poll = await this.managers.appPollsManager.getPoll(message.media.poll.id);
|
||||
const poll = await this.managers.appPollsManager.getPoll((message.media as MessageMedia.messageMediaPoll).poll.id);
|
||||
|
||||
this.setTitle(poll.poll.pFlags.quiz ? 'PollResults.Title.Quiz' : 'PollResults.Title.Poll');
|
||||
|
||||
|
@ -62,11 +63,11 @@ export default class AppPollResultsTab extends SliderSuperTab {
|
|||
appSidebarRight.onCloseBtnClick();
|
||||
}, undefined, true);
|
||||
|
||||
list.style.minHeight = Math.min(result.voters, 4) * 50 + 'px';
|
||||
list.style.minHeight = Math.min(result.voters, 4) * 48 + 'px';
|
||||
|
||||
fragment.append(hr, answerEl, list);
|
||||
|
||||
let offset: string, limit = 4, loading = false, left = result.voters - 4;
|
||||
let offset: string, limit = 4, loading = false, left = Math.max(0, result.voters - 4);
|
||||
const load = () => {
|
||||
if(loading) return;
|
||||
loading = true;
|
||||
|
@ -78,14 +79,17 @@ export default class AppPollResultsTab extends SliderSuperTab {
|
|||
container: list,
|
||||
rippleEnabled: false,
|
||||
meAsSaved: false,
|
||||
avatarSize: 32
|
||||
avatarSize: 'small'
|
||||
});
|
||||
dom.lastMessageSpan.parentElement.remove();
|
||||
});
|
||||
|
||||
if(offset) {
|
||||
left -= votesList.votes.length;
|
||||
(showMore.lastElementChild as HTMLElement).replaceWith(i18n('PollResults.LoadMore', [Math.min(20, left)]));
|
||||
left = Math.max(0, left - votesList.votes.length);
|
||||
|
||||
if(left) {
|
||||
(showMore.lastElementChild as HTMLElement).replaceWith(i18n('PollResults.LoadMore', [Math.min(20, left)]));
|
||||
}
|
||||
}
|
||||
|
||||
offset = votesList.next_offset;
|
||||
|
@ -99,19 +103,13 @@ export default class AppPollResultsTab extends SliderSuperTab {
|
|||
});
|
||||
};
|
||||
|
||||
load();
|
||||
|
||||
if(left <= 0) return;
|
||||
|
||||
const showMore = document.createElement('div');
|
||||
showMore.classList.add('poll-results-more', 'show-more', 'rp-overflow');
|
||||
const showMore = Button('poll-results-more btn btn-primary btn-transparent', {icon: 'down'});
|
||||
showMore.addEventListener('click', load);
|
||||
ripple(showMore);
|
||||
const down = document.createElement('div');
|
||||
down.classList.add('tgico-down');
|
||||
showMore.append(down, i18n('PollResults.LoadMore', [Math.min(20, left)]));
|
||||
showMore.append(i18n('PollResults.LoadMore', [Math.min(20, left)]));
|
||||
|
||||
fragment.append(showMore);
|
||||
|
||||
load();
|
||||
});
|
||||
|
||||
this.resultsDiv.append(title, fragment);
|
||||
|
|
|
@ -42,7 +42,7 @@ export default class AppUserPermissionsTab extends SliderSuperTabEventable {
|
|||
peerId: this.userId.toPeerId(false),
|
||||
container: list,
|
||||
rippleEnabled: true,
|
||||
avatarSize: 48
|
||||
avatarSize: 'abitbigger'
|
||||
});
|
||||
|
||||
dom.lastMessageSpan.append(getUserStatusString(await this.managers.appUsersManager.getUser(this.userId)));
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
import appDialogsManager, {AppDialogsManager, DialogDom} from '../lib/appManagers/appDialogsManager';
|
||||
import appDialogsManager, {AppDialogsManager, DialogDom, DialogElementSize} from '../lib/appManagers/appDialogsManager';
|
||||
import {getHeavyAnimationPromise} from '../hooks/useHeavyAnimationCheck';
|
||||
import isInDOM from '../helpers/dom/isInDOM';
|
||||
import positionElementByIndex from '../helpers/dom/positionElementByIndex';
|
||||
|
@ -25,7 +25,7 @@ export default class SortedUserList extends SortedList<SortedUser> {
|
|||
public list: HTMLUListElement;
|
||||
|
||||
protected lazyLoadQueue: LazyLoadQueue;
|
||||
protected avatarSize = 48;
|
||||
protected avatarSize: DialogElementSize = 'abitbigger';
|
||||
protected rippleEnabled = true;
|
||||
protected autonomous = true;
|
||||
protected createChatListOptions: Parameters<AppDialogsManager['createChatList']>[0];
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import indexOfAndSplice from '../../helpers/array/indexOfAndSplice';
|
||||
import {formatTime} from '../../helpers/date';
|
||||
import {formatTime, ONE_DAY} from '../../helpers/date';
|
||||
import htmlToSpan from '../../helpers/dom/htmlToSpan';
|
||||
import setInnerHTML from '../../helpers/dom/setInnerHTML';
|
||||
import formatCallDuration from '../../helpers/formatCallDuration';
|
||||
|
@ -18,16 +18,21 @@ import wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';
|
|||
import wrapPlainText from '../../lib/richTextProcessor/wrapPlainText';
|
||||
import wrapRichText from '../../lib/richTextProcessor/wrapRichText';
|
||||
import rootScope from '../../lib/rootScope';
|
||||
import PeerTitle from '../peerTitle';
|
||||
import getPeerTitle from './getPeerTitle';
|
||||
import wrapJoinVoiceChatAnchor from './joinVoiceChatAnchor';
|
||||
import wrapMessageForReply from './messageForReply';
|
||||
import wrapPeerTitle from './peerTitle';
|
||||
|
||||
async function wrapLinkToMessage(message: Message.message | Message.messageService, plain?: boolean) {
|
||||
const wrapped = await wrapMessageForReply(message, undefined, undefined, plain as any);
|
||||
if(plain) {
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
const a = document.createElement('i');
|
||||
a.dataset.savedFrom = message.peerId + '_' + message.mid;
|
||||
a.dir = 'auto';
|
||||
a.append(await wrapMessageForReply(message, undefined, undefined, plain as any));
|
||||
a.append(wrapped);
|
||||
return a;
|
||||
}
|
||||
|
||||
|
@ -53,8 +58,8 @@ export default async function wrapMessageActionTextNewUnsafe(message: MyMessage,
|
|||
|
||||
const managers = rootScope.managers;
|
||||
|
||||
const getNameDivHTML = async(peerId: PeerId, plain: boolean) => {
|
||||
return plain ? getPeerTitle(peerId, plain) : (new PeerTitle({peerId})).element;
|
||||
const getNameDivHTML = (peerId: PeerId, plain: boolean) => {
|
||||
return plain ? getPeerTitle(peerId, plain) : wrapPeerTitle({peerId});
|
||||
};
|
||||
|
||||
switch(action._) {
|
||||
|
@ -268,7 +273,10 @@ export default async function wrapMessageActionTextNewUnsafe(message: MyMessage,
|
|||
} else {
|
||||
langPackKey = isRecurringUsed ? 'Chat.Service.PaymentSentRecurringUsed' : (isRecurringInit ? 'Chat.Service.PaymentSentRecurringInit' : 'Chat.Service.PaymentSent1');
|
||||
args.push(wrapLinkToMessage(invoiceMessage, plain).then((el) => {
|
||||
el.classList.add('is-receipt-link');
|
||||
if(el instanceof HTMLElement) {
|
||||
el.classList.add('is-receipt-link');
|
||||
}
|
||||
|
||||
return el;
|
||||
}));
|
||||
}
|
||||
|
@ -277,6 +285,52 @@ export default async function wrapMessageActionTextNewUnsafe(message: MyMessage,
|
|||
break;
|
||||
}
|
||||
|
||||
case 'messageActionSetMessagesTTL': {
|
||||
args = [];
|
||||
|
||||
const isBroadcast = await managers.appPeersManager.isBroadcast(message.peerId);
|
||||
if(action.period) {
|
||||
if(isBroadcast) {
|
||||
langPackKey = 'ActionTTLChannelChanged';
|
||||
} else if(message.fromId === rootScope.myId) {
|
||||
langPackKey = 'ActionTTLYouChanged';
|
||||
} else {
|
||||
langPackKey = 'ActionTTLChanged';
|
||||
args.push(getNameDivHTML(message.fromId, plain));
|
||||
}
|
||||
|
||||
let duration: ReturnType<typeof formatCallDuration>;
|
||||
if(action.period > 1814400) {
|
||||
let key: LangPackKey;
|
||||
const args: FormatterArguments = [];
|
||||
const year = 31536000;
|
||||
if(action.period >= year) {
|
||||
key = 'Years';
|
||||
args.push(action.period / year | 0);
|
||||
} else {
|
||||
key = 'Months';
|
||||
args.push(action.period / (ONE_DAY * 30) | 0);
|
||||
}
|
||||
|
||||
duration = plain ? I18n.format(key, true, args) : i18n(key, args);
|
||||
} else {
|
||||
duration = formatCallDuration(action.period, plain);
|
||||
}
|
||||
|
||||
args.push(duration);
|
||||
} else {
|
||||
if(isBroadcast) {
|
||||
langPackKey = 'ActionTTLChannelDisabled';
|
||||
} else if(message.fromId === rootScope.myId) {
|
||||
langPackKey = 'ActionTTLYouDisabled';
|
||||
} else {
|
||||
langPackKey = 'ActionTTLDisabled';
|
||||
args.push(getNameDivHTML(message.fromId, plain));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
langPackKey = (langPack[_] || `[${action._}]`) as any;
|
||||
break;
|
||||
|
|
|
@ -40,7 +40,7 @@ export default async function wrapMessageForReply(message: MyMessage | MyDraftMe
|
|||
if(plain) {
|
||||
parts.push(part);
|
||||
} else {
|
||||
const el = document.createElement('i');
|
||||
const el = document.createElement('span');
|
||||
if(typeof(part) === 'string') el.innerHTML = part;
|
||||
else el.append(part);
|
||||
parts.push(el);
|
||||
|
|
|
@ -704,14 +704,48 @@ export async function onEmojiStickerClick({event, container, managers, peerId, m
|
|||
peerId: PeerId,
|
||||
middleware: Middleware
|
||||
}) {
|
||||
if(!peerId.isUser()) {
|
||||
return;
|
||||
}
|
||||
|
||||
cancelEvent(event);
|
||||
|
||||
const bubble = findUpClassName(container, 'bubble');
|
||||
const emoji = container.dataset.stickerEmoji;
|
||||
|
||||
const animation = !container.classList.contains('custom-emoji') ? lottieLoader.getAnimation(container) : undefined;
|
||||
if(animation?.paused) {
|
||||
const doc = await managers.appStickersManager.getAnimatedEmojiSoundDocument(emoji);
|
||||
if(doc) {
|
||||
const audio = document.createElement('audio');
|
||||
audio.style.display = 'none';
|
||||
container.parentElement.append(audio);
|
||||
|
||||
try {
|
||||
const url = await appDownloadManager.downloadMediaURL({media: doc});
|
||||
|
||||
audio.src = url;
|
||||
audio.play();
|
||||
await onMediaLoad(audio, undefined, true);
|
||||
|
||||
audio.addEventListener('ended', () => {
|
||||
audio.src = '';
|
||||
audio.remove();
|
||||
}, {once: true});
|
||||
} catch(err) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
animation.autoplay = true;
|
||||
animation.restart();
|
||||
}
|
||||
|
||||
if(!peerId.isUser()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const doc = await managers.appStickersManager.getAnimatedEmojiSticker(emoji, true);
|
||||
if(!doc) {
|
||||
return;
|
||||
}
|
||||
|
||||
const data: SendMessageEmojiInteractionData = (container as any).emojiData ??= {
|
||||
a: [],
|
||||
v: 1
|
||||
|
@ -743,39 +777,6 @@ export async function onEmojiStickerClick({event, container, managers, peerId, m
|
|||
data.a.length = 0;
|
||||
}, 1000, false);
|
||||
|
||||
const animation = !container.classList.contains('custom-emoji') ? lottieLoader.getAnimation(container) : undefined;
|
||||
if(animation?.paused) {
|
||||
const doc = await managers.appStickersManager.getAnimatedEmojiSoundDocument(emoji);
|
||||
if(doc) {
|
||||
const audio = document.createElement('audio');
|
||||
audio.style.display = 'none';
|
||||
container.parentElement.append(audio);
|
||||
|
||||
try {
|
||||
const url = await appDownloadManager.downloadMediaURL({media: doc});
|
||||
|
||||
audio.src = url;
|
||||
audio.play();
|
||||
await onMediaLoad(audio, undefined, true);
|
||||
|
||||
audio.addEventListener('ended', () => {
|
||||
audio.src = '';
|
||||
audio.remove();
|
||||
}, {once: true});
|
||||
} catch(err) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
animation.autoplay = true;
|
||||
animation.restart();
|
||||
}
|
||||
|
||||
const doc = await managers.appStickersManager.getAnimatedEmojiSticker(emoji, true);
|
||||
if(!doc) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isOut = bubble ? bubble.classList.contains('is-out') : undefined;
|
||||
const {animationDiv} = wrapStickerAnimation({
|
||||
doc,
|
||||
|
|
|
@ -24,7 +24,9 @@ export default class SuperIntersectionObserver {
|
|||
const entry = entries[i];
|
||||
const callbacks = observing.get(entry.target);
|
||||
if(!callbacks) {
|
||||
console.error('intersection process no callbacks:', entry);
|
||||
debugger;
|
||||
continue;
|
||||
}
|
||||
|
||||
for(const callback of callbacks) {
|
||||
|
|
|
@ -12,7 +12,9 @@ const CALL_DURATION_LANG_KEYS: {[type in DurationType]: LangPackKey} = {
|
|||
m: 'Minutes',
|
||||
h: 'Hours',
|
||||
d: 'Days',
|
||||
w: 'Weeks'
|
||||
w: 'Weeks',
|
||||
mm: 'Months',
|
||||
y: 'Years'
|
||||
};
|
||||
export default function formatCallDuration(duration: number, plain?: boolean) {
|
||||
const a = formatDuration(duration, 2);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
export type DurationType = 's' | 'm' | 'h' | 'd' | 'w';
|
||||
export type DurationType = 's' | 'm' | 'h' | 'd' | 'w' | 'mm' | 'y';
|
||||
export default function formatDuration(duration: number, showLast = 2) {
|
||||
if(!duration) {
|
||||
duration = 1;
|
||||
|
@ -21,7 +21,7 @@ export default function formatDuration(duration: number, showLast = 2) {
|
|||
const s = 1;
|
||||
let t = s;
|
||||
p.forEach((o, idx) => {
|
||||
t *= o.m;
|
||||
t = Math.round(t * o.m);
|
||||
|
||||
if(duration < t) {
|
||||
return;
|
||||
|
|
14
src/lang.ts
14
src/lang.ts
|
@ -504,6 +504,14 @@ const lang = {
|
|||
'one_value': '%1$d week',
|
||||
'other_value': '%1$d weeks'
|
||||
},
|
||||
'Months': {
|
||||
'one_value': '%1$d month',
|
||||
'other_value': '%1$d months'
|
||||
},
|
||||
'Years': {
|
||||
'one_value': '%1$d year',
|
||||
'other_value': '%1$d years'
|
||||
},
|
||||
'TodayAtFormattedWithToday': 'today at %1$s',
|
||||
'formatDateAtTime': '%1$s at %2$s',
|
||||
'JoinByPeekChannelTitle': 'Join Channel',
|
||||
|
@ -791,6 +799,12 @@ const lang = {
|
|||
'IncreaseLimit': 'Increase Limit',
|
||||
'LimitFree': 'Free',
|
||||
'LimitPremium': 'Premium',
|
||||
'ActionTTLChanged': 'un1 set messages to auto-delete in %1$s',
|
||||
'ActionTTLYouChanged': 'You set messages to auto-delete in %1$s',
|
||||
'ActionTTLChannelChanged': 'Messages in this channel will be automatically deleted after %1$s',
|
||||
'ActionTTLChannelDisabled': 'Messages in this channel will no longer be automatically deleted',
|
||||
'ActionTTLDisabled': 'un1 disabled the auto-delete timer',
|
||||
'ActionTTLYouDisabled': 'You disabled the auto-delete timer',
|
||||
|
||||
// * macos
|
||||
'AccountSettings.Filters': 'Chat Folders',
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
import deepEqual from '../../helpers/object/deepEqual';
|
||||
import isObject from '../../helpers/object/isObject';
|
||||
import safeReplaceObject from '../../helpers/object/safeReplaceObject';
|
||||
import {ChannelParticipant, ChannelsCreateChannel, Chat, ChatAdminRights, ChatBannedRights, ChatInvite, ChatPhoto, ChatReactions, InputChannel, InputChatPhoto, InputFile, InputPeer, SponsoredMessage, Update, Updates} from '../../layer';
|
||||
import {ChannelParticipant, ChannelsCreateChannel, Chat, ChatAdminRights, ChatBannedRights, ChatInvite, ChatPhoto, ChatReactions, InputChannel, InputChatPhoto, InputFile, InputPeer, MessagesSponsoredMessages, SponsoredMessage, Update, Updates} from '../../layer';
|
||||
import {isRestricted} from '../../helpers/restrictions';
|
||||
import {AppManager} from './manager';
|
||||
import hasRights from './utils/chats/hasRights';
|
||||
|
@ -694,9 +694,93 @@ export class AppChatsManager extends AppManager {
|
|||
}
|
||||
|
||||
public getSponsoredMessage(chatId: ChatId) {
|
||||
return this.apiManager.invokeApiCacheable('channels.getSponsoredMessages', {
|
||||
// const s: MessagesSponsoredMessages.messagesSponsoredMessages = {
|
||||
// '_': 'messages.sponsoredMessages',
|
||||
// 'messages': [
|
||||
// {
|
||||
// '_': 'sponsoredMessage',
|
||||
// 'pFlags': {},
|
||||
// 'flags': 9,
|
||||
// 'random_id': new Uint8Array([
|
||||
// 80,
|
||||
// 5,
|
||||
// 249,
|
||||
// 174,
|
||||
// 44,
|
||||
// 73,
|
||||
// 173,
|
||||
// 14,
|
||||
// 246,
|
||||
// 81,
|
||||
// 187,
|
||||
// 182,
|
||||
// 223,
|
||||
// 5,
|
||||
// 4,
|
||||
// 128
|
||||
// ]),
|
||||
// 'from_id': {
|
||||
// '_': 'peerUser',
|
||||
// 'user_id': 983000232
|
||||
// },
|
||||
// 'start_param': 'GreatMinds',
|
||||
// 'message': 'This is a long sponsored message. In fact, it has the maximum length allowed on the platform – 160 characters 😬😬. It\'s promoting a bot with a start parameter.' + chatId
|
||||
// }
|
||||
// ],
|
||||
// 'chats': [],
|
||||
// 'users': [
|
||||
// {
|
||||
// '_': 'user',
|
||||
// 'pFlags': {
|
||||
// 'bot': true,
|
||||
// 'verified': true,
|
||||
// 'apply_min_photo': true
|
||||
// },
|
||||
// 'flags': 34226219,
|
||||
// 'id': 983000232,
|
||||
// 'access_hash': '-294959558742535650',
|
||||
// 'first_name': 'Quiz Bot',
|
||||
// 'username': 'QuizBot',
|
||||
// 'photo': {
|
||||
// '_': 'userProfilePhoto',
|
||||
// 'pFlags': {},
|
||||
// 'flags': 2,
|
||||
// 'photo_id': '4221953848856651689',
|
||||
// 'stripped_thumb': new Uint8Array([
|
||||
// 1,
|
||||
// 8,
|
||||
// 8,
|
||||
// 155,
|
||||
// 247,
|
||||
// 95,
|
||||
// 103,
|
||||
// 255,
|
||||
// 0,
|
||||
// 110,
|
||||
// 138,
|
||||
// 40,
|
||||
// 174,
|
||||
// 132,
|
||||
// 142,
|
||||
// 6,
|
||||
// 238,
|
||||
// 127
|
||||
// ]),
|
||||
// 'dc_id': 2
|
||||
// },
|
||||
// 'bot_info_version': 11,
|
||||
// 'bot_inline_placeholder': 'Search a quiz...',
|
||||
// 'sortName': 'quiz bot'
|
||||
// }
|
||||
// ]
|
||||
// };
|
||||
|
||||
// const promise = Promise.resolve(s);
|
||||
const promise = this.apiManager.invokeApiCacheable('channels.getSponsoredMessages', {
|
||||
channel: this.getChannelInput(chatId)
|
||||
}, {cacheSeconds: 300}).then((sponsoredMessages) => {
|
||||
}, {cacheSeconds: 300});
|
||||
|
||||
return promise.then((sponsoredMessages) => {
|
||||
this.appUsersManager.saveApiUsers(sponsoredMessages.users);
|
||||
this.appChatsManager.saveApiChats(sponsoredMessages.chats);
|
||||
|
||||
|
|
|
@ -86,12 +86,13 @@ import whichChild from '../../helpers/dom/whichChild';
|
|||
import {MiddlewareHelper} from '../../helpers/middleware';
|
||||
import makeError from '../../helpers/makeError';
|
||||
import getUnsafeRandomInt from '../../helpers/number/getUnsafeRandomInt';
|
||||
import Row, {RowMediaSizeType} from '../../components/row'
|
||||
|
||||
export const DIALOG_LIST_ELEMENT_TAG = 'A';
|
||||
|
||||
export type DialogDom = {
|
||||
avatarEl: AvatarElement,
|
||||
captionDiv: HTMLDivElement,
|
||||
captionDiv: HTMLElement,
|
||||
titleSpan: HTMLSpanElement,
|
||||
titleSpanContainer: HTMLSpanElement,
|
||||
statusSpan: HTMLSpanElement,
|
||||
|
@ -128,6 +129,8 @@ function setPromiseMiddleware<T extends {[smth in K as K]?: CancellablePromise<v
|
|||
return {deferred, middleware};
|
||||
}
|
||||
|
||||
const BADGE_SIZE = 22;
|
||||
|
||||
class SortedDialogList extends SortedList<SortedDialog> {
|
||||
constructor(
|
||||
public managers: AppManagers,
|
||||
|
@ -170,6 +173,151 @@ class SortedDialogList extends SortedList<SortedDialog> {
|
|||
}
|
||||
}
|
||||
|
||||
export type DialogElementSize = RowMediaSizeType;
|
||||
class DialogElement extends Row {
|
||||
public dom: DialogDom;
|
||||
|
||||
constructor({
|
||||
peerId,
|
||||
rippleEnabled = true,
|
||||
onlyFirstName = false,
|
||||
meAsSaved = true,
|
||||
avatarSize = 'bigger',
|
||||
autonomous,
|
||||
lazyLoadQueue,
|
||||
loadPromises,
|
||||
fromName,
|
||||
noIcons
|
||||
}: {
|
||||
peerId: PeerId,
|
||||
rippleEnabled?: boolean,
|
||||
onlyFirstName?: boolean,
|
||||
meAsSaved?: boolean,
|
||||
avatarSize?: RowMediaSizeType,
|
||||
autonomous?: boolean,
|
||||
lazyLoadQueue?: LazyLoadQueue,
|
||||
loadPromises?: Promise<any>[],
|
||||
fromName?: string,
|
||||
noIcons?: boolean
|
||||
}) {
|
||||
super({
|
||||
clickable: true,
|
||||
noRipple: !rippleEnabled,
|
||||
havePadding: true,
|
||||
title: true,
|
||||
titleRightSecondary: true,
|
||||
subtitle: true,
|
||||
subtitleRight: true,
|
||||
noWrap: true,
|
||||
asLink: true
|
||||
});
|
||||
|
||||
const avatarEl = new AvatarElement();
|
||||
const avatarSizeMap: {[k in DialogElementSize]?: number} = {
|
||||
bigger: 54,
|
||||
abitbigger: 42,
|
||||
small: 32
|
||||
};
|
||||
const s = avatarSizeMap[avatarSize];
|
||||
avatarEl.classList.add('dialog-avatar', 'avatar-' + s);
|
||||
avatarEl.updateWithOptions({
|
||||
loadPromises,
|
||||
lazyLoadQueue,
|
||||
isDialog: !!meAsSaved,
|
||||
peerId,
|
||||
peerTitle: fromName
|
||||
});
|
||||
|
||||
const captionDiv = this.container;
|
||||
|
||||
const titleSpanContainer = this.title;
|
||||
titleSpanContainer.classList.add('user-title');
|
||||
|
||||
this.titleRow.classList.add('dialog-title');
|
||||
|
||||
const peerTitle = new PeerTitle();
|
||||
const peerTitlePromise = peerTitle.update({
|
||||
peerId,
|
||||
fromName,
|
||||
dialog: meAsSaved,
|
||||
onlyFirstName,
|
||||
plainText: false,
|
||||
withIcons: !noIcons
|
||||
});
|
||||
|
||||
loadPromises?.push(peerTitlePromise);
|
||||
titleSpanContainer.append(peerTitle.element);
|
||||
|
||||
// for muted icon
|
||||
titleSpanContainer.classList.add('tgico'); // * эта строка будет актуальна только для !container, но ладно
|
||||
|
||||
// const titleIconsPromise = generateTitleIcons(peerId).then((elements) => {
|
||||
// titleSpanContainer.append(...elements);
|
||||
// });
|
||||
|
||||
// if(loadPromises) {
|
||||
// loadPromises.push(titleIconsPromise);
|
||||
// }
|
||||
// }
|
||||
|
||||
const span = this.subtitle;
|
||||
// span.classList.add('user-last-message');
|
||||
|
||||
const li = this.container;
|
||||
li.classList.add('chatlist-chat', 'chatlist-chat-' + avatarSize);
|
||||
if(!autonomous) (li as HTMLAnchorElement).href = '#' + peerId;
|
||||
// if(rippleEnabled) {
|
||||
// ripple(li);
|
||||
// }
|
||||
|
||||
if(avatarSize === 'bigger') {
|
||||
this.container.classList.add('row-big');
|
||||
} else if(avatarSize === 'small') {
|
||||
this.container.classList.add('row-small');
|
||||
}
|
||||
|
||||
this.applyMediaElement(avatarEl, avatarSize);
|
||||
li.dataset.peerId = '' + peerId;
|
||||
|
||||
const statusSpan = document.createElement('span');
|
||||
statusSpan.classList.add('message-status', 'sending-status'/* , 'transition', 'reveal' */);
|
||||
|
||||
const lastTimeSpan = document.createElement('span');
|
||||
lastTimeSpan.classList.add('message-time');
|
||||
|
||||
const unreadBadge = document.createElement('div');
|
||||
unreadBadge.className = 'dialog-subtitle-badge badge badge-' + BADGE_SIZE;
|
||||
|
||||
const rightSpan = this.titleRight;
|
||||
rightSpan.classList.add('dialog-title-details');
|
||||
rightSpan.append(statusSpan, lastTimeSpan);
|
||||
|
||||
this.subtitleRow.classList.add('dialog-subtitle');
|
||||
|
||||
const dom: DialogDom = this.dom = {
|
||||
avatarEl,
|
||||
captionDiv,
|
||||
titleSpan: peerTitle.element,
|
||||
titleSpanContainer,
|
||||
statusSpan,
|
||||
lastTimeSpan,
|
||||
unreadBadge,
|
||||
lastMessageSpan: span,
|
||||
containerEl: li,
|
||||
listEl: li,
|
||||
subtitleEl: this.subtitleRow
|
||||
};
|
||||
|
||||
if(!autonomous) {
|
||||
(li as any).dialogDom = dom;
|
||||
|
||||
if(appImManager.chat?.peerId === peerId) {
|
||||
appDialogsManager.setDialogActive(li, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// const testScroll = false;
|
||||
// let testTopSlice = 1;
|
||||
|
||||
|
@ -316,6 +464,7 @@ export class AppDialogsManager {
|
|||
// setTimeout(() =>
|
||||
apiManagerProxy.getState().then(async(state) => {
|
||||
this.loadedDialogsAtLeastOnce = false;
|
||||
this.showFiltersPromise = undefined;
|
||||
|
||||
/* const clearPromises: Promise<any>[] = [];
|
||||
for(const name in this.managers.appStateManager.storagesResults) {
|
||||
|
@ -659,9 +808,8 @@ export class AppDialogsManager {
|
|||
});
|
||||
}
|
||||
|
||||
private setDialogActive(listEl: HTMLElement, active: boolean) {
|
||||
// @ts-ignore
|
||||
const dom = listEl.dialogDom as DialogDom;
|
||||
public setDialogActive(listEl: HTMLElement, active: boolean) {
|
||||
const dom = (listEl as any).dialogDom as DialogDom;
|
||||
listEl.classList.toggle('active', active);
|
||||
if(active) {
|
||||
this.lastActiveElements.add(listEl);
|
||||
|
@ -955,31 +1103,29 @@ export class AppDialogsManager {
|
|||
}
|
||||
|
||||
private onFiltersLengthChange() {
|
||||
if(!this.showFiltersPromise) {
|
||||
this.showFiltersPromise = new Promise<void>((resolve) => {
|
||||
window.setTimeout(() => {
|
||||
const length = Object.keys(this.filtersRendered).length;
|
||||
const show = length > 1;
|
||||
const wasShowing = !this.folders.menuScrollContainer.classList.contains('hide');
|
||||
let promise = this.showFiltersPromise;
|
||||
return promise ??= this.showFiltersPromise = pause(0).then(() => {
|
||||
if(this.showFiltersPromise !== promise) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(show !== wasShowing) {
|
||||
this.folders.menuScrollContainer.classList.toggle('hide', !show);
|
||||
if(show && !wasShowing) {
|
||||
this.setFiltersUnreadCount();
|
||||
}
|
||||
const length = Object.keys(this.filtersRendered).length;
|
||||
const show = length > 1;
|
||||
const wasShowing = !this.folders.menuScrollContainer.classList.contains('hide');
|
||||
|
||||
this.chatsContainer.classList.toggle('has-filters', show);
|
||||
}
|
||||
if(show !== wasShowing) {
|
||||
this.folders.menuScrollContainer.classList.toggle('hide', !show);
|
||||
if(show && !wasShowing) {
|
||||
this.setFiltersUnreadCount();
|
||||
}
|
||||
|
||||
this.changeFiltersAllChatsKey();
|
||||
this.chatsContainer.classList.toggle('has-filters', show);
|
||||
}
|
||||
|
||||
this.showFiltersPromise = undefined;
|
||||
resolve();
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
this.changeFiltersAllChatsKey();
|
||||
|
||||
return this.showFiltersPromise;
|
||||
this.showFiltersPromise = undefined;
|
||||
});
|
||||
}
|
||||
|
||||
private loadDialogs(side: SliceSides) {
|
||||
|
@ -1341,7 +1487,7 @@ export class AppDialogsManager {
|
|||
};
|
||||
|
||||
const sortedUserList = new SortedUserList({
|
||||
avatarSize: 42,
|
||||
avatarSize: 'abitbigger',
|
||||
createChatListOptions: {
|
||||
dialogSize: 48,
|
||||
new: true
|
||||
|
@ -1737,30 +1883,31 @@ export class AppDialogsManager {
|
|||
|
||||
/* if(lastMessage.from_id === auth.id) { // You: */
|
||||
if(draftMessage) {
|
||||
const bold = document.createElement('b');
|
||||
bold.classList.add('danger');
|
||||
bold.append(i18n('Draft'), ': ');
|
||||
willPrepend.unshift(bold);
|
||||
const span = document.createElement('span');
|
||||
span.classList.add('danger');
|
||||
span.append(i18n('Draft'), ': ');
|
||||
willPrepend.unshift(span);
|
||||
} else if(peerId.isAnyChat() && peerId !== lastMessage.fromId && !(lastMessage as Message.messageService).action) {
|
||||
const senderBold = document.createElement('b');
|
||||
const span = document.createElement('span');
|
||||
span.classList.add('primary-text');
|
||||
|
||||
if(lastMessage.fromId === rootScope.myId) {
|
||||
senderBold.append(i18n('FromYou'));
|
||||
willPrepend.unshift(senderBold);
|
||||
span.append(i18n('FromYou'));
|
||||
willPrepend.unshift(span);
|
||||
} else {
|
||||
// str = sender.first_name || sender.last_name || sender.username;
|
||||
const p = middleware(wrapPeerTitle({
|
||||
peerId: lastMessage.fromId,
|
||||
onlyFirstName: true
|
||||
})).then((element) => {
|
||||
senderBold.prepend(element);
|
||||
return senderBold;
|
||||
span.prepend(element);
|
||||
return span;
|
||||
}, noop);
|
||||
|
||||
willPrepend.unshift(p);
|
||||
}
|
||||
|
||||
senderBold.append(': ');
|
||||
span.append(': ');
|
||||
// console.log(sender, senderBold.innerText);
|
||||
}
|
||||
|
||||
|
@ -1870,7 +2017,7 @@ export class AppDialogsManager {
|
|||
if(hasMentionsBadge) {
|
||||
if(!dom.mentionsBadge) {
|
||||
dom.mentionsBadge = document.createElement('div');
|
||||
dom.mentionsBadge.className = 'dialog-subtitle-badge badge badge-24 mention mention-badge';
|
||||
dom.mentionsBadge.className = `dialog-subtitle-badge badge badge-${BADGE_SIZE} mention mention-badge`;
|
||||
dom.mentionsBadge.innerText = '@';
|
||||
dom.subtitleEl.insertBefore(dom.mentionsBadge, dom.lastMessageSpan.nextSibling);
|
||||
}
|
||||
|
@ -2041,14 +2188,27 @@ export class AppDialogsManager {
|
|||
onlyFirstName?: boolean,
|
||||
meAsSaved?: boolean,
|
||||
append?: boolean,
|
||||
avatarSize?: number,
|
||||
avatarSize?: RowMediaSizeType,
|
||||
autonomous?: boolean,
|
||||
lazyLoadQueue?: LazyLoadQueue,
|
||||
loadPromises?: Promise<any>[],
|
||||
fromName?: string,
|
||||
noIcons?: boolean
|
||||
}) {
|
||||
return this.addDialog(options.peerId, options.container, options.rippleEnabled, options.onlyFirstName, options.meAsSaved, options.append, options.avatarSize, options.autonomous, options.lazyLoadQueue, options.loadPromises, options.fromName, options.noIcons);
|
||||
const d = new DialogElement({
|
||||
autonomous: !!options.container,
|
||||
avatarSize: 'bigger',
|
||||
...options
|
||||
// avatarSize: !options.avatarSize || options.avatarSize >= 54 ? 'bigger' : 'abitbigger',
|
||||
});
|
||||
|
||||
if(options.container) {
|
||||
const method = !options.append ? 'append' : 'prepend';
|
||||
options.container[method](d.container);
|
||||
}
|
||||
|
||||
return d;
|
||||
// return this.addDialog(options.peerId, options.container, options.rippleEnabled, options.onlyFirstName, options.meAsSaved, options.append, options.avatarSize, options.autonomous, options.lazyLoadQueue, options.loadPromises, options.fromName, options.noIcons);
|
||||
}
|
||||
|
||||
public addDialog(
|
||||
|
@ -2138,7 +2298,7 @@ export class AppDialogsManager {
|
|||
lastTimeSpan.classList.add('message-time');
|
||||
|
||||
const unreadBadge = document.createElement('div');
|
||||
unreadBadge.className = 'dialog-subtitle-badge badge badge-24';
|
||||
unreadBadge.className = 'dialog-subtitle-badge badge badge-' + BADGE_SIZE;
|
||||
|
||||
const titleP = document.createElement('p');
|
||||
titleP.classList.add('dialog-title');
|
||||
|
|
|
@ -1000,6 +1000,14 @@ export class AppImManager extends EventListenerBase<{
|
|||
}
|
||||
|
||||
private onHashChange = (saveState?: boolean) => {
|
||||
try {
|
||||
this.onHashChangeUnsafe(saveState);
|
||||
} catch(err) {
|
||||
this.log.error('hash change error', err);
|
||||
}
|
||||
};
|
||||
|
||||
private onHashChangeUnsafe = (saveState?: boolean) => {
|
||||
const hash = location.hash;
|
||||
if(!saveState) {
|
||||
appNavigationController.replaceState();
|
||||
|
@ -1023,6 +1031,10 @@ export class AppImManager extends EventListenerBase<{
|
|||
}
|
||||
|
||||
case '#/im': {
|
||||
if(!Object.keys(params).length) {
|
||||
break;
|
||||
}
|
||||
|
||||
const p: string = params.p;
|
||||
const postId = params.post !== undefined ? generateMessageId(+params.post) : undefined;
|
||||
|
||||
|
@ -1289,7 +1301,7 @@ export class AppImManager extends EventListenerBase<{
|
|||
const top = chatBubbles.scrollable.scrollTop;
|
||||
|
||||
const position = {
|
||||
mids: getObjectKeysAndSort(chatBubbles.bubbles, 'desc').filter((mid) => !chatBubbles.skippedMids.has(mid)),
|
||||
mids: getObjectKeysAndSort(chatBubbles.bubbles, 'desc').filter((mid) => mid > 0 && !chatBubbles.skippedMids.has(mid)),
|
||||
top
|
||||
};
|
||||
|
||||
|
@ -1704,9 +1716,7 @@ export class AppImManager extends EventListenerBase<{
|
|||
this.dispatchEvent('peer_changed', chatTo.peerId);
|
||||
|
||||
const searchTab = appSidebarRight.getTab(AppPrivateSearchTab);
|
||||
if(searchTab) {
|
||||
searchTab.close();
|
||||
}
|
||||
searchTab?.close();
|
||||
|
||||
appSidebarRight.replaceSharedMediaTab(chatTo.sharedMediaTab);
|
||||
}
|
||||
|
|
|
@ -1492,6 +1492,8 @@ export class AppMessagesManager extends AppManager {
|
|||
sequential: options.sequential
|
||||
};
|
||||
|
||||
this.pendingTopMsgs[peerId] = messageId;
|
||||
|
||||
if(!options.isGroupedItem && message.send) {
|
||||
callbacks.push(() => {
|
||||
if(options.clearDraft) {
|
||||
|
|
|
@ -11,10 +11,12 @@ import parseMarkdown from '../richTextProcessor/parseMarkdown';
|
|||
import {AppManager} from './manager';
|
||||
import getServerMessageId from './utils/messageId/getServerMessageId';
|
||||
|
||||
type PollId = Poll['id'];
|
||||
|
||||
export class AppPollsManager extends AppManager {
|
||||
public polls: {[id: string]: Poll} = {};
|
||||
public results: {[id: string]: PollResults} = {};
|
||||
public pollToMessages: {[id: string]: Set<string>} = {};
|
||||
public polls: {[id: PollId]: Poll} = {};
|
||||
public results: {[id: PollId]: PollResults} = {};
|
||||
public pollToMessages: {[id: PollId]: Set<string>} = {};
|
||||
|
||||
private log = logger('POLLS', LogTypes.Error);
|
||||
|
||||
|
@ -78,7 +80,7 @@ export class AppPollsManager extends AppManager {
|
|||
return results;
|
||||
}
|
||||
|
||||
public getPoll(pollId: string): {poll: Poll, results: PollResults} {
|
||||
public getPoll(pollId: PollId): {poll: Poll, results: PollResults} {
|
||||
return {
|
||||
poll: this.polls[pollId],
|
||||
results: this.results[pollId]
|
||||
|
@ -128,8 +130,8 @@ export class AppPollsManager extends AppManager {
|
|||
}
|
||||
}
|
||||
|
||||
public sendVote(message: any, optionIds: number[]): Promise<void> {
|
||||
const poll: Poll = message.media.poll;
|
||||
public sendVote(message: Message.message, optionIds: number[]): Promise<void> {
|
||||
const poll: Poll = (message.media as MessageMedia.messageMediaPoll).poll;
|
||||
|
||||
const options: Uint8Array[] = optionIds.map((index) => {
|
||||
return poll.answers[index].option;
|
||||
|
@ -142,7 +144,7 @@ export class AppPollsManager extends AppManager {
|
|||
if(message.pFlags.is_outgoing) {
|
||||
return this.appMessagesManager.invokeAfterMessageIsSent(messageId, 'sendVote', (message) => {
|
||||
this.log('invoke sendVote callback');
|
||||
return this.sendVote(message, optionIds);
|
||||
return this.sendVote(message as Message.message, optionIds);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -156,7 +158,7 @@ export class AppPollsManager extends AppManager {
|
|||
});
|
||||
}
|
||||
|
||||
public getResults(message: any) {
|
||||
public getResults(message: Message.message) {
|
||||
const inputPeer = this.appPeersManager.getInputPeerById(message.peerId);
|
||||
|
||||
return this.apiManager.invokeApi('messages.getPollResults', {
|
||||
|
@ -168,7 +170,7 @@ export class AppPollsManager extends AppManager {
|
|||
});
|
||||
}
|
||||
|
||||
public getVotes(message: any, option?: Uint8Array, offset?: string, limit = 20) {
|
||||
public getVotes(message: Message.message, option?: Uint8Array, offset?: string, limit = 20) {
|
||||
return this.apiManager.invokeApi('messages.getPollVotes', {
|
||||
peer: this.appPeersManager.getInputPeerById(message.peerId),
|
||||
id: getServerMessageId(message.mid),
|
||||
|
@ -184,8 +186,8 @@ export class AppPollsManager extends AppManager {
|
|||
});
|
||||
}
|
||||
|
||||
public stopPoll(message: any) {
|
||||
const poll: Poll = message.media.poll;
|
||||
public stopPoll(message: Message.message) {
|
||||
const poll: Poll = (message.media as MessageMedia.messageMediaPoll).poll;
|
||||
|
||||
if(poll.pFlags.closed) return Promise.resolve();
|
||||
|
||||
|
|
|
@ -271,8 +271,11 @@ export class AppProfileManager extends AppManager {
|
|||
const fullChat = this.chatsFull[id] as ChatFull.chatFull;
|
||||
if(fullChat && !override && Date.now() < this.fullExpiration[peerId]) {
|
||||
const chat: Chat.chat = this.appChatsManager.getChat(id);
|
||||
if(chat.version === (fullChat.participants as ChatParticipants.chatParticipants).version ||
|
||||
chat.pFlags.left) {
|
||||
if(
|
||||
chat.pFlags.left ||
|
||||
chat.pFlags.deactivated ||
|
||||
chat.version === (fullChat.participants as ChatParticipants.chatParticipants).version
|
||||
) {
|
||||
return fullChat as ChatFull;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -396,10 +396,16 @@ export class AppUsersManager extends AppManager {
|
|||
public getContactsPeerIds(
|
||||
query?: Parameters<AppUsersManager['getContacts']>[0],
|
||||
includeSaved?: Parameters<AppUsersManager['getContacts']>[1],
|
||||
sortBy?: Parameters<AppUsersManager['getContacts']>[2]
|
||||
sortBy?: Parameters<AppUsersManager['getContacts']>[2],
|
||||
limit?: number
|
||||
) {
|
||||
return this.getContacts(query, includeSaved, sortBy).then((userIds) => {
|
||||
return userIds.map((userId) => userId.toPeerId(false));
|
||||
const peerIds = userIds.map((userId) => userId.toPeerId(false));
|
||||
if(limit) {
|
||||
return peerIds.slice(0, limit);
|
||||
}
|
||||
|
||||
return peerIds;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import apiManagerProxy from '../mtproto/mtprotoworker';
|
|||
import {AckedResult} from '../mtproto/superMessagePort';
|
||||
import noop from '../../helpers/noop';
|
||||
import dT from '../../helpers/dT';
|
||||
import DEBUG from '../../config/debug';
|
||||
|
||||
// let stats: {
|
||||
// [manager: string]: {
|
||||
|
@ -58,6 +59,11 @@ import dT from '../../helpers/dT';
|
|||
// sentMethods2 = {};
|
||||
// }, 2000);
|
||||
|
||||
const DEBUG_MANAGER_REQUESTS: {[managerName: string]: Set<string>} = {};
|
||||
if(DEBUG) {
|
||||
(window as any).DEBUG_MANAGER_REQUESTS = DEBUG_MANAGER_REQUESTS;
|
||||
}
|
||||
|
||||
function createProxy(/* source: T, */name: string, ack?: boolean) {
|
||||
const proxy = new Proxy({}, {
|
||||
get: (target, p, receiver) => {
|
||||
|
@ -75,6 +81,12 @@ function createProxy(/* source: T, */name: string, ack?: boolean) {
|
|||
args
|
||||
}, ack as any);
|
||||
|
||||
if(DEBUG) {
|
||||
if(DEBUG_MANAGER_REQUESTS[name]?.has(p as any)) {
|
||||
console.warn('manager request', name, p, args);
|
||||
}
|
||||
}
|
||||
|
||||
// collectStats(name, p as string, args, promise);
|
||||
|
||||
return promise;
|
||||
|
@ -93,27 +105,30 @@ type AA<T> = {
|
|||
};
|
||||
|
||||
type T = Awaited<ReturnType<typeof createManagers>>;
|
||||
export default function getProxiedManagers() {
|
||||
let proxied: {
|
||||
[name in keyof T]?: ModifyFunctionsToAsync<T[name]>;
|
||||
} & {
|
||||
acknowledged?: {
|
||||
[name in keyof T]?: AA<T[name]>;
|
||||
}
|
||||
};
|
||||
type ProxiedManagers = {
|
||||
[name in keyof T]?: ModifyFunctionsToAsync<T[name]>;
|
||||
} & {
|
||||
acknowledged?: {
|
||||
[name in keyof T]?: AA<T[name]>;
|
||||
}
|
||||
};
|
||||
|
||||
function createProxyProxy(proxied: any, ack?: boolean) {
|
||||
return new Proxy(proxied, {
|
||||
get: (target, p, receiver) => {
|
||||
// @ts-ignore
|
||||
return target[p] ??= createProxy(p as string, ack);
|
||||
}
|
||||
});
|
||||
function createProxyProxy(proxied: any, ack?: boolean) {
|
||||
return new Proxy(proxied, {
|
||||
get: (target, p, receiver) => {
|
||||
// @ts-ignore
|
||||
return target[p] ??= createProxy(p as string, ack);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let proxied: ProxiedManagers;
|
||||
export default function getProxiedManagers() {
|
||||
if(proxied) {
|
||||
return proxied;
|
||||
}
|
||||
|
||||
proxied = createProxyProxy({}, false);
|
||||
|
||||
proxied.acknowledged = createProxyProxy({}, true);
|
||||
|
||||
return proxied;
|
||||
}
|
||||
|
|
|
@ -795,14 +795,15 @@ export default class DialogsStorage extends AppManager {
|
|||
const updatedDialogs: Map<PeerId, Dialog> = new Map();
|
||||
(dialogsResult.dialogs as Dialog[]).forEach((dialog) => {
|
||||
const peerId = this.appPeersManager.getPeerId(dialog.peer);
|
||||
let topMessage = dialog.top_message;
|
||||
let topMid = dialog.top_message;
|
||||
|
||||
const topPendingMessage = this.appMessagesManager.pendingTopMsgs[peerId];
|
||||
if(topPendingMessage) {
|
||||
if(!topMessage ||
|
||||
(this.appMessagesManager.getMessageByPeer(peerId, topPendingMessage) as MyMessage)?.date > (this.appMessagesManager.getMessageByPeer(peerId, topMessage) as MyMessage)?.date) {
|
||||
dialog.top_message = topMessage = topPendingMessage;
|
||||
this.appMessagesManager.getHistoryStorage(peerId).maxId = topPendingMessage;
|
||||
const topPendingMid = this.appMessagesManager.pendingTopMsgs[peerId];
|
||||
if(topPendingMid) {
|
||||
const topPendingMessage = this.appMessagesManager.getMessageByPeer(peerId, topPendingMid) as MyMessage;
|
||||
const topMessage = this.appMessagesManager.getMessageByPeer(peerId, topMid) as MyMessage;
|
||||
if(!topMid || (topPendingMessage && (!topMessage || topPendingMessage?.date > topMessage?.date))) {
|
||||
dialog.top_message = topMid = topPendingMid;
|
||||
this.appMessagesManager.getHistoryStorage(peerId).maxId = topPendingMid;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -811,7 +812,7 @@ export default class DialogsStorage extends AppManager {
|
|||
this.log.error('applyConversation lun', dialog, d);
|
||||
} */
|
||||
|
||||
if(topMessage || dialog.draft?._ === 'draftMessage') {
|
||||
if(topMid || dialog.draft?._ === 'draftMessage') {
|
||||
if(this.saveDialog(dialog)) {
|
||||
updatedDialogs.set(peerId, dialog);
|
||||
}
|
||||
|
|
|
@ -78,6 +78,7 @@ avatar-element {
|
|||
} */
|
||||
|
||||
&.tgico-deletedaccount {
|
||||
overflow: hidden;
|
||||
--color-top: var(--peer-avatar-archive-top);
|
||||
--color-bottom: var(--peer-avatar-archive-bottom);
|
||||
|
||||
|
|
|
@ -5,11 +5,18 @@
|
|||
*/
|
||||
|
||||
.badge {
|
||||
--size: 1.375rem;
|
||||
--padding: .4375rem;
|
||||
border-radius: .75rem;
|
||||
font-weight: var(--font-weight-bold);
|
||||
color: var(--badge-text-color);
|
||||
font-size: .875rem;
|
||||
text-align: center;
|
||||
|
||||
height: var(--size);
|
||||
min-width: var(--size);
|
||||
line-height: var(--size) !important;
|
||||
padding: 0 var(--padding);
|
||||
|
||||
@include animation-level(2) {
|
||||
transition: background-color .2s ease-in-out;
|
||||
|
@ -20,24 +27,18 @@
|
|||
}
|
||||
|
||||
&-20 {
|
||||
height: 1.25rem;
|
||||
min-width: 1.25rem;
|
||||
line-height: 1.25rem !important;
|
||||
padding: 0 .375rem;
|
||||
--size: 1.25rem;
|
||||
--padding: .375rem;
|
||||
}
|
||||
|
||||
&-24 {
|
||||
height: 1.5rem;
|
||||
min-width: 1.5rem;
|
||||
line-height: 1.5rem !important;
|
||||
padding: 0 .5rem;
|
||||
--size: 1.5rem;
|
||||
--padding: .5rem;
|
||||
}
|
||||
|
||||
&.tgico {
|
||||
// width: 1.5rem;
|
||||
|
||||
&:before {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
&.tgico {
|
||||
&:before {
|
||||
font-size: var(--size);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -675,7 +675,7 @@ $btn-menu-z-index: 4;
|
|||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 1rem;
|
||||
height: 3.5rem;
|
||||
height: 3rem;
|
||||
//width: auto;
|
||||
//text-transform: capitalize;
|
||||
font-weight: normal;
|
||||
|
@ -690,7 +690,7 @@ $btn-menu-z-index: 4;
|
|||
&.danger {
|
||||
@include hover-background-effect(red);
|
||||
}
|
||||
|
||||
|
||||
&.primary {
|
||||
@include hover-background-effect(primary);
|
||||
}
|
||||
|
@ -700,6 +700,10 @@ $btn-menu-z-index: 4;
|
|||
color: var(--secondary-text-color);
|
||||
font-size: 1.5rem;
|
||||
margin-right: 2rem;
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
margin-right: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
&.btn-short:before {
|
||||
|
|
|
@ -1680,6 +1680,11 @@ $chat-input-border-radius: 1rem;
|
|||
padding: 0 $chat-padding-handhelds;
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: " ";
|
||||
height: .125rem;
|
||||
}
|
||||
|
||||
&.is-chat {
|
||||
.is-in {
|
||||
//margin-left: 45px;
|
||||
|
|
|
@ -85,6 +85,7 @@ $bubble-border-radius-big: 12px;
|
|||
}
|
||||
|
||||
.bubble {
|
||||
--line-height: var(--messages-line-height);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin: 0 auto $bubble-margin;
|
||||
|
|
|
@ -180,6 +180,7 @@ body.is-right-column-shown {
|
|||
max-width: calc(100% - 1.5rem);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: var(--font-weight-bold);
|
||||
|
||||
span.emoji {
|
||||
vertical-align: inherit;
|
||||
|
|
|
@ -129,7 +129,7 @@
|
|||
.search-super {
|
||||
.search-group {
|
||||
margin-bottom: 0px;
|
||||
padding: 4px 0 0;
|
||||
padding: 0 0 .5rem;
|
||||
|
||||
&__name {
|
||||
padding-top: 1rem;
|
||||
|
@ -138,7 +138,6 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ul.chatlist {
|
||||
|
@ -151,8 +150,6 @@ ul.chatlist {
|
|||
}
|
||||
|
||||
.chatlist {
|
||||
//--avatarSize: 54px;
|
||||
//--height: 72px;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
@ -164,40 +161,11 @@ ul.chatlist {
|
|||
-webkit-user-select: none; /* disable selection/Copy of UIWebView */
|
||||
-webkit-touch-callout: none; /* disable the IOS popup when long-press on a link */
|
||||
|
||||
/* &.chatlist-avatar-48 {
|
||||
--avatarSize: 48px;
|
||||
}
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
&.chatlist-handhelds-66 {
|
||||
--height: 66px;
|
||||
}
|
||||
} */
|
||||
|
||||
&-chat {
|
||||
--background: unset;
|
||||
//height: var(--height);
|
||||
height: 72px;
|
||||
//max-height: var(--height);
|
||||
border-radius: $border-radius-medium;
|
||||
display: flex;
|
||||
align-items: flex-start; // TODO: проверить разницу в производительности с align-items: center;
|
||||
flex-direction: row;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
padding: .5625rem;
|
||||
/* padding-top: calc((var(--height) - var(--avatarSize)) / 2);
|
||||
padding-bottom: calc((var(--height) - var(--avatarSize)) / 2);
|
||||
padding-right: 8.5px;
|
||||
padding-left: 8.5px; */
|
||||
overflow: hidden;
|
||||
background: var(--background);
|
||||
background: var(--background) !important;
|
||||
-webkit-user-drag: none;
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
//@include hover-background-effect();
|
||||
@include hover(gray, --background, false);
|
||||
|
||||
|
@ -227,31 +195,14 @@ ul.chatlist {
|
|||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
height: 27px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
i {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.text-highlight {
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
|
||||
/* img.emoji {
|
||||
margin-right: .25rem;
|
||||
margin-left: .25rem;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
} */
|
||||
|
||||
&.menu-open {
|
||||
--background: var(--light-secondary-text-color);
|
||||
}
|
||||
|
@ -261,7 +212,8 @@ ul.chatlist {
|
|||
--background: var(--primary-color) !important;
|
||||
//background: var(--light-secondary-text-color);
|
||||
|
||||
.user-caption,
|
||||
.row-subtitle,
|
||||
.row-title,
|
||||
.tgico-chatspinned:before,
|
||||
//.user-title:after,
|
||||
.user-title,
|
||||
|
@ -270,7 +222,7 @@ ul.chatlist {
|
|||
.premium-icon,
|
||||
.verified-icon,
|
||||
.sending-status-icon {
|
||||
color: #fff;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.badge-fake {
|
||||
|
@ -278,7 +230,8 @@ ul.chatlist {
|
|||
border-color: #fff;
|
||||
}
|
||||
|
||||
b {
|
||||
.primary-text,
|
||||
.danger {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
|
@ -316,17 +269,6 @@ ul.chatlist {
|
|||
}
|
||||
}
|
||||
|
||||
/* .user-title,
|
||||
.dialog-title-details,
|
||||
.user-last-message */&-chat span {
|
||||
//display: inline-block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
//margin: .1rem 0;
|
||||
line-height: 27px;
|
||||
}
|
||||
|
||||
.peer-typing-container {
|
||||
--color: var(--secondary-text-color);
|
||||
|
||||
|
@ -347,12 +289,8 @@ ul.chatlist {
|
|||
}
|
||||
|
||||
&-subtitle {
|
||||
margin-top: -3px;
|
||||
|
||||
&-badge {
|
||||
display: block !important;
|
||||
margin-top: 4px;
|
||||
margin-right: -3px;
|
||||
margin-left: .5rem;
|
||||
flex: 0 0 auto;
|
||||
|
||||
|
@ -368,13 +306,21 @@ ul.chatlist {
|
|||
&-media {
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
line-height: 1.25rem;
|
||||
position: relative;
|
||||
flex: 0 0 auto;
|
||||
border-radius: .25rem;
|
||||
margin-top: -0.125rem;
|
||||
margin-right: 0.375rem;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
|
||||
&:before {
|
||||
content: " ";
|
||||
display: inline-block;
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
min-width: inherit;
|
||||
min-height: inherit;
|
||||
}
|
||||
|
||||
&.is-round {
|
||||
border-radius: 50%;
|
||||
|
@ -400,6 +346,8 @@ ul.chatlist {
|
|||
height: inherit;
|
||||
object-fit: cover;
|
||||
border-radius: inherit;
|
||||
top: auto;
|
||||
bottom: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -431,15 +379,8 @@ ul.chatlist {
|
|||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.user-caption {
|
||||
overflow: hidden;
|
||||
color: var(--secondary-text-color);
|
||||
flex: 1 1 auto;
|
||||
padding: .0625rem .4375rem .0625rem .5625rem;
|
||||
}
|
||||
|
||||
.dialog-avatar,
|
||||
.user-caption {
|
||||
.dialog-avatar,
|
||||
.row-row {
|
||||
pointer-events: none;
|
||||
position: relative; // for z-index
|
||||
}
|
||||
|
@ -454,12 +395,6 @@ ul.chatlist {
|
|||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
/* span.emoji {
|
||||
&:first-of-type:not(:first-child) {
|
||||
margin-left: .125rem;
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
.user-last-message {
|
||||
|
@ -481,11 +416,6 @@ ul.chatlist {
|
|||
.user-last-message {
|
||||
flex-grow: 1;
|
||||
position: relative; // * for custom emoji
|
||||
|
||||
i {
|
||||
font-style: normal;
|
||||
//color: var(--primary-color);
|
||||
}
|
||||
}
|
||||
|
||||
.message-status {
|
||||
|
@ -505,10 +435,6 @@ ul.chatlist {
|
|||
}
|
||||
}
|
||||
|
||||
/* .message-time {
|
||||
vertical-align: middle;
|
||||
} */
|
||||
|
||||
.tgico-chatspinned {
|
||||
background: transparent;
|
||||
|
||||
|
@ -530,8 +456,7 @@ ul.chatlist {
|
|||
}
|
||||
}
|
||||
|
||||
.tgico-chatspinned/* ,
|
||||
.tgico-mention */ {
|
||||
.tgico-chatspinned {
|
||||
position: relative;
|
||||
|
||||
&:before {
|
||||
|
@ -546,12 +471,12 @@ ul.chatlist {
|
|||
background-color: var(--chatlist-status-color) !important;
|
||||
|
||||
html.is-mac & {
|
||||
line-height: 22px !important;
|
||||
line-height: 1.25rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
.mention-badge {
|
||||
margin-right: -2px;
|
||||
margin-right: -.125rem;
|
||||
}
|
||||
|
||||
/* .tgico-mention {
|
||||
|
@ -619,87 +544,4 @@ ul.chatlist {
|
|||
// margin-top: -.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
// * supernew correct layout
|
||||
&-new {
|
||||
.chatlist-chat {
|
||||
height: 4.5rem;
|
||||
padding: 0 .75rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.user-caption {
|
||||
padding-left: .75rem;
|
||||
}
|
||||
|
||||
p {
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
span {
|
||||
line-height: var(--line-height) !important;
|
||||
}
|
||||
|
||||
.dialog-subtitle {
|
||||
margin-top: .125rem;
|
||||
}
|
||||
|
||||
.user-last-message {
|
||||
font-size: .875rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// use together like class="chatlist-container contacts-container"
|
||||
.contacts-container,
|
||||
.search-group-contacts {
|
||||
.chatlist-chat {
|
||||
padding: .75rem;
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
height: 66px;
|
||||
padding-top: 9px;
|
||||
padding-bottom: 9px;
|
||||
}
|
||||
}
|
||||
|
||||
.user-caption {
|
||||
padding: 1px 3.5px 1px 13px;
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
padding: 0 4px 0 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.user-title,
|
||||
b,
|
||||
.user-last-message b {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
p {
|
||||
height: 24px;
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
height: 26px;
|
||||
}
|
||||
}
|
||||
|
||||
span.user-last-message {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.chatlist-new.chatlist-48 {
|
||||
.chatlist-chat {
|
||||
height: 3.5rem;
|
||||
}
|
||||
|
||||
.user-caption {
|
||||
padding-left: 1.125rem;
|
||||
}
|
||||
|
||||
.dialog-subtitle {
|
||||
margin-top: .0625rem;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,6 +95,7 @@
|
|||
}
|
||||
|
||||
&-input {
|
||||
// --padding: calc((var(--height) - var(--border-width) * 2 - var(--line-height)) / 2);
|
||||
--padding: 1rem;
|
||||
--padding-horizontal: 1rem;
|
||||
--border-width: 1px;
|
||||
|
|
|
@ -345,40 +345,52 @@
|
|||
.chatlist {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding-left: 4px;
|
||||
margin-top: -1px;
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
padding: 0 0 1px;
|
||||
|
||||
.chatlist-chat {
|
||||
height: 98px;
|
||||
border-radius: 10px;
|
||||
max-width: 78px;
|
||||
width: 78px;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 12px 0 0 !important;
|
||||
margin: 0 5px 0 0;
|
||||
flex: 0 0 auto;
|
||||
&:before,
|
||||
&:after {
|
||||
content: " ";
|
||||
display: inline-block;
|
||||
width: .3125rem;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
width: 77px;
|
||||
max-width: 77px;
|
||||
&-chat {
|
||||
width: 4.875rem;
|
||||
max-width: 4.875rem;
|
||||
height: 6.125rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
flex: 0 0 auto;
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-title-details, .dialog-subtitle {
|
||||
display: none;
|
||||
}
|
||||
.dialog {
|
||||
&-title-details,
|
||||
&-subtitle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&-title {
|
||||
max-width: 65px;
|
||||
padding-bottom: .75rem;
|
||||
|
||||
.user-caption {
|
||||
max-width: 65px;
|
||||
padding: 2px 0px 9px;
|
||||
font-size: 12px;
|
||||
.user-title {
|
||||
font-size: .75rem !important;
|
||||
}
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
max-width: 56px;
|
||||
.peer-title {
|
||||
font-weight: var(--font-weight-normal) !important;
|
||||
}
|
||||
}
|
||||
|
||||
&-avatar {
|
||||
left: auto !important;
|
||||
top: .75rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -535,7 +547,6 @@
|
|||
|
||||
@include respond-to(handhelds) {
|
||||
width: 100%;
|
||||
padding: 0 .25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -550,7 +561,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
.new-channel-container, .new-group-container, .edit-profile-container {
|
||||
.new-channel-container,
|
||||
.new-group-container,
|
||||
.edit-profile-container {
|
||||
.sidebar-content {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
@ -560,7 +573,7 @@
|
|||
}
|
||||
|
||||
.caption {
|
||||
font-size: 0.875rem;
|
||||
font-size: .875rem;
|
||||
margin-top: 14px;
|
||||
margin-left: 23px;
|
||||
color: var(--secondary-text-color);
|
||||
|
@ -642,8 +655,8 @@
|
|||
.caption {
|
||||
text-align: center;
|
||||
color: var(--secondary-text-color);
|
||||
font-size: 14px;
|
||||
line-height: var(--line-height);
|
||||
font-size: var(--font-size-14);
|
||||
line-height: var(--line-height-14);
|
||||
max-width: 20rem;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
@ -697,21 +710,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.folder-list {
|
||||
.chatlist-chat {
|
||||
padding: 9px 12px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.user-caption {
|
||||
padding: 3px 28px 6px 27px;
|
||||
}
|
||||
|
||||
p span {
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.folder-categories {
|
||||
.checkbox-field {
|
||||
position: absolute;
|
||||
|
@ -719,31 +717,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.folder-category-button {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.popup-forward, .included-chatlist-container {
|
||||
.selector {
|
||||
.chatlist {
|
||||
&-chat {
|
||||
padding: 7px .75rem !important;
|
||||
height: 3.75rem;
|
||||
}
|
||||
|
||||
.user-caption {
|
||||
padding: 0px 0px 0 14px;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.user-last-message {
|
||||
font-size: 15px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.included-chatlist-container {
|
||||
.sidebar-left-section {
|
||||
padding-bottom: 0;
|
||||
|
@ -786,27 +759,6 @@
|
|||
font-size: 22px;
|
||||
//}
|
||||
}
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
.chatlist-chat {
|
||||
height: 62px;
|
||||
padding-top: 7px;
|
||||
padding-bottom: 7px;
|
||||
}
|
||||
|
||||
.user-caption {
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.user-title {
|
||||
font-weight: var(--font-weight-bold) !important;
|
||||
}
|
||||
|
||||
.dialog-avatar {
|
||||
--size: 46px;
|
||||
--multiplier: 1.173913;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
|
@ -913,7 +865,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
.checkbox-field, .radio-field {
|
||||
.checkbox-field,
|
||||
.radio-field {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
@ -1081,9 +1034,9 @@
|
|||
|
||||
.active-sessions-container {
|
||||
.row {
|
||||
margin-top: 0;
|
||||
padding-top: 1rem;
|
||||
padding-bottom: .9375rem;
|
||||
// margin-top: 0;
|
||||
// padding-top: 1rem;
|
||||
// padding-bottom: .9375rem;
|
||||
|
||||
&-title:first-child {
|
||||
font-weight: var(--font-weight-bold);
|
||||
|
@ -1113,21 +1066,6 @@
|
|||
}
|
||||
|
||||
.blocked-users-container {
|
||||
.chatlist-chat {
|
||||
height: 66px;
|
||||
padding-top: 9px;
|
||||
padding-bottom: 9px;
|
||||
}
|
||||
|
||||
.user-caption {
|
||||
padding-left: .75rem;
|
||||
}
|
||||
|
||||
.dialog-subtitle {
|
||||
margin-top: -.375rem;
|
||||
font-size: .875rem;
|
||||
}
|
||||
|
||||
ul {
|
||||
@include respond-to(not-handhelds) {
|
||||
padding: 0 .6875rem;
|
||||
|
|
|
@ -79,6 +79,7 @@ poll-element {
|
|||
&-avatars {
|
||||
display: flex;
|
||||
margin-left: 18px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&-avatar {
|
||||
|
|
|
@ -125,10 +125,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.profile-name {
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
.profile-subtitle,
|
||||
.verified-icon,
|
||||
.premium-icon {
|
||||
|
@ -299,8 +295,8 @@
|
|||
|
||||
&-name {
|
||||
text-align: center;
|
||||
font-size: 1.25rem;
|
||||
line-height: var(--line-height);
|
||||
font-size: var(--font-size-20);
|
||||
line-height: var(--line-height-20);
|
||||
font-weight: var(--font-weight-bold);
|
||||
overflow: hidden;
|
||||
max-width: 21.25rem;
|
||||
|
|
|
@ -564,7 +564,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
&-content-music, &-content-voice {
|
||||
&-content-music,
|
||||
&-content-voice {
|
||||
.search-super-month-items {
|
||||
padding: 20px 15px 0px 20px;
|
||||
|
||||
|
@ -596,19 +597,6 @@
|
|||
.chatlist {
|
||||
padding-top: .5rem;
|
||||
padding-bottom: .5rem;
|
||||
|
||||
.chatlist-chat {
|
||||
padding: .75rem;
|
||||
}
|
||||
|
||||
.user-caption {
|
||||
padding-left: .75rem;
|
||||
}
|
||||
|
||||
.dialog-subtitle {
|
||||
font-size: .875rem;
|
||||
margin-top: -.375rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -692,9 +680,9 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.search-group.is-short {
|
||||
li:nth-child(n + 4) {
|
||||
.chatlist-chat:nth-child(n + 4) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
@ -794,22 +782,12 @@
|
|||
}
|
||||
|
||||
&-more {
|
||||
padding-top: 13px;
|
||||
padding-bottom: 13px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
position: relative;
|
||||
margin: 0 .5rem;
|
||||
width: auto;
|
||||
|
||||
@include respond-to(not-handhelds) {
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.tgico-down {
|
||||
float: left;
|
||||
padding-right: 32px;
|
||||
padding-left: 16.5px;
|
||||
font-size: 24px;
|
||||
color: var(--secondary-text-color);
|
||||
@include respond-to(handhelds) {
|
||||
margin: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -827,30 +805,8 @@
|
|||
hr {
|
||||
margin-bottom: 15px;
|
||||
margin-top: 7px;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.user-caption {
|
||||
padding: 3px 28px 6px;
|
||||
}
|
||||
|
||||
.user-title {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.chatlist-chat {
|
||||
height: 50px;
|
||||
padding: 9px;
|
||||
|
||||
@include respond-to(not-handhelds) {
|
||||
padding: 9px 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#search-gifs-container {
|
||||
.gifs-masonry {
|
||||
margin-top: -2.5px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,8 @@ $row-border-radius: $border-radius-medium;
|
|||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
&.no-subtitle {
|
||||
&.no-subtitle,
|
||||
&.row-small {
|
||||
min-height: 3rem;
|
||||
padding-top: .1875rem;
|
||||
padding-bottom: .1875rem;
|
||||
|
@ -31,25 +32,43 @@ $row-border-radius: $border-radius-medium;
|
|||
opacity: var(--disabled-opacity);
|
||||
}
|
||||
|
||||
&.no-wrap {
|
||||
padding-top: 0 !important;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
|
||||
a {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&-title-row {
|
||||
&-title-row,
|
||||
& > &-title {
|
||||
order: 0;
|
||||
}
|
||||
|
||||
&-big {
|
||||
min-height: 4.5rem;
|
||||
padding: .5625rem .75rem .5625rem 1rem;
|
||||
}
|
||||
|
||||
&-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
order: 0;
|
||||
|
||||
.row-title {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
.row-title,
|
||||
.row-subtitle {
|
||||
@include text-overflow(true);
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
|
||||
&-subtitle-row,
|
||||
& > &-subtitle {
|
||||
order: 1;
|
||||
}
|
||||
|
||||
// &-title,
|
||||
// &-title-row,
|
||||
// &-subtitle {
|
||||
|
@ -58,41 +77,51 @@ $row-border-radius: $border-radius-medium;
|
|||
|
||||
&-title {
|
||||
color: var(--primary-text-color);
|
||||
font-size: var(--font-size);
|
||||
line-height: var(--line-height);
|
||||
order: 0;
|
||||
|
||||
@include text-overflow(false);
|
||||
|
||||
&-right {
|
||||
flex: 0 0 auto !important;
|
||||
margin-left: 1rem;
|
||||
|
||||
&-secondary {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-title-right,
|
||||
&-subtitle-right {
|
||||
flex: 0 0 auto !important;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
&-midtitle {
|
||||
font-size: .875rem;
|
||||
font-size: var(--font-size-14);
|
||||
order: 1;
|
||||
}
|
||||
|
||||
&-with-padding {
|
||||
padding-left: 4.5rem;
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
padding-left: 4rem;
|
||||
}
|
||||
|
||||
.row-title.tgico:before {
|
||||
position: absolute;
|
||||
left: 1rem;
|
||||
font-size: 1.5rem;
|
||||
color: var(--secondary-text-color);
|
||||
pointer-events: none;
|
||||
margin-top: -.125rem;
|
||||
|
||||
// margin-top: -.125rem;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.row-subtitle:not(:empty):not(.hide) + .row-title.tgico:before {
|
||||
margin-top: .25rem;
|
||||
}
|
||||
// .row-subtitle:not(:empty):not(.hide) + .row-title.tgico:before {
|
||||
// margin-top: .25rem;
|
||||
// }
|
||||
}
|
||||
|
||||
&-clickable {
|
||||
|
@ -144,11 +173,9 @@ $row-border-radius: $border-radius-medium;
|
|||
|
||||
&-subtitle {
|
||||
color: var(--secondary-text-color) !important;
|
||||
font-size: .875rem !important;
|
||||
font-size: var(--font-size-14) !important;
|
||||
line-height: var(--line-height-14);
|
||||
margin-top: .125rem;
|
||||
margin-bottom: .0625rem;
|
||||
order: 1;
|
||||
margin-top: .1875rem;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
|
@ -172,11 +199,23 @@ $row-border-radius: $border-radius-medium;
|
|||
left: .75rem !important;
|
||||
}
|
||||
|
||||
&-abitbigger {
|
||||
width: 2.625rem !important;
|
||||
height: 2.625rem !important;
|
||||
left: .75rem !important;
|
||||
}
|
||||
|
||||
&-big {
|
||||
width: 3rem !important;
|
||||
height: 3rem !important;
|
||||
left: .5rem !important;
|
||||
}
|
||||
|
||||
&-bigger {
|
||||
width: 3.375rem !important;
|
||||
height: 3.375rem !important;
|
||||
left: .5625rem !important; // it's wrong but old chatlist has it
|
||||
}
|
||||
}
|
||||
|
||||
&.menu-open {
|
||||
|
|
|
@ -143,32 +143,6 @@
|
|||
} */
|
||||
}
|
||||
|
||||
.chatlist {
|
||||
&-chat {
|
||||
padding-top: .75rem;
|
||||
padding-bottom: .75rem;
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
height: 66px;
|
||||
padding-top: 9px;
|
||||
padding-bottom: 9px;
|
||||
}
|
||||
}
|
||||
|
||||
.user-caption {
|
||||
padding-left: .75rem;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
height: 24px !important;
|
||||
}
|
||||
|
||||
span.user-last-message {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
> hr {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
@ -180,8 +154,11 @@
|
|||
}
|
||||
|
||||
.checkbox-field {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
--offset-left: 0 !important;
|
||||
pointer-events: none;
|
||||
position: absolute !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
transform: translateY(-50%);
|
||||
top: 50%;
|
||||
z-index: 1;
|
||||
|
@ -193,8 +170,6 @@
|
|||
}
|
||||
|
||||
.checkbox-field-round {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
right: 1.125rem;
|
||||
--size: 1.25rem;
|
||||
|
||||
|
@ -206,4 +181,20 @@
|
|||
--offset: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
&-square {
|
||||
$add: 3rem;
|
||||
|
||||
.checkbox-field {
|
||||
left: 1.25rem !important;
|
||||
}
|
||||
|
||||
.chatlist-chat {
|
||||
padding-left: #{4.5rem + $add} !important; // 4.5 + x
|
||||
}
|
||||
|
||||
.dialog-avatar {
|
||||
margin-left: #{$add} !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,21 +19,23 @@
|
|||
|
||||
&-header {
|
||||
flex: 0 0 auto;
|
||||
margin-bottom: 3px;
|
||||
margin-bottom: 7px;
|
||||
padding: 0 1rem;
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
padding-left: .9375rem;
|
||||
padding-left: .8125rem;
|
||||
}
|
||||
}
|
||||
|
||||
&-title {
|
||||
flex-grow: 1;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.selector, .chatlist-container {
|
||||
.selector,
|
||||
.chatlist-container {
|
||||
height: auto;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
|
@ -44,24 +46,19 @@
|
|||
|
||||
.selector {
|
||||
&-search-input {
|
||||
font-size: 1.25rem;
|
||||
font-size: var(--font-size-20);
|
||||
line-height: 1;
|
||||
padding: .5rem 1.5rem;
|
||||
width: 100%;
|
||||
line-height: var(--line-height);
|
||||
height: 100%;
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
padding-left: 1.0625rem;
|
||||
padding-left: 1.1875rem;
|
||||
}
|
||||
}
|
||||
|
||||
.chatlist {
|
||||
margin-top: 0 !important;
|
||||
|
||||
&-chat {
|
||||
height: 3.875rem !important;
|
||||
padding-top: .5rem !important;
|
||||
padding-bottom: .5rem !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -154,7 +154,6 @@
|
|||
}
|
||||
|
||||
&-participant {
|
||||
align-items: center;
|
||||
// border-radius: 0;
|
||||
padding-right: .5rem;
|
||||
|
||||
|
@ -175,8 +174,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
.dialog-title,
|
||||
.dialog-subtitle {
|
||||
padding-right: 2.5rem;
|
||||
}
|
||||
|
||||
&-muted-icon-container {
|
||||
flex: 0 0 auto;
|
||||
position: absolute !important;
|
||||
right: .5rem;
|
||||
}
|
||||
|
||||
&-video {
|
||||
|
@ -382,10 +387,6 @@
|
|||
color: var(--gc-secondary-text-color);
|
||||
}
|
||||
|
||||
.dialog-subtitle {
|
||||
margin-top: -.25rem;
|
||||
}
|
||||
|
||||
// .user-caption {
|
||||
// padding-right: 1rem;
|
||||
// }
|
||||
|
|
|
@ -86,6 +86,7 @@ $chat-input-inner-padding-handhelds: .25rem;
|
|||
--message-highlightning-color: hsla(85.5319, 36.9171%, 40.402%, .4);//rgba(77, 142, 80, .4);
|
||||
--messages-container-width: #{$messages-container-width};
|
||||
--messages-text-size: 16px;
|
||||
--messages-line-height: 1.3125;
|
||||
--messages-secondary-text-size: calc(var(--messages-text-size) - 2px);
|
||||
--messages-secondary-line-height: calc(var(--messages-secondary-text-size) + 4px);
|
||||
--messages-time-text-size: calc(var(--messages-text-size) - 4px);
|
||||
|
@ -93,15 +94,16 @@ $chat-input-inner-padding-handhelds: .25rem;
|
|||
--messages-custom-emoji-size: calc(var(--messages-text-size) + 4px);
|
||||
--bubble-transition-in: transform var(--transition-standard-in), opacity var(--transition-standard-in);
|
||||
--bubble-transition-out: transform var(--transition-standard-out), opacity var(--transition-standard-out);
|
||||
--line-height: 1.3125;
|
||||
--line-height-20: 23px;
|
||||
--line-height-20: 26px;
|
||||
--line-height-16: 21px;
|
||||
--line-height-14: 18px;
|
||||
--line-height-12: 16px;
|
||||
--line-height: 1.3125;
|
||||
--font-size-20: 20px;
|
||||
--font-size-16: 16px;
|
||||
--font-size-14: 14px;
|
||||
--font-size-12: 12px;
|
||||
--font-size: var(--font-size-16);
|
||||
--esg-sticker-size: 72px;
|
||||
--esg-custom-emoji-size: 36px;
|
||||
--popup-sticker-size: 80px;
|
||||
|
@ -111,6 +113,7 @@ $chat-input-inner-padding-handhelds: .25rem;
|
|||
--menu-backdrop-filter: blur(50px);
|
||||
--font-monospace: 'Roboto Mono', monospace;
|
||||
--font-weight-bold: 500;
|
||||
--font-weight-normal: 400;
|
||||
--selection-background-color: rgba(var(--primary-color-rgb), .4);
|
||||
--selection-color: inherit;
|
||||
|
||||
|
@ -418,14 +421,15 @@ $chat-input-inner-padding-handhelds: .25rem;
|
|||
@import "partials/pages/chats";
|
||||
@import "partials/pages/password";
|
||||
|
||||
html, body {
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden; // + disable overscroll behavior on macOS
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
overflow: hidden;
|
||||
height: calc(var(--vh, 1vh) * 100);
|
||||
}
|
||||
|
||||
|
@ -619,7 +623,8 @@ input:-webkit-autofill:active {
|
|||
}
|
||||
}
|
||||
|
||||
.blue, .primary {
|
||||
.blue,
|
||||
.primary {
|
||||
color: var(--primary-color) !important;
|
||||
|
||||
.c-ripple__circle {
|
||||
|
@ -627,13 +632,19 @@ input:-webkit-autofill:active {
|
|||
}
|
||||
}
|
||||
|
||||
.primary-text {
|
||||
color: var(--primary-text-color) !important;
|
||||
}
|
||||
|
||||
.color-premium {
|
||||
background: var(--premium-gradient);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.blue:before, .primary:before, .danger:before {
|
||||
.blue:before,
|
||||
.primary:before,
|
||||
.danger:before {
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
|
@ -771,16 +782,9 @@ hr {
|
|||
padding-bottom: .5rem;
|
||||
}
|
||||
|
||||
.user-title, b/* , .user-last-message b */ {
|
||||
b {
|
||||
color: var(--primary-text-color);
|
||||
// font-weight: bolder;
|
||||
font-weight: var(--font-weight-bold);
|
||||
//font-weight: normal;
|
||||
}
|
||||
|
||||
.user-last-message b {
|
||||
font-weight: 400;
|
||||
//margin-right: .25rem;
|
||||
}
|
||||
|
||||
.avatar-edit {
|
||||
|
@ -1576,13 +1580,18 @@ middle-ellipsis-element {
|
|||
|
||||
&-caption {
|
||||
margin: -0.1875rem 0 1rem;
|
||||
font-size: .875rem;
|
||||
font-size: var(--font-size-14);
|
||||
line-height: var(--line-height-14);
|
||||
padding: 0 1.5rem;
|
||||
|
||||
&:first-child {
|
||||
margin-top: .8125rem;
|
||||
margin-bottom: .8125rem;
|
||||
}
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
&-container {
|
||||
|
@ -1997,6 +2006,67 @@ hr {
|
|||
}
|
||||
}
|
||||
|
||||
.chatlist-chat {
|
||||
padding-left: 4.5rem !important;
|
||||
|
||||
span {
|
||||
@include text-overflow(true);
|
||||
}
|
||||
|
||||
.row {
|
||||
&-title {
|
||||
font-size: var(--font-size-16) !important;
|
||||
line-height: 1.375rem;
|
||||
|
||||
&-right-secondary {
|
||||
margin-top: -.4375rem;
|
||||
font-size: var(--font-size-12) !important;
|
||||
line-height: var(--line-height-12) !important;
|
||||
}
|
||||
|
||||
// .peer-title {
|
||||
// font-weight: var(--font-weight-bold);
|
||||
// }
|
||||
}
|
||||
|
||||
&-row {
|
||||
height: 1.375rem;
|
||||
}
|
||||
}
|
||||
|
||||
&.chatlist-chat-small {
|
||||
|
||||
}
|
||||
|
||||
&.chatlist-chat-abitbigger {
|
||||
.row {
|
||||
&-subtitle {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.chatlist-chat-bigger {
|
||||
.row {
|
||||
&-subtitle {
|
||||
margin-top: 0;
|
||||
font-size: var(--font-size-16) !important;
|
||||
line-height: 1.375rem;
|
||||
|
||||
&-row {
|
||||
margin-top: .125rem;
|
||||
}
|
||||
}
|
||||
|
||||
&-title {
|
||||
.peer-title {
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// .contacts-container {
|
||||
// .chatlist-chat {
|
||||
// /* align-items: center; */
|
||||
|
|
Loading…
Reference in New Issue