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;
|
const searchGroup = this.searchGroups.messages;
|
||||||
|
|
||||||
history.forEach((message) => {
|
history.forEach((message) => {
|
||||||
const peerId = this.peerId ? message.fromId : message.peerId;
|
try {
|
||||||
const {dialog, dom} = appDialogsManager.addDialogNew({
|
const peerId = this.peerId ? message.fromId : message.peerId;
|
||||||
dialog: peerId,
|
appDialogsManager.addDialogAndSetLastMessage({
|
||||||
container: this.scrollable/* searchGroup.list */,
|
peerId,
|
||||||
drawStatus: false,
|
container: this.scrollable/* searchGroup.list */,
|
||||||
avatarSize: 54,
|
drawStatus: false,
|
||||||
meAsSaved: false
|
avatarSize: 54,
|
||||||
});
|
meAsSaved: false,
|
||||||
|
message,
|
||||||
if(message.peerId !== peerId) {
|
query
|
||||||
dom.listEl.dataset.peerId = '' + message.peerId;
|
});
|
||||||
|
} catch(err) {
|
||||||
|
console.error('[appSearch] render search result', err);
|
||||||
}
|
}
|
||||||
|
|
||||||
appDialogsManager.setLastMessage(dialog, message, dom, query);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
searchGroup.toggle();
|
searchGroup.toggle();
|
||||||
|
@ -28,7 +28,7 @@ import I18n, { LangPackKey, i18n } from "../lib/langPack";
|
|||||||
import findUpClassName from "../helpers/dom/findUpClassName";
|
import findUpClassName from "../helpers/dom/findUpClassName";
|
||||||
import { getMiddleware } from "../helpers/middleware";
|
import { getMiddleware } from "../helpers/middleware";
|
||||||
import appProfileManager from "../lib/appManagers/appProfileManager";
|
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 SortedUserList from "./sortedUserList";
|
||||||
import findUpTag from "../helpers/dom/findUpTag";
|
import findUpTag from "../helpers/dom/findUpTag";
|
||||||
import appSidebarRight from "./sidebarRight";
|
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 {
|
export default class AppSearchSuper {
|
||||||
public tabs: {[t in SearchSuperType]: HTMLDivElement} = {} as any;
|
public tabs: {[t in SearchSuperType]: HTMLDivElement} = {} as any;
|
||||||
|
|
||||||
@ -655,6 +664,217 @@ export default class AppSearchSuper {
|
|||||||
|
|
||||||
return filtered;
|
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) {
|
public async performSearchResult(messages: any[], mediaTab: SearchSuperMediaTab, append = true) {
|
||||||
const elemsToAppend: {element: HTMLElement, message: any}[] = [];
|
const elemsToAppend: {element: HTMLElement, message: any}[] = [];
|
||||||
@ -674,73 +894,26 @@ export default class AppSearchSuper {
|
|||||||
searchGroup = this.searchGroups.messages;
|
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
|
// https://core.telegram.org/type/MessagesFilter
|
||||||
switch(inputFilter) {
|
switch(inputFilter) {
|
||||||
case 'inputMessagesFilterEmpty': {
|
case 'inputMessagesFilterEmpty': {
|
||||||
for(const message of messages) {
|
processCallback = this.processEmptyFilter;
|
||||||
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();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'inputMessagesFilterPhotoVideo': {
|
case 'inputMessagesFilterPhotoVideo': {
|
||||||
for(const message of messages) {
|
processCallback = this.processPhotoVideoFilter;
|
||||||
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});
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -748,158 +921,12 @@ export default class AppSearchSuper {
|
|||||||
case 'inputMessagesFilterRoundVoice':
|
case 'inputMessagesFilterRoundVoice':
|
||||||
case 'inputMessagesFilterMusic':
|
case 'inputMessagesFilterMusic':
|
||||||
case 'inputMessagesFilterDocument': {
|
case 'inputMessagesFilterDocument': {
|
||||||
for(const message of messages) {
|
processCallback = this.processDocumentFilter;
|
||||||
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});
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'inputMessagesFilterUrl': {
|
case 'inputMessagesFilterUrl': {
|
||||||
for(let message of messages) {
|
processCallback = this.processUrlFilter;
|
||||||
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});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -908,6 +935,23 @@ export default class AppSearchSuper {
|
|||||||
break;
|
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) {
|
if(this.loadMutex) {
|
||||||
promises.push(this.loadMutex);
|
promises.push(this.loadMutex);
|
||||||
}
|
}
|
||||||
@ -1163,7 +1207,7 @@ export default class AppSearchSuper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
promise.then(() => {
|
promise.then(() => {
|
||||||
appImManager.setInnerPeer(peerId);
|
appImManager.setInnerPeer({peerId});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
mediaTab.contentTab.append(this.membersList.list);
|
mediaTab.contentTab.append(this.membersList.list);
|
||||||
|
@ -1011,7 +1011,9 @@ export default class ChatBubbles {
|
|||||||
|
|
||||||
const contactDiv: HTMLElement = findUpClassName(target, 'contact');
|
const contactDiv: HTMLElement = findUpClassName(target, 'contact');
|
||||||
if(contactDiv) {
|
if(contactDiv) {
|
||||||
this.chat.appImManager.setInnerPeer(contactDiv.dataset.peerId.toPeerId());
|
this.chat.appImManager.setInnerPeer({
|
||||||
|
peerId: contactDiv.dataset.peerId.toPeerId()
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1035,7 +1037,11 @@ export default class ChatBubbles {
|
|||||||
const replies = message.replies;
|
const replies = message.replies;
|
||||||
if(replies) {
|
if(replies) {
|
||||||
this.appMessagesManager.getDiscussionMessage(this.peerId, message.mid).then(message => {
|
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) {
|
if(savedFrom) {
|
||||||
const [peerId, mid] = savedFrom.split('_');
|
const [peerId, mid] = savedFrom.split('_');
|
||||||
|
|
||||||
this.chat.appImManager.setInnerPeer(peerId.toPeerId(), +mid);
|
this.chat.appImManager.setInnerPeer({
|
||||||
|
peerId: peerId.toPeerId(),
|
||||||
|
lastMsgId: +mid
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
const peerId = peerIdStr.toPeerId();
|
const peerId = peerIdStr.toPeerId();
|
||||||
if(peerId !== NULL_PEER_ID) {
|
if(peerId !== NULL_PEER_ID) {
|
||||||
this.chat.appImManager.setInnerPeer(peerId);
|
this.chat.appImManager.setInnerPeer({peerId});
|
||||||
} else {
|
} else {
|
||||||
toast(I18n.format('HidAccount', true));
|
toast(I18n.format('HidAccount', true));
|
||||||
}
|
}
|
||||||
@ -1213,7 +1222,10 @@ export default class ChatBubbles {
|
|||||||
const savedFrom = bubble.dataset.savedFrom;
|
const savedFrom = bubble.dataset.savedFrom;
|
||||||
const [peerId, mid] = savedFrom.split('_');
|
const [peerId, mid] = savedFrom.split('_');
|
||||||
////this.log('savedFrom', peerId, msgID);
|
////this.log('savedFrom', peerId, msgID);
|
||||||
this.chat.appImManager.setInnerPeer(peerId.toPeerId(), +mid);
|
this.chat.appImManager.setInnerPeer({
|
||||||
|
peerId: peerId.toPeerId(),
|
||||||
|
lastMsgId: +mid
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
} else if(target.classList.contains('forward')) {
|
} else if(target.classList.contains('forward')) {
|
||||||
const mid = +bubble.dataset.mid;
|
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 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;
|
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') {
|
/* if(this.chat.type === 'discussion') {
|
||||||
this.chat.appImManager.setMessageId(, originalMessageId);
|
this.chat.appImManager.setMessageId(, originalMessageId);
|
||||||
|
@ -223,7 +223,7 @@ export default class Chat extends EventListenerBase<{
|
|||||||
|
|
||||||
this.bubbles.listenerSetter.add(rootScope)('dialog_drop', (e) => {
|
this.bubbles.listenerSetter.add(rootScope)('dialog_drop', (e) => {
|
||||||
if(e.peerId === this.peerId) {
|
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) {
|
if(!samePeer) {
|
||||||
rootScope.dispatchEvent('peer_changing', this);
|
rootScope.dispatchEvent('peer_changing', this);
|
||||||
this.peerId = peerId;
|
this.peerId = peerId;
|
||||||
this.noForwards = this.appPeersManager.noForwards(peerId);
|
|
||||||
this.container.classList.toggle('no-forwards', this.noForwards);
|
|
||||||
} else if(this.setPeerPromise) {
|
} else if(this.setPeerPromise) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -297,6 +295,9 @@ export default class Chat extends EventListenerBase<{
|
|||||||
searchTab.close();
|
searchTab.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.noForwards = this.appPeersManager.noForwards(peerId);
|
||||||
|
this.container.classList.toggle('no-forwards', this.noForwards);
|
||||||
|
|
||||||
appSidebarRight.sharedMediaTab.setPeer(peerId, this.threadId);
|
appSidebarRight.sharedMediaTab.setPeer(peerId, this.threadId);
|
||||||
this.input.clearHelper(); // костыль
|
this.input.clearHelper(); // костыль
|
||||||
this.selection.cleanup(); // TODO: REFACTOR !!!!!!
|
this.selection.cleanup(); // TODO: REFACTOR !!!!!!
|
||||||
|
@ -805,7 +805,7 @@ export default class ChatInput {
|
|||||||
const peerId = this.chat.peerId;
|
const peerId = this.chat.peerId;
|
||||||
|
|
||||||
new PopupPinMessage(peerId, 0, true, () => {
|
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;
|
const originalChat = this.chat.appImManager.chat;
|
||||||
|
@ -202,12 +202,12 @@ export default class ChatTopbar {
|
|||||||
} else {
|
} else {
|
||||||
const peerId = container.dataset.peerId.toPeerId();
|
const peerId = container.dataset.peerId.toPeerId();
|
||||||
const searchContext = appMediaPlaybackController.getSearchContext();
|
const searchContext = appMediaPlaybackController.getSearchContext();
|
||||||
this.chat.appImManager.setInnerPeer(
|
this.chat.appImManager.setInnerPeer({
|
||||||
peerId,
|
peerId,
|
||||||
mid,
|
lastMsgId: mid,
|
||||||
searchContext.isScheduled ? 'scheduled' : (searchContext.threadId ? 'discussion' : undefined),
|
type: searchContext.isScheduled ? 'scheduled' : (searchContext.threadId ? 'discussion' : undefined),
|
||||||
searchContext.threadId
|
threadId: searchContext.threadId
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(mediaSizes.activeScreen === ScreenSize.medium && document.body.classList.contains(LEFT_COLUMN_ACTIVE_CLASSNAME)) {
|
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');
|
//const item = appNavigationController.findItemByType('chat');
|
||||||
// * return manually to chat by arrow, since can't get back to
|
// * 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)) {
|
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 {
|
} else {
|
||||||
const isFirstChat = this.chat.appImManager.chats.indexOf(this.chat) === 0;
|
const isFirstChat = this.chat.appImManager.chats.indexOf(this.chat) === 0;
|
||||||
appNavigationController.back(isFirstChat ? 'im' : 'chat');
|
appNavigationController.back(isFirstChat ? 'im' : 'chat');
|
||||||
@ -337,7 +337,9 @@ export default class ChatTopbar {
|
|||||||
const middleware = this.chat.bubbles.getMiddleware();
|
const middleware = this.chat.bubbles.getMiddleware();
|
||||||
this.appProfileManager.getChannelFull(this.peerId.toChatId()).then(channelFull => {
|
this.appProfileManager.getChannelFull(this.peerId.toChatId()).then(channelFull => {
|
||||||
if(middleware() && channelFull.linked_chat_id) {
|
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();
|
resolve();
|
||||||
|
|
||||||
this.appMessagesManager.sendOther(peerId, this.appUsersManager.getContactMediaInput(contactPeerId));
|
this.appMessagesManager.sendOther(peerId, this.appUsersManager.getContactMediaInput(contactPeerId));
|
||||||
this.chat.appImManager.setInnerPeer(peerId);
|
this.chat.appImManager.setInnerPeer({peerId});
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
langKey: 'Cancel',
|
langKey: 'Cancel',
|
||||||
@ -640,7 +642,11 @@ export default class ChatTopbar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public openPinned(byCurrent: boolean) {
|
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 = () => {
|
private onResize = () => {
|
||||||
@ -748,7 +754,7 @@ export default class ChatTopbar {
|
|||||||
|
|
||||||
// ! костыль х2, это нужно делать в другом месте
|
// ! костыль х2, это нужно делать в другом месте
|
||||||
if(!count) {
|
if(!count) {
|
||||||
this.chat.appImManager.setPeer(NULL_PEER_ID); // * close tab
|
this.chat.appImManager.setPeer(); // * close tab
|
||||||
|
|
||||||
// ! костыль, это скроет закреплённые сообщения сразу, вместо того, чтобы ждать пока анимация перехода закончится
|
// ! костыль, это скроет закреплённые сообщения сразу, вместо того, чтобы ждать пока анимация перехода закончится
|
||||||
const originalChat = this.chat.appImManager.chat;
|
const originalChat = this.chat.appImManager.chat;
|
||||||
|
@ -10,9 +10,12 @@ import rootScope from "../lib/rootScope";
|
|||||||
import { i18n } from "../lib/langPack";
|
import { i18n } from "../lib/langPack";
|
||||||
import replaceContent from "../helpers/dom/replaceContent";
|
import replaceContent from "../helpers/dom/replaceContent";
|
||||||
import appUsersManager from "../lib/appManagers/appUsersManager";
|
import appUsersManager from "../lib/appManagers/appUsersManager";
|
||||||
|
import RichTextProcessor from "../lib/richtextprocessor";
|
||||||
|
import { NULL_PEER_ID } from "../lib/mtproto/mtproto_config";
|
||||||
|
|
||||||
export type PeerTitleOptions = {
|
export type PeerTitleOptions = {
|
||||||
peerId: PeerId,
|
peerId?: PeerId,
|
||||||
|
fromName?: string,
|
||||||
plainText?: boolean,
|
plainText?: boolean,
|
||||||
onlyFirstName?: boolean,
|
onlyFirstName?: boolean,
|
||||||
dialog?: boolean
|
dialog?: boolean
|
||||||
@ -37,6 +40,7 @@ rootScope.addEventListener('peer_title_edit', (peerId) => {
|
|||||||
export default class PeerTitle {
|
export default class PeerTitle {
|
||||||
public element: HTMLElement;
|
public element: HTMLElement;
|
||||||
public peerId: PeerId;
|
public peerId: PeerId;
|
||||||
|
public fromName: string;
|
||||||
public plainText = false;
|
public plainText = false;
|
||||||
public onlyFirstName = false;
|
public onlyFirstName = false;
|
||||||
public dialog = false;
|
public dialog = false;
|
||||||
@ -54,12 +58,21 @@ export default class PeerTitle {
|
|||||||
if(options) {
|
if(options) {
|
||||||
for(let i in options) {
|
for(let i in options) {
|
||||||
// @ts-ignore
|
// @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
|
// @ts-ignore
|
||||||
this[i] = options[i];
|
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 !== rootScope.myId || !this.dialog) {
|
||||||
if(this.peerId.isUser() && appUsersManager.getUser(this.peerId).pFlags.deleted) {
|
if(this.peerId.isUser() && appUsersManager.getUser(this.peerId).pFlags.deleted) {
|
||||||
replaceContent(this.element, i18n(this.onlyFirstName ? 'Deleted' : 'HiddenName'));
|
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);
|
appImManager.chat.input.initMessagesForward(peerIdMids);
|
||||||
},
|
},
|
||||||
placeholder: 'ShareModal.Search.ForwardPlaceholder',
|
placeholder: 'ShareModal.Search.ForwardPlaceholder',
|
||||||
|
@ -122,7 +122,9 @@ export class AppSidebarLeft extends SidebarSlider {
|
|||||||
text: 'SavedMessages',
|
text: 'SavedMessages',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
setTimeout(() => { // menu doesn't close if no timeout (lol)
|
setTimeout(() => { // menu doesn't close if no timeout (lol)
|
||||||
appImManager.setPeer(appImManager.myId);
|
appImManager.setPeer({
|
||||||
|
peerId: appImManager.myId
|
||||||
|
});
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
}, btnArchive, {
|
}, btnArchive, {
|
||||||
|
@ -1358,9 +1358,11 @@ export class AppDialogsManager {
|
|||||||
const peerId = elem.dataset.peerId.toPeerId();
|
const peerId = elem.dataset.peerId.toPeerId();
|
||||||
const lastMsgId = +elem.dataset.mid || undefined;
|
const lastMsgId = +elem.dataset.mid || undefined;
|
||||||
|
|
||||||
setPeerFunc(peerId, lastMsgId);
|
setPeerFunc({
|
||||||
|
peerId, lastMsgId
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
setPeerFunc(NULL_PEER_ID);
|
setPeerFunc();
|
||||||
}
|
}
|
||||||
}, {capture: true});
|
}, {capture: true});
|
||||||
|
|
||||||
@ -1641,12 +1643,13 @@ export class AppDialogsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getDialog(dialog: Dialog | PeerId): Dialog {
|
private getDialog(dialog: Dialog | PeerId): Dialog {
|
||||||
if(typeof(dialog) !== 'object' && dialog) {
|
if(typeof(dialog) !== 'object') {
|
||||||
const originalDialog = appMessagesManager.getDialogOnly(dialog);
|
const originalDialog = appMessagesManager.getDialogOnly(dialog);
|
||||||
if(!originalDialog) {
|
if(!originalDialog) {
|
||||||
|
const peerId = dialog || NULL_PEER_ID;
|
||||||
return {
|
return {
|
||||||
peerId: dialog,
|
peerId,
|
||||||
peer: appPeersManager.getOutputPeer(dialog),
|
peer: appPeersManager.getOutputPeer(peerId),
|
||||||
pFlags: {}
|
pFlags: {}
|
||||||
} as any;
|
} as any;
|
||||||
}
|
}
|
||||||
@ -1712,6 +1715,30 @@ export class AppDialogsManager {
|
|||||||
this.setCallStatus(dom, !!(chat.pFlags.call_active && chat.pFlags.call_not_empty));
|
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: {
|
public addDialogNew(options: {
|
||||||
dialog: Parameters<AppDialogsManager['addDialog']>[0],
|
dialog: Parameters<AppDialogsManager['addDialog']>[0],
|
||||||
container?: Parameters<AppDialogsManager['addDialog']>[1],
|
container?: Parameters<AppDialogsManager['addDialog']>[1],
|
||||||
@ -1723,12 +1750,14 @@ export class AppDialogsManager {
|
|||||||
avatarSize?: number,
|
avatarSize?: number,
|
||||||
autonomous?: boolean,
|
autonomous?: boolean,
|
||||||
lazyLoadQueue?: LazyLoadQueueIntersector,
|
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,
|
container?: HTMLElement | Scrollable | DocumentFragment | false,
|
||||||
drawStatus = true,
|
drawStatus = true,
|
||||||
rippleEnabled = true,
|
rippleEnabled = true,
|
||||||
@ -1738,7 +1767,9 @@ export class AppDialogsManager {
|
|||||||
avatarSize = 54,
|
avatarSize = 54,
|
||||||
autonomous = !!container,
|
autonomous = !!container,
|
||||||
lazyLoadQueue?: LazyLoadQueueIntersector,
|
lazyLoadQueue?: LazyLoadQueueIntersector,
|
||||||
loadPromises?: Promise<any>[]) {
|
loadPromises?: Promise<any>[],
|
||||||
|
fromName?: string
|
||||||
|
) {
|
||||||
const dialog = this.getDialog(_dialog);
|
const dialog = this.getDialog(_dialog);
|
||||||
const peerId = dialog.peerId;
|
const peerId = dialog.peerId;
|
||||||
|
|
||||||
@ -1746,6 +1777,7 @@ export class AppDialogsManager {
|
|||||||
avatarEl.loadPromises = loadPromises;
|
avatarEl.loadPromises = loadPromises;
|
||||||
avatarEl.lazyLoadQueue = lazyLoadQueue;
|
avatarEl.lazyLoadQueue = lazyLoadQueue;
|
||||||
avatarEl.setAttribute('dialog', meAsSaved ? '1' : '0');
|
avatarEl.setAttribute('dialog', meAsSaved ? '1' : '0');
|
||||||
|
if(fromName !== undefined) avatarEl.setAttribute('peer-title', fromName);
|
||||||
avatarEl.setAttribute('peer', '' + peerId);
|
avatarEl.setAttribute('peer', '' + peerId);
|
||||||
avatarEl.classList.add('dialog-avatar', 'avatar-' + avatarSize);
|
avatarEl.classList.add('dialog-avatar', 'avatar-' + avatarSize);
|
||||||
|
|
||||||
@ -1764,6 +1796,7 @@ export class AppDialogsManager {
|
|||||||
|
|
||||||
const peerTitle = new PeerTitle({
|
const peerTitle = new PeerTitle({
|
||||||
peerId,
|
peerId,
|
||||||
|
fromName,
|
||||||
dialog: meAsSaved,
|
dialog: meAsSaved,
|
||||||
onlyFirstName,
|
onlyFirstName,
|
||||||
plainText: false
|
plainText: false
|
||||||
|
@ -43,7 +43,7 @@ import appNavigationController from '../../components/appNavigationController';
|
|||||||
import appNotificationsManager from './appNotificationsManager';
|
import appNotificationsManager from './appNotificationsManager';
|
||||||
import AppPrivateSearchTab from '../../components/sidebarRight/tabs/search';
|
import AppPrivateSearchTab from '../../components/sidebarRight/tabs/search';
|
||||||
import I18n, { i18n, join, LangPackKey } from '../langPack';
|
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 { hslaStringToHex } from '../../helpers/color';
|
||||||
import { copy, getObjectKeysAndSort } from '../../helpers/object';
|
import { copy, getObjectKeysAndSort } from '../../helpers/object';
|
||||||
import { getFilesFromEvent } from '../../helpers/files';
|
import { getFilesFromEvent } from '../../helpers/files';
|
||||||
@ -79,6 +79,7 @@ import IS_GROUP_CALL_SUPPORTED from '../../environment/groupCallSupport';
|
|||||||
import appAvatarsManager from './appAvatarsManager';
|
import appAvatarsManager from './appAvatarsManager';
|
||||||
import IS_CALL_SUPPORTED from '../../environment/callSupport';
|
import IS_CALL_SUPPORTED from '../../environment/callSupport';
|
||||||
import { CallType } from '../calls/types';
|
import { CallType } from '../calls/types';
|
||||||
|
import { Modify } from '../../types';
|
||||||
|
|
||||||
//console.log('appImManager included33!');
|
//console.log('appImManager included33!');
|
||||||
|
|
||||||
@ -92,6 +93,19 @@ export type ChatSavedPosition = {
|
|||||||
top: number
|
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 {
|
export class AppImManager {
|
||||||
public columnEl = document.getElementById('column-center') as HTMLDivElement;
|
public columnEl = document.getElementById('column-center') as HTMLDivElement;
|
||||||
public chatsContainer: HTMLElement;
|
public chatsContainer: HTMLElement;
|
||||||
@ -197,7 +211,12 @@ export class AppImManager {
|
|||||||
if(threadId) threadId = appMessagesIdsManager.generateMessageId(threadId);
|
if(threadId) threadId = appMessagesIdsManager.generateMessageId(threadId);
|
||||||
if(mid) mid = appMessagesIdsManager.generateMessageId(mid); // because mid can come from notification, i.e. server message id
|
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) => {
|
rootScope.addEventListener('peer_changing', (chat) => {
|
||||||
@ -374,7 +393,7 @@ export class AppImManager {
|
|||||||
// pathnameParams: [string, string?],
|
// pathnameParams: [string, string?],
|
||||||
// uriParams: {comment?: number}
|
// uriParams: {comment?: number}
|
||||||
pathnameParams: ['c', string, string] | [string, string?],
|
pathnameParams: ['c', string, string] | [string, string?],
|
||||||
uriParams: {thread?: string, comment?: string} | {comment?: string}
|
uriParams: {thread?: string, comment?: string} | {comment?: string, start?: string}
|
||||||
}>({
|
}>({
|
||||||
name: 'im',
|
name: 'im',
|
||||||
callback: async({pathnameParams, uriParams}) => {
|
callback: async({pathnameParams, uriParams}) => {
|
||||||
@ -384,7 +403,7 @@ export class AppImManager {
|
|||||||
_: INTERNAL_LINK_TYPE.PRIVATE_POST,
|
_: INTERNAL_LINK_TYPE.PRIVATE_POST,
|
||||||
channel: pathnameParams[1],
|
channel: pathnameParams[1],
|
||||||
post: pathnameParams[2],
|
post: pathnameParams[2],
|
||||||
thread: 'thread' in uriParams ? uriParams.thread : undefined,
|
thread: 'thread' in uriParams && uriParams.thread,
|
||||||
comment: uriParams.comment
|
comment: uriParams.comment
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
@ -392,7 +411,8 @@ export class AppImManager {
|
|||||||
_: INTERNAL_LINK_TYPE.MESSAGE,
|
_: INTERNAL_LINK_TYPE.MESSAGE,
|
||||||
domain: pathnameParams[0],
|
domain: pathnameParams[0],
|
||||||
post: pathnameParams[1],
|
post: pathnameParams[1],
|
||||||
comment: uriParams.comment
|
comment: uriParams.comment,
|
||||||
|
start: 'start' in uriParams && uriParams.start
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,7 +534,7 @@ export class AppImManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(nextDialog) {
|
if(nextDialog) {
|
||||||
this.setPeer(nextDialog.peerId);
|
this.setPeer({peerId: nextDialog.peerId});
|
||||||
}
|
}
|
||||||
} else if(key === 'ArrowUp') {
|
} else if(key === 'ArrowUp') {
|
||||||
if(!chat.input.editMsgId && chat.input.isInputEmpty()) {
|
if(!chat.input.editMsgId && chat.input.isInputEmpty()) {
|
||||||
@ -606,7 +626,11 @@ export class AppImManager {
|
|||||||
const threadId = link.thread ? appMessagesIdsManager.generateMessageId(+link.thread) : undefined;
|
const threadId = link.thread ? appMessagesIdsManager.generateMessageId(+link.thread) : undefined;
|
||||||
|
|
||||||
if(threadId) this.openThread(peerId, postId, threadId);
|
if(threadId) this.openThread(peerId, postId, threadId);
|
||||||
else this.setInnerPeer(peerId, postId);
|
else this.setInnerPeer({
|
||||||
|
peerId,
|
||||||
|
lastMsgId: postId,
|
||||||
|
threadId
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -627,7 +651,9 @@ export class AppImManager {
|
|||||||
|
|
||||||
if(chatInvite._ === 'chatInviteAlready' ||
|
if(chatInvite._ === 'chatInviteAlready' ||
|
||||||
chatInvite._ === 'chatInvitePeek'/* && chatInvite.expires > tsNow(true) */) {
|
chatInvite._ === 'chatInvitePeek'/* && chatInvite.expires > tsNow(true) */) {
|
||||||
this.setInnerPeer(chatInvite.chat.id.toPeerId(true));
|
this.setInnerPeer({
|
||||||
|
peerId: chatInvite.chat.id.toPeerId(true)
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -719,7 +745,10 @@ export class AppImManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
default: { // peerId
|
default: { // peerId
|
||||||
this.setInnerPeer(postId ? p.toPeerId(true) : p.toPeerId(), postId);
|
this.setInnerPeer({
|
||||||
|
peerId: postId ? p.toPeerId(true) : p.toPeerId(),
|
||||||
|
lastMsgId: postId
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -730,14 +759,21 @@ export class AppImManager {
|
|||||||
//location.hash = '';
|
//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 => {
|
return appUsersManager.resolveUsername(username).then(peer => {
|
||||||
const isUser = peer._ === 'user';
|
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);
|
if(threadId) {
|
||||||
else if(commentId) return this.openComment(peerId, msgId, commentId);
|
return this.openThread(peerId, lastMsgId, threadId);
|
||||||
else return this.setInnerPeer(peerId, msgId);
|
} else if(commentId) {
|
||||||
|
return this.openComment(peerId, lastMsgId, commentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.setInnerPeer({
|
||||||
|
peerId,
|
||||||
|
lastMsgId
|
||||||
|
});
|
||||||
}, (err) => {
|
}, (err) => {
|
||||||
if(err.type === 'USERNAME_NOT_OCCUPIED') {
|
if(err.type === 'USERNAME_NOT_OCCUPIED') {
|
||||||
toastNew({langPackKey: 'NoUsernameFound'});
|
toastNew({langPackKey: 'NoUsernameFound'});
|
||||||
@ -752,10 +788,19 @@ export class AppImManager {
|
|||||||
*/
|
*/
|
||||||
public openThread(peerId: PeerId, lastMsgId: number, threadId: number) {
|
public openThread(peerId: PeerId, lastMsgId: number, threadId: number) {
|
||||||
return appMessagesManager.wrapSingleMessage(peerId, threadId).then(() => {
|
return appMessagesManager.wrapSingleMessage(peerId, threadId).then(() => {
|
||||||
const message = appMessagesManager.getMessageByPeer(peerId, threadId);
|
const message: Message = appMessagesManager.getMessageByPeer(peerId, threadId);
|
||||||
appMessagesManager.generateThreadServiceStartMessage(message);
|
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({
|
appNavigationController.pushItem({
|
||||||
type: 'chat',
|
type: 'chat',
|
||||||
onPop: (canAnimate) => {
|
onPop: (canAnimate) => {
|
||||||
this.setPeer(NULL_PEER_ID, undefined, canAnimate);
|
this.setPeer({}, canAnimate);
|
||||||
blurActiveElement();
|
blurActiveElement();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1270,7 +1315,7 @@ export class AppImManager {
|
|||||||
type: 'im',
|
type: 'im',
|
||||||
onPop: (canAnimate) => {
|
onPop: (canAnimate) => {
|
||||||
//this.selectTab(prevTabId, !isSafari);
|
//this.selectTab(prevTabId, !isSafari);
|
||||||
this.setPeer(NULL_PEER_ID, undefined, canAnimate);
|
this.setPeer({}, canAnimate);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1382,12 +1427,14 @@ export class AppImManager {
|
|||||||
}, 250 + 100);
|
}, 250 + 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
public setPeer(peerId: PeerId, lastMsgId?: number, animate?: boolean): boolean {
|
public setPeer(options: ChatSetPeerOptions = {}, animate?: boolean): boolean {
|
||||||
if(this.init) {
|
if(this.init) {
|
||||||
this.init();
|
this.init();
|
||||||
this.init = null;
|
this.init = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const {peerId, lastMsgId} = options;
|
||||||
|
|
||||||
const chat = this.chat;
|
const chat = this.chat;
|
||||||
const chatIndex = this.chats.indexOf(chat);
|
const chatIndex = this.chats.indexOf(chat);
|
||||||
|
|
||||||
@ -1411,7 +1458,7 @@ export class AppImManager {
|
|||||||
this.spliceChats(0, true, true, spliced);
|
this.spliceChats(0, true, true, spliced);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
const ret = this.setPeer(peerId, lastMsgId);
|
const ret = this.setPeer(options);
|
||||||
this.spliceChats(0, false, false, spliced);
|
this.spliceChats(0, false, false, spliced);
|
||||||
return ret;
|
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) {
|
if(peerId === NULL_PEER_ID || !peerId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const type = options.type ??= 'chat';
|
||||||
|
|
||||||
// * prevent opening already opened peer
|
// * prevent opening already opened peer
|
||||||
const existingIndex = this.chats.findIndex(chat => chat.peerId === peerId && chat.type === type);
|
const existingIndex = this.chats.findIndex(chat => chat.peerId === peerId && chat.type === type);
|
||||||
if(existingIndex !== -1) {
|
if(existingIndex !== -1) {
|
||||||
this.spliceChats(existingIndex + 1);
|
this.spliceChats(existingIndex + 1);
|
||||||
return this.setPeer(peerId, lastMsgId);
|
return this.setPeer(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
const oldChat = this.chat;
|
const oldChat = this.chat;
|
||||||
@ -1473,8 +1523,8 @@ export class AppImManager {
|
|||||||
if(type) {
|
if(type) {
|
||||||
chat.setType(type);
|
chat.setType(type);
|
||||||
|
|
||||||
if(threadId) {
|
if(options.threadId) {
|
||||||
chat.threadId = threadId;
|
chat.threadId = options.threadId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1482,11 +1532,14 @@ export class AppImManager {
|
|||||||
|
|
||||||
//this.chatsSelectTab(chat.container);
|
//this.chatsSelectTab(chat.container);
|
||||||
|
|
||||||
return this.setPeer(peerId, lastMsgId);
|
return this.setPeer(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public openScheduled(peerId: PeerId) {
|
public openScheduled(peerId: PeerId) {
|
||||||
this.setInnerPeer(peerId, undefined, 'scheduled');
|
this.setInnerPeer({
|
||||||
|
peerId,
|
||||||
|
type: 'scheduled'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private getTypingElement(action: SendMessageAction) {
|
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);
|
//return Object.keys(this.groupedMessagesStorage[grouped_id]).map(id => +id).sort((a, b) => a - b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getMidsByMessage(message: Message.message) {
|
public getMidsByMessage(message: Message) {
|
||||||
if(message?.grouped_id) return this.getMidsByAlbum(message.grouped_id);
|
if((message as Message.message)?.grouped_id) return this.getMidsByAlbum((message as Message.message).grouped_id);
|
||||||
else return [message.mid];
|
else return [message.mid];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2949,7 +2949,7 @@ export class AppMessagesManager {
|
|||||||
fromMe ?
|
fromMe ?
|
||||||
i18n('FromYou') :
|
i18n('FromYou') :
|
||||||
new PeerTitle({
|
new PeerTitle({
|
||||||
peerId: message.fromId,
|
...this.getMessageSenderPeerIdOrName(message),
|
||||||
dialog: message.peerId === rootScope.myId
|
dialog: message.peerId === rootScope.myId
|
||||||
}).element
|
}).element
|
||||||
);
|
);
|
||||||
@ -2962,6 +2962,18 @@ export class AppMessagesManager {
|
|||||||
return senderTitle;
|
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) {
|
public wrapSentTime(message: MyMessage) {
|
||||||
const el: HTMLElement = document.createElement('span');
|
const el: HTMLElement = document.createElement('span');
|
||||||
el.classList.add('sent-time');
|
el.classList.add('sent-time');
|
||||||
@ -3844,7 +3856,7 @@ export class AppMessagesManager {
|
|||||||
this.getDiscussionMessage(peerId, mid);
|
this.getDiscussionMessage(peerId, mid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public generateThreadServiceStartMessage(message: Message.message) {
|
public generateThreadServiceStartMessage(message: Message.message | Message.messageService) {
|
||||||
const threadKey = message.peerId + '_' + message.mid;
|
const threadKey = message.peerId + '_' + message.mid;
|
||||||
if(this.threadsServiceMessagesIdsStorage[threadKey]) return;
|
if(this.threadsServiceMessagesIdsStorage[threadKey]) return;
|
||||||
|
|
||||||
|
@ -19,7 +19,8 @@ export namespace InternalLink {
|
|||||||
_: INTERNAL_LINK_TYPE.MESSAGE,
|
_: INTERNAL_LINK_TYPE.MESSAGE,
|
||||||
domain: string,
|
domain: string,
|
||||||
post?: string,
|
post?: string,
|
||||||
comment?: string
|
comment?: string,
|
||||||
|
start?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InternalLinkPrivatePost {
|
export interface InternalLinkPrivatePost {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user