Fix rendering bugged webpages
Fix rendering search results from hidden sender
This commit is contained in:
parent
71d7495e68
commit
8d7dd98df8
@ -205,7 +205,12 @@ export default class AppMediaViewer extends AppMediaViewerBase<'caption', 'delet
|
||||
}
|
||||
}
|
||||
|
||||
appImManager.setInnerPeer(message.peerId, mid, threadId ? 'discussion' : undefined, threadId);
|
||||
appImManager.setInnerPeer({
|
||||
peerId: message.peerId,
|
||||
lastMsgId: mid,
|
||||
type: threadId ? 'discussion' : undefined,
|
||||
threadId
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -184,20 +184,20 @@ export default class AppSearch {
|
||||
const searchGroup = this.searchGroups.messages;
|
||||
|
||||
history.forEach((message) => {
|
||||
const peerId = this.peerId ? message.fromId : message.peerId;
|
||||
const {dialog, dom} = appDialogsManager.addDialogNew({
|
||||
dialog: peerId,
|
||||
container: this.scrollable/* searchGroup.list */,
|
||||
drawStatus: false,
|
||||
avatarSize: 54,
|
||||
meAsSaved: false
|
||||
});
|
||||
|
||||
if(message.peerId !== peerId) {
|
||||
dom.listEl.dataset.peerId = '' + message.peerId;
|
||||
try {
|
||||
const peerId = this.peerId ? message.fromId : message.peerId;
|
||||
appDialogsManager.addDialogAndSetLastMessage({
|
||||
peerId,
|
||||
container: this.scrollable/* searchGroup.list */,
|
||||
drawStatus: false,
|
||||
avatarSize: 54,
|
||||
meAsSaved: false,
|
||||
message,
|
||||
query
|
||||
});
|
||||
} catch(err) {
|
||||
console.error('[appSearch] render search result', err);
|
||||
}
|
||||
|
||||
appDialogsManager.setLastMessage(dialog, message, dom, query);
|
||||
});
|
||||
|
||||
searchGroup.toggle();
|
||||
|
@ -28,7 +28,7 @@ import I18n, { LangPackKey, i18n } from "../lib/langPack";
|
||||
import findUpClassName from "../helpers/dom/findUpClassName";
|
||||
import { getMiddleware } from "../helpers/middleware";
|
||||
import appProfileManager from "../lib/appManagers/appProfileManager";
|
||||
import { ChannelParticipant, ChatFull, ChatParticipant, ChatParticipants } from "../layer";
|
||||
import { ChannelParticipant, ChatFull, ChatParticipant, ChatParticipants, Message, MessageMedia, Photo, WebPage } from "../layer";
|
||||
import SortedUserList from "./sortedUserList";
|
||||
import findUpTag from "../helpers/dom/findUpTag";
|
||||
import appSidebarRight from "./sidebarRight";
|
||||
@ -222,6 +222,15 @@ class SearchContextMenu {
|
||||
};
|
||||
}
|
||||
|
||||
export type ProcessSearchSuperResult = {
|
||||
message: Message.message,
|
||||
middleware: () => boolean,
|
||||
promises: Promise<any>[],
|
||||
elemsToAppend: {element: HTMLElement, message: any}[],
|
||||
inputFilter: MyInputMessagesFilter,
|
||||
searchGroup?: SearchGroup
|
||||
};
|
||||
|
||||
export default class AppSearchSuper {
|
||||
public tabs: {[t in SearchSuperType]: HTMLDivElement} = {} as any;
|
||||
|
||||
@ -655,6 +664,217 @@ export default class AppSearchSuper {
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
private processEmptyFilter({message, searchGroup}: ProcessSearchSuperResult) {
|
||||
const {dialog, dom} = appDialogsManager.addDialogNew({
|
||||
dialog: message.peerId,
|
||||
container: searchGroup.list,
|
||||
drawStatus: false,
|
||||
avatarSize: 54
|
||||
});
|
||||
|
||||
appDialogsManager.setLastMessage(dialog, message, dom, this.searchContext.query);
|
||||
}
|
||||
|
||||
private processPhotoVideoFilter({message, promises, middleware, elemsToAppend}: ProcessSearchSuperResult) {
|
||||
const media = appMessagesManager.getMediaFromMessage(message);
|
||||
|
||||
const div = document.createElement('div');
|
||||
div.classList.add('grid-item');
|
||||
//this.log(message, photo);
|
||||
|
||||
let wrapped: ReturnType<typeof wrapPhoto>;
|
||||
const size = appPhotosManager.choosePhotoSize(media, 200, 200);
|
||||
if(media._ !== 'photo') {
|
||||
wrapped = wrapVideo({
|
||||
doc: media,
|
||||
message,
|
||||
container: div,
|
||||
boxWidth: 0,
|
||||
boxHeight: 0,
|
||||
lazyLoadQueue: this.lazyLoadQueue,
|
||||
middleware,
|
||||
onlyPreview: true,
|
||||
withoutPreloader: true,
|
||||
noPlayButton: true,
|
||||
size
|
||||
}).thumb;
|
||||
} else {
|
||||
wrapped = wrapPhoto({
|
||||
photo: media,
|
||||
message,
|
||||
container: div,
|
||||
boxWidth: 0,
|
||||
boxHeight: 0,
|
||||
lazyLoadQueue: this.lazyLoadQueue,
|
||||
middleware,
|
||||
withoutPreloader: true,
|
||||
noBlur: true,
|
||||
size
|
||||
});
|
||||
}
|
||||
|
||||
[wrapped.images.thumb, wrapped.images.full].filter(Boolean).forEach(image => {
|
||||
image.classList.add('grid-item-media');
|
||||
});
|
||||
|
||||
promises.push(wrapped.loadPromises.thumb);
|
||||
|
||||
elemsToAppend.push({element: div, message});
|
||||
}
|
||||
|
||||
private processDocumentFilter({message, elemsToAppend, inputFilter}: ProcessSearchSuperResult) {
|
||||
const document = appMessagesManager.getMediaFromMessage(message);
|
||||
const showSender = this.showSender || (['voice', 'round'] as MyDocument['type'][]).includes(document.type);
|
||||
const div = wrapDocument({
|
||||
message,
|
||||
withTime: !showSender,
|
||||
fontWeight: 400,
|
||||
voiceAsMusic: true,
|
||||
showSender,
|
||||
searchContext: this.copySearchContext(inputFilter),
|
||||
lazyLoadQueue: this.lazyLoadQueue,
|
||||
noAutoDownload: true
|
||||
});
|
||||
|
||||
if((['audio', 'voice', 'round'] as MyDocument['type'][]).includes(document.type)) {
|
||||
div.classList.add('audio-48');
|
||||
}
|
||||
|
||||
elemsToAppend.push({element: div, message});
|
||||
}
|
||||
|
||||
private processUrlFilter({message, promises, middleware, elemsToAppend}: ProcessSearchSuperResult) {
|
||||
let webpage = (message.media as MessageMedia.messageMediaWebPage)?.webpage as WebPage.webPage;
|
||||
|
||||
if(!webpage) {
|
||||
const entity = message.totalEntities ? message.totalEntities.find((e: any) => e._ === 'messageEntityUrl' || e._ === 'messageEntityTextUrl') : null;
|
||||
let url: string, display_url: string, sliced: string;
|
||||
|
||||
if(!entity) {
|
||||
//this.log.error('NO ENTITY:', message);
|
||||
const match = RichTextProcessor.matchUrl(message.message);
|
||||
if(!match) {
|
||||
//this.log.error('NO ENTITY AND NO MATCH:', message);
|
||||
return;
|
||||
}
|
||||
|
||||
url = match[0];
|
||||
} else {
|
||||
sliced = message.message.slice(entity.offset, entity.offset + entity.length);
|
||||
}
|
||||
|
||||
if(entity?._ === 'messageEntityTextUrl') {
|
||||
url = entity.url;
|
||||
//display_url = sliced;
|
||||
} else {
|
||||
url = url || sliced;
|
||||
}
|
||||
|
||||
display_url = url;
|
||||
|
||||
const same = message.message === url;
|
||||
if(!url.match(/^(ftp|http|https):\/\//)) {
|
||||
display_url = 'https://' + url;
|
||||
url = url.includes('@') ? url : 'https://' + url;
|
||||
}
|
||||
|
||||
display_url = new URL(display_url).hostname;
|
||||
|
||||
webpage = {
|
||||
_: 'webPage',
|
||||
url,
|
||||
display_url,
|
||||
id: '',
|
||||
hash: 0
|
||||
};
|
||||
|
||||
if(!same) {
|
||||
webpage.description = message.message;
|
||||
webpage.rDescription = RichTextProcessor.wrapRichText(limitSymbols(message.message, 150, 180));
|
||||
}
|
||||
}
|
||||
|
||||
let previewDiv = document.createElement('div');
|
||||
previewDiv.classList.add('preview', 'row-media');
|
||||
|
||||
//this.log('wrapping webpage', webpage);
|
||||
|
||||
if(webpage.photo) {
|
||||
const res = wrapPhoto({
|
||||
container: previewDiv,
|
||||
message: null,
|
||||
photo: webpage.photo as Photo.photo,
|
||||
boxWidth: 0,
|
||||
boxHeight: 0,
|
||||
withoutPreloader: true,
|
||||
lazyLoadQueue: this.lazyLoadQueue,
|
||||
middleware,
|
||||
size: appPhotosManager.choosePhotoSize(webpage.photo as Photo.photo, 60, 60, false),
|
||||
loadPromises: promises,
|
||||
noBlur: true
|
||||
});
|
||||
} else {
|
||||
previewDiv.classList.add('empty');
|
||||
previewDiv.innerHTML = RichTextProcessor.getAbbreviation(webpage.title || webpage.display_url || webpage.description || webpage.url, true);
|
||||
}
|
||||
|
||||
let title = webpage.rTitle || '';
|
||||
let subtitle = webpage.rDescription || '';
|
||||
|
||||
const subtitleFragment = htmlToDocumentFragment(subtitle);
|
||||
const aFragment = htmlToDocumentFragment(RichTextProcessor.wrapRichText(webpage.url || ''));
|
||||
const a = aFragment.firstElementChild;
|
||||
if(a instanceof HTMLAnchorElement) {
|
||||
try { // can have 'URIError: URI malformed'
|
||||
a.innerText = decodeURIComponent(a.href);
|
||||
} catch(err) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(subtitleFragment.firstChild) {
|
||||
subtitleFragment.append('\n');
|
||||
}
|
||||
|
||||
subtitleFragment.append(a);
|
||||
|
||||
if(this.showSender) {
|
||||
subtitleFragment.append('\n', appMessagesManager.wrapSenderToPeer(message));
|
||||
}
|
||||
|
||||
if(!title) {
|
||||
//title = new URL(webpage.url).hostname;
|
||||
title = RichTextProcessor.wrapPlainText(webpage.display_url.split('/', 1)[0]);
|
||||
}
|
||||
|
||||
const row = new Row({
|
||||
title,
|
||||
titleRight: appMessagesManager.wrapSentTime(message),
|
||||
subtitle: subtitleFragment,
|
||||
havePadding: true,
|
||||
clickable: true,
|
||||
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}
|
||||
`); */
|
||||
|
||||
if(row.container.innerText.trim().length) {
|
||||
elemsToAppend.push({element: row.container, message});
|
||||
}
|
||||
}
|
||||
|
||||
public async performSearchResult(messages: any[], mediaTab: SearchSuperMediaTab, append = true) {
|
||||
const elemsToAppend: {element: HTMLElement, message: any}[] = [];
|
||||
@ -674,73 +894,26 @@ export default class AppSearchSuper {
|
||||
searchGroup = this.searchGroups.messages;
|
||||
}
|
||||
|
||||
const options: ProcessSearchSuperResult = {
|
||||
elemsToAppend,
|
||||
inputFilter,
|
||||
message: undefined,
|
||||
middleware,
|
||||
promises,
|
||||
searchGroup
|
||||
};
|
||||
|
||||
let processCallback: (options: ProcessSearchSuperResult) => any;
|
||||
|
||||
// https://core.telegram.org/type/MessagesFilter
|
||||
switch(inputFilter) {
|
||||
case 'inputMessagesFilterEmpty': {
|
||||
for(const message of messages) {
|
||||
const {dialog, dom} = appDialogsManager.addDialogNew({
|
||||
dialog: message.peerId,
|
||||
container: searchGroup.list,
|
||||
drawStatus: false,
|
||||
avatarSize: 54
|
||||
});
|
||||
appDialogsManager.setLastMessage(dialog, message, dom, this.searchContext.query);
|
||||
}
|
||||
|
||||
if(searchGroup.list.childElementCount) {
|
||||
searchGroup.setActive();
|
||||
}
|
||||
processCallback = this.processEmptyFilter;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'inputMessagesFilterPhotoVideo': {
|
||||
for(const message of messages) {
|
||||
const media = message.media.photo || message.media.document || (message.media.webpage && message.media.webpage.document);
|
||||
|
||||
const div = document.createElement('div');
|
||||
div.classList.add('grid-item');
|
||||
//this.log(message, photo);
|
||||
|
||||
let wrapped: ReturnType<typeof wrapPhoto>;
|
||||
const size = appPhotosManager.choosePhotoSize(media, 200, 200);
|
||||
if(media._ !== 'photo') {
|
||||
wrapped = wrapVideo({
|
||||
doc: media,
|
||||
message,
|
||||
container: div,
|
||||
boxWidth: 0,
|
||||
boxHeight: 0,
|
||||
lazyLoadQueue: this.lazyLoadQueue,
|
||||
middleware,
|
||||
onlyPreview: true,
|
||||
withoutPreloader: true,
|
||||
noPlayButton: true,
|
||||
size
|
||||
}).thumb;
|
||||
} else {
|
||||
wrapped = wrapPhoto({
|
||||
photo: media,
|
||||
message,
|
||||
container: div,
|
||||
boxWidth: 0,
|
||||
boxHeight: 0,
|
||||
lazyLoadQueue: this.lazyLoadQueue,
|
||||
middleware,
|
||||
withoutPreloader: true,
|
||||
noBlur: true,
|
||||
size
|
||||
});
|
||||
}
|
||||
|
||||
[wrapped.images.thumb, wrapped.images.full].filter(Boolean).forEach(image => {
|
||||
image.classList.add('grid-item-media');
|
||||
});
|
||||
|
||||
promises.push(wrapped.loadPromises.thumb);
|
||||
|
||||
elemsToAppend.push({element: div, message});
|
||||
}
|
||||
|
||||
processCallback = this.processPhotoVideoFilter;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -748,158 +921,12 @@ export default class AppSearchSuper {
|
||||
case 'inputMessagesFilterRoundVoice':
|
||||
case 'inputMessagesFilterMusic':
|
||||
case 'inputMessagesFilterDocument': {
|
||||
for(const message of messages) {
|
||||
const showSender = this.showSender || (['voice', 'round'] as MyDocument['type'][]).includes(message.media.document.type);
|
||||
const div = wrapDocument({
|
||||
message,
|
||||
withTime: !showSender,
|
||||
fontWeight: 400,
|
||||
voiceAsMusic: true,
|
||||
showSender,
|
||||
searchContext: this.copySearchContext(inputFilter),
|
||||
lazyLoadQueue: this.lazyLoadQueue,
|
||||
noAutoDownload: true
|
||||
});
|
||||
|
||||
if((['audio', 'voice', 'round'] as MyDocument['type'][]).includes(message.media.document.type)) {
|
||||
div.classList.add('audio-48');
|
||||
}
|
||||
|
||||
elemsToAppend.push({element: div, message});
|
||||
}
|
||||
processCallback = this.processDocumentFilter;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'inputMessagesFilterUrl': {
|
||||
for(let message of messages) {
|
||||
let webpage: any;
|
||||
|
||||
if(message.media?.webpage && message.media.webpage._ !== 'webPageEmpty') {
|
||||
webpage = message.media.webpage;
|
||||
} else {
|
||||
const entity = message.totalEntities ? message.totalEntities.find((e: any) => e._ === 'messageEntityUrl' || e._ === 'messageEntityTextUrl') : null;
|
||||
let url: string, display_url: string, sliced: string;
|
||||
|
||||
if(!entity) {
|
||||
//this.log.error('NO ENTITY:', message);
|
||||
const match = RichTextProcessor.matchUrl(message.message);
|
||||
if(!match) {
|
||||
//this.log.error('NO ENTITY AND NO MATCH:', message);
|
||||
continue;
|
||||
}
|
||||
|
||||
url = match[0];
|
||||
} else {
|
||||
sliced = message.message.slice(entity.offset, entity.offset + entity.length);
|
||||
}
|
||||
|
||||
if(entity?._ === 'messageEntityTextUrl') {
|
||||
url = entity.url;
|
||||
//display_url = sliced;
|
||||
} else {
|
||||
url = url || sliced;
|
||||
}
|
||||
|
||||
display_url = url;
|
||||
|
||||
const same = message.message === url;
|
||||
if(!url.match(/^(ftp|http|https):\/\//)) {
|
||||
display_url = 'https://' + url;
|
||||
url = url.includes('@') ? url : 'https://' + url;
|
||||
}
|
||||
|
||||
display_url = new URL(display_url).hostname;
|
||||
|
||||
webpage = {
|
||||
url,
|
||||
display_url
|
||||
};
|
||||
|
||||
if(!same) {
|
||||
webpage.description = message.message;
|
||||
webpage.rDescription = RichTextProcessor.wrapRichText(limitSymbols(message.message, 150, 180));
|
||||
}
|
||||
}
|
||||
|
||||
let div = document.createElement('div');
|
||||
|
||||
let previewDiv = document.createElement('div');
|
||||
previewDiv.classList.add('preview', 'row-media');
|
||||
|
||||
//this.log('wrapping webpage', webpage);
|
||||
|
||||
if(webpage.photo) {
|
||||
const res = wrapPhoto({
|
||||
container: previewDiv,
|
||||
message: null,
|
||||
photo: webpage.photo,
|
||||
boxWidth: 0,
|
||||
boxHeight: 0,
|
||||
withoutPreloader: true,
|
||||
lazyLoadQueue: this.lazyLoadQueue,
|
||||
middleware,
|
||||
size: appPhotosManager.choosePhotoSize(webpage.photo, 60, 60, false),
|
||||
loadPromises: promises,
|
||||
noBlur: true
|
||||
});
|
||||
} else {
|
||||
previewDiv.classList.add('empty');
|
||||
previewDiv.innerHTML = RichTextProcessor.getAbbreviation(webpage.title || webpage.display_url || webpage.description || webpage.url, true);
|
||||
}
|
||||
|
||||
let title = webpage.rTitle || '';
|
||||
let subtitle = webpage.rDescription || '';
|
||||
|
||||
const subtitleFragment = htmlToDocumentFragment(subtitle);
|
||||
const aFragment = htmlToDocumentFragment(RichTextProcessor.wrapRichText(webpage.url || ''));
|
||||
const a = aFragment.firstElementChild;
|
||||
if(a instanceof HTMLAnchorElement) {
|
||||
a.innerText = decodeURIComponent(a.href);
|
||||
}
|
||||
|
||||
if(subtitleFragment.firstChild) {
|
||||
subtitleFragment.append('\n');
|
||||
}
|
||||
|
||||
subtitleFragment.append(a);
|
||||
|
||||
if(this.showSender) {
|
||||
subtitleFragment.append('\n', appMessagesManager.wrapSenderToPeer(message));
|
||||
}
|
||||
|
||||
if(!title) {
|
||||
//title = new URL(webpage.url).hostname;
|
||||
title = RichTextProcessor.wrapPlainText(webpage.display_url.split('/', 1)[0]);
|
||||
}
|
||||
|
||||
const row = new Row({
|
||||
title,
|
||||
titleRight: appMessagesManager.wrapSentTime(message),
|
||||
subtitle: subtitleFragment,
|
||||
havePadding: true,
|
||||
clickable: true,
|
||||
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}
|
||||
`); */
|
||||
|
||||
if(row.container.innerText.trim().length) {
|
||||
elemsToAppend.push({element: row.container, message});
|
||||
}
|
||||
}
|
||||
|
||||
processCallback = this.processUrlFilter;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -908,6 +935,23 @@ export default class AppSearchSuper {
|
||||
break;
|
||||
}
|
||||
|
||||
if(processCallback) {
|
||||
processCallback = processCallback.bind(this);
|
||||
|
||||
for(const message of messages) {
|
||||
try {
|
||||
options.message = message;
|
||||
processCallback(options);
|
||||
} catch(err) {
|
||||
this.log.error('error rendering filter', inputFilter, options, message, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(searchGroup && searchGroup.list.childElementCount) {
|
||||
searchGroup.setActive();
|
||||
}
|
||||
|
||||
if(this.loadMutex) {
|
||||
promises.push(this.loadMutex);
|
||||
}
|
||||
@ -1163,7 +1207,7 @@ export default class AppSearchSuper {
|
||||
}
|
||||
|
||||
promise.then(() => {
|
||||
appImManager.setInnerPeer(peerId);
|
||||
appImManager.setInnerPeer({peerId});
|
||||
});
|
||||
});
|
||||
mediaTab.contentTab.append(this.membersList.list);
|
||||
|
@ -1011,7 +1011,9 @@ export default class ChatBubbles {
|
||||
|
||||
const contactDiv: HTMLElement = findUpClassName(target, 'contact');
|
||||
if(contactDiv) {
|
||||
this.chat.appImManager.setInnerPeer(contactDiv.dataset.peerId.toPeerId());
|
||||
this.chat.appImManager.setInnerPeer({
|
||||
peerId: contactDiv.dataset.peerId.toPeerId()
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1035,7 +1037,11 @@ export default class ChatBubbles {
|
||||
const replies = message.replies;
|
||||
if(replies) {
|
||||
this.appMessagesManager.getDiscussionMessage(this.peerId, message.mid).then(message => {
|
||||
this.chat.appImManager.setInnerPeer(replies.channel_id.toPeerId(true), undefined, 'discussion', (message as MyMessage).mid);
|
||||
this.chat.appImManager.setInnerPeer({
|
||||
peerId: replies.channel_id.toPeerId(true),
|
||||
type: 'discussion',
|
||||
threadId: (message as MyMessage).mid
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1064,11 +1070,14 @@ export default class ChatBubbles {
|
||||
if(savedFrom) {
|
||||
const [peerId, mid] = savedFrom.split('_');
|
||||
|
||||
this.chat.appImManager.setInnerPeer(peerId.toPeerId(), +mid);
|
||||
this.chat.appImManager.setInnerPeer({
|
||||
peerId: peerId.toPeerId(),
|
||||
lastMsgId: +mid
|
||||
});
|
||||
} else {
|
||||
const peerId = peerIdStr.toPeerId();
|
||||
if(peerId !== NULL_PEER_ID) {
|
||||
this.chat.appImManager.setInnerPeer(peerId);
|
||||
this.chat.appImManager.setInnerPeer({peerId});
|
||||
} else {
|
||||
toast(I18n.format('HidAccount', true));
|
||||
}
|
||||
@ -1213,7 +1222,10 @@ export default class ChatBubbles {
|
||||
const savedFrom = bubble.dataset.savedFrom;
|
||||
const [peerId, mid] = savedFrom.split('_');
|
||||
////this.log('savedFrom', peerId, msgID);
|
||||
this.chat.appImManager.setInnerPeer(peerId.toPeerId(), +mid);
|
||||
this.chat.appImManager.setInnerPeer({
|
||||
peerId: peerId.toPeerId(),
|
||||
lastMsgId: +mid
|
||||
});
|
||||
return;
|
||||
} else if(target.classList.contains('forward')) {
|
||||
const mid = +bubble.dataset.mid;
|
||||
@ -1240,7 +1252,12 @@ export default class ChatBubbles {
|
||||
const replyToPeerId = message.reply_to.reply_to_peer_id ? this.appPeersManager.getPeerId(message.reply_to.reply_to_peer_id) : this.peerId;
|
||||
const replyToMid = message.reply_to.reply_to_msg_id;
|
||||
|
||||
this.chat.appImManager.setInnerPeer(replyToPeerId, replyToMid, this.chat.type, this.chat.threadId);
|
||||
this.chat.appImManager.setInnerPeer({
|
||||
peerId: replyToPeerId,
|
||||
lastMsgId: replyToMid,
|
||||
type: this.chat.type,
|
||||
threadId: this.chat.threadId
|
||||
});
|
||||
|
||||
/* if(this.chat.type === 'discussion') {
|
||||
this.chat.appImManager.setMessageId(, originalMessageId);
|
||||
|
@ -223,7 +223,7 @@ export default class Chat extends EventListenerBase<{
|
||||
|
||||
this.bubbles.listenerSetter.add(rootScope)('dialog_drop', (e) => {
|
||||
if(e.peerId === this.peerId) {
|
||||
this.appImManager.setPeer(NULL_PEER_ID);
|
||||
this.appImManager.setPeer();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -271,8 +271,6 @@ export default class Chat extends EventListenerBase<{
|
||||
if(!samePeer) {
|
||||
rootScope.dispatchEvent('peer_changing', this);
|
||||
this.peerId = peerId;
|
||||
this.noForwards = this.appPeersManager.noForwards(peerId);
|
||||
this.container.classList.toggle('no-forwards', this.noForwards);
|
||||
} else if(this.setPeerPromise) {
|
||||
return;
|
||||
}
|
||||
@ -297,6 +295,9 @@ export default class Chat extends EventListenerBase<{
|
||||
searchTab.close();
|
||||
}
|
||||
|
||||
this.noForwards = this.appPeersManager.noForwards(peerId);
|
||||
this.container.classList.toggle('no-forwards', this.noForwards);
|
||||
|
||||
appSidebarRight.sharedMediaTab.setPeer(peerId, this.threadId);
|
||||
this.input.clearHelper(); // костыль
|
||||
this.selection.cleanup(); // TODO: REFACTOR !!!!!!
|
||||
|
@ -805,7 +805,7 @@ export default class ChatInput {
|
||||
const peerId = this.chat.peerId;
|
||||
|
||||
new PopupPinMessage(peerId, 0, true, () => {
|
||||
this.chat.appImManager.setPeer(NULL_PEER_ID); // * close tab
|
||||
this.chat.appImManager.setPeer(); // * close tab
|
||||
|
||||
// ! костыль, это скроет закреплённые сообщения сразу, вместо того, чтобы ждать пока анимация перехода закончится
|
||||
const originalChat = this.chat.appImManager.chat;
|
||||
|
@ -202,12 +202,12 @@ export default class ChatTopbar {
|
||||
} else {
|
||||
const peerId = container.dataset.peerId.toPeerId();
|
||||
const searchContext = appMediaPlaybackController.getSearchContext();
|
||||
this.chat.appImManager.setInnerPeer(
|
||||
this.chat.appImManager.setInnerPeer({
|
||||
peerId,
|
||||
mid,
|
||||
searchContext.isScheduled ? 'scheduled' : (searchContext.threadId ? 'discussion' : undefined),
|
||||
searchContext.threadId
|
||||
);
|
||||
lastMsgId: mid,
|
||||
type: searchContext.isScheduled ? 'scheduled' : (searchContext.threadId ? 'discussion' : undefined),
|
||||
threadId: searchContext.threadId
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if(mediaSizes.activeScreen === ScreenSize.medium && document.body.classList.contains(LEFT_COLUMN_ACTIVE_CLASSNAME)) {
|
||||
@ -228,7 +228,7 @@ export default class ChatTopbar {
|
||||
//const item = appNavigationController.findItemByType('chat');
|
||||
// * return manually to chat by arrow, since can't get back to
|
||||
if(mediaSizes.activeScreen === ScreenSize.medium && document.body.classList.contains(LEFT_COLUMN_ACTIVE_CLASSNAME)) {
|
||||
this.chat.appImManager.setPeer(this.peerId);
|
||||
this.chat.appImManager.setPeer({peerId: this.peerId});
|
||||
} else {
|
||||
const isFirstChat = this.chat.appImManager.chats.indexOf(this.chat) === 0;
|
||||
appNavigationController.back(isFirstChat ? 'im' : 'chat');
|
||||
@ -337,7 +337,9 @@ export default class ChatTopbar {
|
||||
const middleware = this.chat.bubbles.getMiddleware();
|
||||
this.appProfileManager.getChannelFull(this.peerId.toChatId()).then(channelFull => {
|
||||
if(middleware() && channelFull.linked_chat_id) {
|
||||
this.chat.appImManager.setInnerPeer(channelFull.linked_chat_id.toPeerId(true));
|
||||
this.chat.appImManager.setInnerPeer({
|
||||
peerId: channelFull.linked_chat_id.toPeerId(true)
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -426,7 +428,7 @@ export default class ChatTopbar {
|
||||
resolve();
|
||||
|
||||
this.appMessagesManager.sendOther(peerId, this.appUsersManager.getContactMediaInput(contactPeerId));
|
||||
this.chat.appImManager.setInnerPeer(peerId);
|
||||
this.chat.appImManager.setInnerPeer({peerId});
|
||||
}
|
||||
}, {
|
||||
langKey: 'Cancel',
|
||||
@ -640,7 +642,11 @@ export default class ChatTopbar {
|
||||
}
|
||||
|
||||
public openPinned(byCurrent: boolean) {
|
||||
this.chat.appImManager.setInnerPeer(this.peerId, byCurrent ? +this.pinnedMessage.pinnedMessageContainer.divAndCaption.container.dataset.mid : 0, 'pinned');
|
||||
this.chat.appImManager.setInnerPeer({
|
||||
peerId: this.peerId,
|
||||
lastMsgId: byCurrent ? +this.pinnedMessage.pinnedMessageContainer.divAndCaption.container.dataset.mid : 0,
|
||||
type: 'pinned'
|
||||
});
|
||||
}
|
||||
|
||||
private onResize = () => {
|
||||
@ -748,7 +754,7 @@ export default class ChatTopbar {
|
||||
|
||||
// ! костыль х2, это нужно делать в другом месте
|
||||
if(!count) {
|
||||
this.chat.appImManager.setPeer(NULL_PEER_ID); // * close tab
|
||||
this.chat.appImManager.setPeer(); // * close tab
|
||||
|
||||
// ! костыль, это скроет закреплённые сообщения сразу, вместо того, чтобы ждать пока анимация перехода закончится
|
||||
const originalChat = this.chat.appImManager.chat;
|
||||
|
@ -10,9 +10,12 @@ import rootScope from "../lib/rootScope";
|
||||
import { i18n } from "../lib/langPack";
|
||||
import replaceContent from "../helpers/dom/replaceContent";
|
||||
import appUsersManager from "../lib/appManagers/appUsersManager";
|
||||
import RichTextProcessor from "../lib/richtextprocessor";
|
||||
import { NULL_PEER_ID } from "../lib/mtproto/mtproto_config";
|
||||
|
||||
export type PeerTitleOptions = {
|
||||
peerId: PeerId,
|
||||
peerId?: PeerId,
|
||||
fromName?: string,
|
||||
plainText?: boolean,
|
||||
onlyFirstName?: boolean,
|
||||
dialog?: boolean
|
||||
@ -37,6 +40,7 @@ rootScope.addEventListener('peer_title_edit', (peerId) => {
|
||||
export default class PeerTitle {
|
||||
public element: HTMLElement;
|
||||
public peerId: PeerId;
|
||||
public fromName: string;
|
||||
public plainText = false;
|
||||
public onlyFirstName = false;
|
||||
public dialog = false;
|
||||
@ -54,12 +58,21 @@ export default class PeerTitle {
|
||||
if(options) {
|
||||
for(let i in options) {
|
||||
// @ts-ignore
|
||||
this.element.dataset[i] = options[i] ? '' + (typeof(options[i]) === 'boolean' ? +options[i] : options[i]) : '0';
|
||||
// this.element.dataset[i] = options[i] ? '' + (typeof(options[i]) === 'boolean' ? +options[i] : options[i]) : '0';
|
||||
// @ts-ignore
|
||||
this[i] = options[i];
|
||||
}
|
||||
}
|
||||
|
||||
if(this.fromName !== undefined) {
|
||||
this.element.innerHTML = RichTextProcessor.wrapEmojiText(this.fromName);
|
||||
return;
|
||||
}
|
||||
|
||||
if(this.peerId === undefined) {
|
||||
this.peerId = NULL_PEER_ID;
|
||||
}
|
||||
|
||||
if(this.peerId !== rootScope.myId || !this.dialog) {
|
||||
if(this.peerId.isUser() && appUsersManager.getUser(this.peerId).pFlags.deleted) {
|
||||
replaceContent(this.element, i18n(this.onlyFirstName ? 'Deleted' : 'HiddenName'));
|
||||
|
@ -23,7 +23,7 @@ export default class PopupForward extends PopupPickUser {
|
||||
}
|
||||
}
|
||||
|
||||
appImManager.setInnerPeer(peerId);
|
||||
appImManager.setInnerPeer({peerId});
|
||||
appImManager.chat.input.initMessagesForward(peerIdMids);
|
||||
},
|
||||
placeholder: 'ShareModal.Search.ForwardPlaceholder',
|
||||
|
@ -122,7 +122,9 @@ export class AppSidebarLeft extends SidebarSlider {
|
||||
text: 'SavedMessages',
|
||||
onClick: () => {
|
||||
setTimeout(() => { // menu doesn't close if no timeout (lol)
|
||||
appImManager.setPeer(appImManager.myId);
|
||||
appImManager.setPeer({
|
||||
peerId: appImManager.myId
|
||||
});
|
||||
}, 0);
|
||||
}
|
||||
}, btnArchive, {
|
||||
|
@ -1358,9 +1358,11 @@ export class AppDialogsManager {
|
||||
const peerId = elem.dataset.peerId.toPeerId();
|
||||
const lastMsgId = +elem.dataset.mid || undefined;
|
||||
|
||||
setPeerFunc(peerId, lastMsgId);
|
||||
setPeerFunc({
|
||||
peerId, lastMsgId
|
||||
});
|
||||
} else {
|
||||
setPeerFunc(NULL_PEER_ID);
|
||||
setPeerFunc();
|
||||
}
|
||||
}, {capture: true});
|
||||
|
||||
@ -1641,12 +1643,13 @@ export class AppDialogsManager {
|
||||
}
|
||||
|
||||
private getDialog(dialog: Dialog | PeerId): Dialog {
|
||||
if(typeof(dialog) !== 'object' && dialog) {
|
||||
if(typeof(dialog) !== 'object') {
|
||||
const originalDialog = appMessagesManager.getDialogOnly(dialog);
|
||||
if(!originalDialog) {
|
||||
const peerId = dialog || NULL_PEER_ID;
|
||||
return {
|
||||
peerId: dialog,
|
||||
peer: appPeersManager.getOutputPeer(dialog),
|
||||
peerId,
|
||||
peer: appPeersManager.getOutputPeer(peerId),
|
||||
pFlags: {}
|
||||
} as any;
|
||||
}
|
||||
@ -1712,6 +1715,30 @@ export class AppDialogsManager {
|
||||
this.setCallStatus(dom, !!(chat.pFlags.call_active && chat.pFlags.call_not_empty));
|
||||
}
|
||||
|
||||
/**
|
||||
* use for rendering search result
|
||||
*/
|
||||
public addDialogAndSetLastMessage(options: Omit<Parameters<AppDialogsManager['addDialogNew']>[0], 'dialog'> & {
|
||||
message: MyMessage,
|
||||
peerId: PeerId,
|
||||
query?: string
|
||||
}) {
|
||||
const {peerId, message, query} = options;
|
||||
const ret = appDialogsManager.addDialogNew({
|
||||
...options,
|
||||
...appMessagesManager.getMessageSenderPeerIdOrName(message),
|
||||
dialog: this.getDialog(peerId),
|
||||
});
|
||||
|
||||
this.setLastMessage(ret.dialog, message, ret.dom, query);
|
||||
|
||||
if(message.peerId !== peerId) {
|
||||
ret.dom.listEl.dataset.peerId = '' + message.peerId;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public addDialogNew(options: {
|
||||
dialog: Parameters<AppDialogsManager['addDialog']>[0],
|
||||
container?: Parameters<AppDialogsManager['addDialog']>[1],
|
||||
@ -1723,12 +1750,14 @@ export class AppDialogsManager {
|
||||
avatarSize?: number,
|
||||
autonomous?: boolean,
|
||||
lazyLoadQueue?: LazyLoadQueueIntersector,
|
||||
loadPromises?: Promise<any>[]
|
||||
loadPromises?: Promise<any>[],
|
||||
fromName?: string
|
||||
}) {
|
||||
return this.addDialog(options.dialog, options.container, options.drawStatus, options.rippleEnabled, options.onlyFirstName, options.meAsSaved, options.append, options.avatarSize, options.autonomous, options.lazyLoadQueue, options.loadPromises);
|
||||
return this.addDialog(options.dialog, options.container, options.drawStatus, options.rippleEnabled, options.onlyFirstName, options.meAsSaved, options.append, options.avatarSize, options.autonomous, options.lazyLoadQueue, options.loadPromises, options.fromName);
|
||||
}
|
||||
|
||||
public addDialog(_dialog: Parameters<AppDialogsManager['getDialog']>[0],
|
||||
public addDialog(
|
||||
_dialog: Parameters<AppDialogsManager['getDialog']>[0],
|
||||
container?: HTMLElement | Scrollable | DocumentFragment | false,
|
||||
drawStatus = true,
|
||||
rippleEnabled = true,
|
||||
@ -1738,7 +1767,9 @@ export class AppDialogsManager {
|
||||
avatarSize = 54,
|
||||
autonomous = !!container,
|
||||
lazyLoadQueue?: LazyLoadQueueIntersector,
|
||||
loadPromises?: Promise<any>[]) {
|
||||
loadPromises?: Promise<any>[],
|
||||
fromName?: string
|
||||
) {
|
||||
const dialog = this.getDialog(_dialog);
|
||||
const peerId = dialog.peerId;
|
||||
|
||||
@ -1746,6 +1777,7 @@ export class AppDialogsManager {
|
||||
avatarEl.loadPromises = loadPromises;
|
||||
avatarEl.lazyLoadQueue = lazyLoadQueue;
|
||||
avatarEl.setAttribute('dialog', meAsSaved ? '1' : '0');
|
||||
if(fromName !== undefined) avatarEl.setAttribute('peer-title', fromName);
|
||||
avatarEl.setAttribute('peer', '' + peerId);
|
||||
avatarEl.classList.add('dialog-avatar', 'avatar-' + avatarSize);
|
||||
|
||||
@ -1764,6 +1796,7 @@ export class AppDialogsManager {
|
||||
|
||||
const peerTitle = new PeerTitle({
|
||||
peerId,
|
||||
fromName,
|
||||
dialog: meAsSaved,
|
||||
onlyFirstName,
|
||||
plainText: false
|
||||
|
@ -43,7 +43,7 @@ import appNavigationController from '../../components/appNavigationController';
|
||||
import appNotificationsManager from './appNotificationsManager';
|
||||
import AppPrivateSearchTab from '../../components/sidebarRight/tabs/search';
|
||||
import I18n, { i18n, join, LangPackKey } from '../langPack';
|
||||
import { ChatInvite, Dialog, SendMessageAction } from '../../layer';
|
||||
import { ChatInvite, Dialog, Message, SendMessageAction } from '../../layer';
|
||||
import { hslaStringToHex } from '../../helpers/color';
|
||||
import { copy, getObjectKeysAndSort } from '../../helpers/object';
|
||||
import { getFilesFromEvent } from '../../helpers/files';
|
||||
@ -79,6 +79,7 @@ import IS_GROUP_CALL_SUPPORTED from '../../environment/groupCallSupport';
|
||||
import appAvatarsManager from './appAvatarsManager';
|
||||
import IS_CALL_SUPPORTED from '../../environment/callSupport';
|
||||
import { CallType } from '../calls/types';
|
||||
import { Modify } from '../../types';
|
||||
|
||||
//console.log('appImManager included33!');
|
||||
|
||||
@ -92,6 +93,19 @@ export type ChatSavedPosition = {
|
||||
top: number
|
||||
};
|
||||
|
||||
export type ChatSetPeerOptions = {
|
||||
peerId?: PeerId,
|
||||
lastMsgId?: number,
|
||||
threadId?: number,
|
||||
startParam?: string
|
||||
};
|
||||
|
||||
export type ChatSetInnerPeerOptions = Modify<ChatSetPeerOptions, {
|
||||
peerId: PeerId
|
||||
}> & {
|
||||
type?: ChatType
|
||||
};
|
||||
|
||||
export class AppImManager {
|
||||
public columnEl = document.getElementById('column-center') as HTMLDivElement;
|
||||
public chatsContainer: HTMLElement;
|
||||
@ -197,7 +211,12 @@ export class AppImManager {
|
||||
if(threadId) threadId = appMessagesIdsManager.generateMessageId(threadId);
|
||||
if(mid) mid = appMessagesIdsManager.generateMessageId(mid); // because mid can come from notification, i.e. server message id
|
||||
|
||||
this.setInnerPeer(peerId, mid, threadId ? 'discussion' : undefined, threadId);
|
||||
this.setInnerPeer({
|
||||
peerId,
|
||||
lastMsgId: mid,
|
||||
type: threadId ? 'discussion' : undefined,
|
||||
threadId
|
||||
});
|
||||
});
|
||||
|
||||
rootScope.addEventListener('peer_changing', (chat) => {
|
||||
@ -374,7 +393,7 @@ export class AppImManager {
|
||||
// pathnameParams: [string, string?],
|
||||
// uriParams: {comment?: number}
|
||||
pathnameParams: ['c', string, string] | [string, string?],
|
||||
uriParams: {thread?: string, comment?: string} | {comment?: string}
|
||||
uriParams: {thread?: string, comment?: string} | {comment?: string, start?: string}
|
||||
}>({
|
||||
name: 'im',
|
||||
callback: async({pathnameParams, uriParams}) => {
|
||||
@ -384,7 +403,7 @@ export class AppImManager {
|
||||
_: INTERNAL_LINK_TYPE.PRIVATE_POST,
|
||||
channel: pathnameParams[1],
|
||||
post: pathnameParams[2],
|
||||
thread: 'thread' in uriParams ? uriParams.thread : undefined,
|
||||
thread: 'thread' in uriParams && uriParams.thread,
|
||||
comment: uriParams.comment
|
||||
};
|
||||
} else {
|
||||
@ -392,7 +411,8 @@ export class AppImManager {
|
||||
_: INTERNAL_LINK_TYPE.MESSAGE,
|
||||
domain: pathnameParams[0],
|
||||
post: pathnameParams[1],
|
||||
comment: uriParams.comment
|
||||
comment: uriParams.comment,
|
||||
start: 'start' in uriParams && uriParams.start
|
||||
};
|
||||
}
|
||||
|
||||
@ -514,7 +534,7 @@ export class AppImManager {
|
||||
}
|
||||
|
||||
if(nextDialog) {
|
||||
this.setPeer(nextDialog.peerId);
|
||||
this.setPeer({peerId: nextDialog.peerId});
|
||||
}
|
||||
} else if(key === 'ArrowUp') {
|
||||
if(!chat.input.editMsgId && chat.input.isInputEmpty()) {
|
||||
@ -606,7 +626,11 @@ export class AppImManager {
|
||||
const threadId = link.thread ? appMessagesIdsManager.generateMessageId(+link.thread) : undefined;
|
||||
|
||||
if(threadId) this.openThread(peerId, postId, threadId);
|
||||
else this.setInnerPeer(peerId, postId);
|
||||
else this.setInnerPeer({
|
||||
peerId,
|
||||
lastMsgId: postId,
|
||||
threadId
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
@ -627,7 +651,9 @@ export class AppImManager {
|
||||
|
||||
if(chatInvite._ === 'chatInviteAlready' ||
|
||||
chatInvite._ === 'chatInvitePeek'/* && chatInvite.expires > tsNow(true) */) {
|
||||
this.setInnerPeer(chatInvite.chat.id.toPeerId(true));
|
||||
this.setInnerPeer({
|
||||
peerId: chatInvite.chat.id.toPeerId(true)
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -719,7 +745,10 @@ export class AppImManager {
|
||||
}
|
||||
|
||||
default: { // peerId
|
||||
this.setInnerPeer(postId ? p.toPeerId(true) : p.toPeerId(), postId);
|
||||
this.setInnerPeer({
|
||||
peerId: postId ? p.toPeerId(true) : p.toPeerId(),
|
||||
lastMsgId: postId
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -730,14 +759,21 @@ export class AppImManager {
|
||||
//location.hash = '';
|
||||
};
|
||||
|
||||
public openUsername(username: string, msgId?: number, threadId?: number, commentId?: number) {
|
||||
public openUsername(username: string, lastMsgId?: number, threadId?: number, commentId?: number) {
|
||||
return appUsersManager.resolveUsername(username).then(peer => {
|
||||
const isUser = peer._ === 'user';
|
||||
const peerId = isUser ? peer.id.toPeerId() : peer.id.toPeerId(true);
|
||||
const peerId = peer.id.toPeerId(!isUser);
|
||||
|
||||
if(threadId) return this.openThread(peerId, msgId, threadId);
|
||||
else if(commentId) return this.openComment(peerId, msgId, commentId);
|
||||
else return this.setInnerPeer(peerId, msgId);
|
||||
if(threadId) {
|
||||
return this.openThread(peerId, lastMsgId, threadId);
|
||||
} else if(commentId) {
|
||||
return this.openComment(peerId, lastMsgId, commentId);
|
||||
}
|
||||
|
||||
return this.setInnerPeer({
|
||||
peerId,
|
||||
lastMsgId
|
||||
});
|
||||
}, (err) => {
|
||||
if(err.type === 'USERNAME_NOT_OCCUPIED') {
|
||||
toastNew({langPackKey: 'NoUsernameFound'});
|
||||
@ -752,10 +788,19 @@ export class AppImManager {
|
||||
*/
|
||||
public openThread(peerId: PeerId, lastMsgId: number, threadId: number) {
|
||||
return appMessagesManager.wrapSingleMessage(peerId, threadId).then(() => {
|
||||
const message = appMessagesManager.getMessageByPeer(peerId, threadId);
|
||||
appMessagesManager.generateThreadServiceStartMessage(message);
|
||||
const message: Message = appMessagesManager.getMessageByPeer(peerId, threadId);
|
||||
if(message._ === 'messageEmpty') {
|
||||
lastMsgId = undefined;
|
||||
} else {
|
||||
appMessagesManager.generateThreadServiceStartMessage(message);
|
||||
}
|
||||
|
||||
return this.setInnerPeer(peerId, lastMsgId, 'discussion', threadId);
|
||||
return this.setInnerPeer({
|
||||
peerId,
|
||||
lastMsgId,
|
||||
threadId,
|
||||
type: 'discussion'
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -1044,7 +1089,7 @@ export class AppImManager {
|
||||
appNavigationController.pushItem({
|
||||
type: 'chat',
|
||||
onPop: (canAnimate) => {
|
||||
this.setPeer(NULL_PEER_ID, undefined, canAnimate);
|
||||
this.setPeer({}, canAnimate);
|
||||
blurActiveElement();
|
||||
}
|
||||
});
|
||||
@ -1270,7 +1315,7 @@ export class AppImManager {
|
||||
type: 'im',
|
||||
onPop: (canAnimate) => {
|
||||
//this.selectTab(prevTabId, !isSafari);
|
||||
this.setPeer(NULL_PEER_ID, undefined, canAnimate);
|
||||
this.setPeer({}, canAnimate);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1382,12 +1427,14 @@ export class AppImManager {
|
||||
}, 250 + 100);
|
||||
}
|
||||
|
||||
public setPeer(peerId: PeerId, lastMsgId?: number, animate?: boolean): boolean {
|
||||
public setPeer(options: ChatSetPeerOptions = {}, animate?: boolean): boolean {
|
||||
if(this.init) {
|
||||
this.init();
|
||||
this.init = null;
|
||||
}
|
||||
|
||||
const {peerId, lastMsgId} = options;
|
||||
|
||||
const chat = this.chat;
|
||||
const chatIndex = this.chats.indexOf(chat);
|
||||
|
||||
@ -1411,7 +1458,7 @@ export class AppImManager {
|
||||
this.spliceChats(0, true, true, spliced);
|
||||
return;
|
||||
} else {
|
||||
const ret = this.setPeer(peerId, lastMsgId);
|
||||
const ret = this.setPeer(options);
|
||||
this.spliceChats(0, false, false, spliced);
|
||||
return ret;
|
||||
}
|
||||
@ -1452,16 +1499,19 @@ export class AppImManager {
|
||||
}
|
||||
}
|
||||
|
||||
public setInnerPeer(peerId: PeerId, lastMsgId?: number, type: ChatType = 'chat', threadId?: number) {
|
||||
public setInnerPeer(options: ChatSetInnerPeerOptions) {
|
||||
const {peerId} = options;
|
||||
if(peerId === NULL_PEER_ID || !peerId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const type = options.type ??= 'chat';
|
||||
|
||||
// * prevent opening already opened peer
|
||||
const existingIndex = this.chats.findIndex(chat => chat.peerId === peerId && chat.type === type);
|
||||
if(existingIndex !== -1) {
|
||||
this.spliceChats(existingIndex + 1);
|
||||
return this.setPeer(peerId, lastMsgId);
|
||||
return this.setPeer(options);
|
||||
}
|
||||
|
||||
const oldChat = this.chat;
|
||||
@ -1473,8 +1523,8 @@ export class AppImManager {
|
||||
if(type) {
|
||||
chat.setType(type);
|
||||
|
||||
if(threadId) {
|
||||
chat.threadId = threadId;
|
||||
if(options.threadId) {
|
||||
chat.threadId = options.threadId;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1482,11 +1532,14 @@ export class AppImManager {
|
||||
|
||||
//this.chatsSelectTab(chat.container);
|
||||
|
||||
return this.setPeer(peerId, lastMsgId);
|
||||
return this.setPeer(options);
|
||||
}
|
||||
|
||||
public openScheduled(peerId: PeerId) {
|
||||
this.setInnerPeer(peerId, undefined, 'scheduled');
|
||||
this.setInnerPeer({
|
||||
peerId,
|
||||
type: 'scheduled'
|
||||
});
|
||||
}
|
||||
|
||||
private getTypingElement(action: SendMessageAction) {
|
||||
|
@ -2357,8 +2357,8 @@ export class AppMessagesManager {
|
||||
//return Object.keys(this.groupedMessagesStorage[grouped_id]).map(id => +id).sort((a, b) => a - b);
|
||||
}
|
||||
|
||||
public getMidsByMessage(message: Message.message) {
|
||||
if(message?.grouped_id) return this.getMidsByAlbum(message.grouped_id);
|
||||
public getMidsByMessage(message: Message) {
|
||||
if((message as Message.message)?.grouped_id) return this.getMidsByAlbum((message as Message.message).grouped_id);
|
||||
else return [message.mid];
|
||||
}
|
||||
|
||||
@ -2949,7 +2949,7 @@ export class AppMessagesManager {
|
||||
fromMe ?
|
||||
i18n('FromYou') :
|
||||
new PeerTitle({
|
||||
peerId: message.fromId,
|
||||
...this.getMessageSenderPeerIdOrName(message),
|
||||
dialog: message.peerId === rootScope.myId
|
||||
}).element
|
||||
);
|
||||
@ -2962,6 +2962,18 @@ export class AppMessagesManager {
|
||||
return senderTitle;
|
||||
}
|
||||
|
||||
public getMessageSenderPeerIdOrName(message: MyMessage) {
|
||||
if(message.fromId) {
|
||||
return {
|
||||
peerId: message.fromId
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
fromName: (message as Message.message).fwd_from?.from_name
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public wrapSentTime(message: MyMessage) {
|
||||
const el: HTMLElement = document.createElement('span');
|
||||
el.classList.add('sent-time');
|
||||
@ -3844,7 +3856,7 @@ export class AppMessagesManager {
|
||||
this.getDiscussionMessage(peerId, mid);
|
||||
}
|
||||
|
||||
public generateThreadServiceStartMessage(message: Message.message) {
|
||||
public generateThreadServiceStartMessage(message: Message.message | Message.messageService) {
|
||||
const threadKey = message.peerId + '_' + message.mid;
|
||||
if(this.threadsServiceMessagesIdsStorage[threadKey]) return;
|
||||
|
||||
|
@ -19,7 +19,8 @@ export namespace InternalLink {
|
||||
_: INTERNAL_LINK_TYPE.MESSAGE,
|
||||
domain: string,
|
||||
post?: string,
|
||||
comment?: string
|
||||
comment?: string,
|
||||
start?: string
|
||||
}
|
||||
|
||||
export interface InternalLinkPrivatePost {
|
||||
|
Loading…
x
Reference in New Issue
Block a user