Fix document name XSS
This commit is contained in:
parent
ccb8d847e2
commit
25e5bcf22f
@ -868,8 +868,7 @@ export default class AppSearchSuper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!this.membersList) {
|
if(!this.membersList) {
|
||||||
this.membersList = new SortedUserList();
|
this.membersList = new SortedUserList({lazyLoadQueue: this.lazyLoadQueue, rippleEnabled: false});
|
||||||
this.membersList.lazyLoadQueue = this.lazyLoadQueue;
|
|
||||||
this.membersList.list.addEventListener('click', (e) => {
|
this.membersList.list.addEventListener('click', (e) => {
|
||||||
const li = findUpTag(e.target, 'LI');
|
const li = findUpTag(e.target, 'LI');
|
||||||
if(!li) {
|
if(!li) {
|
||||||
|
@ -272,7 +272,7 @@ function wrapAudio(audioEl: AudioElement) {
|
|||||||
|
|
||||||
const senderTitle = audioEl.showSender ? appMessagesManager.getSenderToPeerText(message) : '';
|
const senderTitle = audioEl.showSender ? appMessagesManager.getSenderToPeerText(message) : '';
|
||||||
|
|
||||||
let title = doc.type === 'voice' ? senderTitle : (doc.audioTitle || doc.file_name);
|
let title = doc.type === 'voice' ? senderTitle : (doc.audioTitle || doc.fileName);
|
||||||
let subtitle: string;
|
let subtitle: string;
|
||||||
|
|
||||||
if(doc.type === 'voice') {
|
if(doc.type === 'voice') {
|
||||||
|
@ -56,7 +56,7 @@ export default class ChatAudio extends PinnedContainer {
|
|||||||
//subtitle = 'Voice message';
|
//subtitle = 'Voice message';
|
||||||
subtitle = formatDate(message.date, false, false);
|
subtitle = formatDate(message.date, false, false);
|
||||||
} else {
|
} else {
|
||||||
title = doc.audioTitle || doc.file_name;
|
title = doc.audioTitle || doc.fileName;
|
||||||
subtitle = doc.audioPerformer ? RichTextProcessor.wrapPlainText(doc.audioPerformer) : 'Unknown Artist';
|
subtitle = doc.audioPerformer ? RichTextProcessor.wrapPlainText(doc.audioPerformer) : 'Unknown Artist';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ import calcImageInBox from "../../helpers/calcImageInBox";
|
|||||||
import isSendShortcutPressed from "../../helpers/dom/isSendShortcutPressed";
|
import isSendShortcutPressed from "../../helpers/dom/isSendShortcutPressed";
|
||||||
import placeCaretAtEnd from "../../helpers/dom/placeCaretAtEnd";
|
import placeCaretAtEnd from "../../helpers/dom/placeCaretAtEnd";
|
||||||
import rootScope from "../../lib/rootScope";
|
import rootScope from "../../lib/rootScope";
|
||||||
|
import RichTextProcessor from "../../lib/richtextprocessor";
|
||||||
|
|
||||||
type SendFileParams = Partial<{
|
type SendFileParams = Partial<{
|
||||||
file: File,
|
file: File,
|
||||||
@ -298,6 +299,7 @@ export default class PopupNewMedia extends PopupElement {
|
|||||||
_: 'document',
|
_: 'document',
|
||||||
file: file,
|
file: file,
|
||||||
file_name: file.name || '',
|
file_name: file.name || '',
|
||||||
|
fileName: file.name ? RichTextProcessor.wrapEmojiText(file.name) : '',
|
||||||
size: file.size,
|
size: file.size,
|
||||||
type: isPhoto ? 'photo' : 'doc'
|
type: isPhoto ? 'photo' : 'doc'
|
||||||
} as MyDocument;
|
} as MyDocument;
|
||||||
|
@ -575,12 +575,16 @@ export class SettingSection {
|
|||||||
constructor(options: {
|
constructor(options: {
|
||||||
name?: LangPackKey,
|
name?: LangPackKey,
|
||||||
caption?: LangPackKey | true,
|
caption?: LangPackKey | true,
|
||||||
noDelimiter?: boolean
|
noDelimiter?: boolean,
|
||||||
|
fakeGradientDelimiter?: boolean
|
||||||
}) {
|
}) {
|
||||||
this.container = document.createElement('div');
|
this.container = document.createElement('div');
|
||||||
this.container.classList.add('sidebar-left-section');
|
this.container.classList.add('sidebar-left-section');
|
||||||
|
|
||||||
if(!options.noDelimiter) {
|
if(options.fakeGradientDelimiter) {
|
||||||
|
this.container.append(generateDelimiter());
|
||||||
|
this.container.classList.add('with-fake-delimiter');
|
||||||
|
} else if(!options.noDelimiter) {
|
||||||
const hr = document.createElement('hr');
|
const hr = document.createElement('hr');
|
||||||
this.container.append(hr);
|
this.container.append(hr);
|
||||||
} else {
|
} else {
|
||||||
@ -620,6 +624,12 @@ export const generateSection = (appendTo: Scrollable, name?: LangPackKey, captio
|
|||||||
return section.content;
|
return section.content;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const generateDelimiter = () => {
|
||||||
|
const delimiter = document.createElement('div');
|
||||||
|
delimiter.classList.add('gradient-delimiter');
|
||||||
|
return delimiter;
|
||||||
|
};
|
||||||
|
|
||||||
const appSidebarLeft = new AppSidebarLeft();
|
const appSidebarLeft = new AppSidebarLeft();
|
||||||
MOUNT_CLASS_TO.appSidebarLeft = appSidebarLeft;
|
MOUNT_CLASS_TO.appSidebarLeft = appSidebarLeft;
|
||||||
export default appSidebarLeft;
|
export default appSidebarLeft;
|
||||||
|
@ -17,7 +17,7 @@ export default class AppArchivedTab extends SliderSuperTab {
|
|||||||
|
|
||||||
if(!appDialogsManager.chatLists[AppArchivedTab.filterId]) {
|
if(!appDialogsManager.chatLists[AppArchivedTab.filterId]) {
|
||||||
const chatList = appDialogsManager.createChatList();
|
const chatList = appDialogsManager.createChatList();
|
||||||
appDialogsManager.generateScrollable(chatList, AppArchivedTab.filterId);
|
appDialogsManager.generateScrollable(chatList, AppArchivedTab.filterId).container.append(chatList);
|
||||||
appDialogsManager.setListClickListener(chatList, null, true);
|
appDialogsManager.setListClickListener(chatList, null, true);
|
||||||
//appDialogsManager.setListClickListener(archivedChatList, null, true); // * to test peer changing
|
//appDialogsManager.setListClickListener(archivedChatList, null, true); // * to test peer changing
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import { SliderSuperTab } from "../../slider";
|
|||||||
import appDialogsManager from "../../../lib/appManagers/appDialogsManager";
|
import appDialogsManager from "../../../lib/appManagers/appDialogsManager";
|
||||||
import appUsersManager from "../../../lib/appManagers/appUsersManager";
|
import appUsersManager from "../../../lib/appManagers/appUsersManager";
|
||||||
import appPhotosManager from "../../../lib/appManagers/appPhotosManager";
|
import appPhotosManager from "../../../lib/appManagers/appPhotosManager";
|
||||||
import rootScope from "../../../lib/rootScope";
|
|
||||||
import InputSearch from "../../inputSearch";
|
import InputSearch from "../../inputSearch";
|
||||||
import { isMobile } from "../../../helpers/userAgent";
|
import { isMobile } from "../../../helpers/userAgent";
|
||||||
import { canFocus } from "../../../helpers/dom/canFocus";
|
import { canFocus } from "../../../helpers/dom/canFocus";
|
||||||
@ -67,7 +66,7 @@ export default class AppContactsTab extends SliderSuperTab {
|
|||||||
if(this.promise) return this.promise;
|
if(this.promise) return this.promise;
|
||||||
this.scrollable.onScrolledBottom = null;
|
this.scrollable.onScrolledBottom = null;
|
||||||
|
|
||||||
this.promise = appUsersManager.getContacts(query).then(_contacts => {
|
this.promise = appUsersManager.getContacts(query, undefined, 'online').then(contacts => {
|
||||||
this.promise = null;
|
this.promise = null;
|
||||||
|
|
||||||
if(!this.alive) {
|
if(!this.alive) {
|
||||||
@ -75,42 +74,26 @@ export default class AppContactsTab extends SliderSuperTab {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const contacts = [..._contacts];
|
|
||||||
|
|
||||||
if(!query) {
|
|
||||||
contacts.findAndSplice(u => u === rootScope.myId);
|
|
||||||
}
|
|
||||||
/* if(query && 'saved messages'.includes(query.toLowerCase())) {
|
|
||||||
contacts.unshift(rootScope.myID);
|
|
||||||
} */
|
|
||||||
|
|
||||||
let sorted = contacts
|
|
||||||
.map(userId => {
|
|
||||||
let user = appUsersManager.getUser(userId);
|
|
||||||
let status = appUsersManager.getUserStatusForSort(user.status);
|
|
||||||
|
|
||||||
return {user, status};
|
|
||||||
})
|
|
||||||
.sort((a, b) => b.status - a.status);
|
|
||||||
|
|
||||||
let renderPage = () => {
|
let renderPage = () => {
|
||||||
let pageCount = appPhotosManager.windowH / 72 * 1.25 | 0;
|
const pageCount = appPhotosManager.windowH / 72 * 1.25 | 0;
|
||||||
let arr = sorted.splice(0, pageCount); // надо splice!
|
const arr = contacts.splice(0, pageCount); // надо splice!
|
||||||
|
|
||||||
arr.forEach(({user}) => {
|
arr.forEach((peerId) => {
|
||||||
let {dialog, dom} = appDialogsManager.addDialogNew({
|
const {dom} = appDialogsManager.addDialogNew({
|
||||||
dialog: user.id,
|
dialog: peerId,
|
||||||
container: this.list,
|
container: this.list,
|
||||||
drawStatus: false,
|
drawStatus: false,
|
||||||
avatarSize: 48,
|
avatarSize: 48,
|
||||||
autonomous: true
|
autonomous: true
|
||||||
});
|
});
|
||||||
|
|
||||||
let status = appUsersManager.getUserStatusString(user.id);
|
const status = appUsersManager.getUserStatusString(peerId);
|
||||||
dom.lastMessageSpan.append(status);
|
dom.lastMessageSpan.append(status);
|
||||||
});
|
});
|
||||||
|
|
||||||
if(!sorted.length) renderPage = undefined;
|
if(!contacts.length) {
|
||||||
|
renderPage = undefined;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
renderPage();
|
renderPage();
|
||||||
|
@ -201,7 +201,7 @@ export default class AppGroupPermissionsTab extends SliderSuperTabEventable {
|
|||||||
const c = section.generateContentElement();
|
const c = section.generateContentElement();
|
||||||
c.classList.add('chatlist-container');
|
c.classList.add('chatlist-container');
|
||||||
|
|
||||||
const list = appDialogsManager.createChatList();
|
const list = appDialogsManager.createChatList({new: true});
|
||||||
c.append(list);
|
c.append(list);
|
||||||
|
|
||||||
attachClickEvent(list, (e) => {
|
attachClickEvent(list, (e) => {
|
||||||
|
@ -26,7 +26,7 @@ import { Chat, Message, MessageAction, ChatFull, Photo } from "../../../layer";
|
|||||||
import Button from "../../button";
|
import Button from "../../button";
|
||||||
import ButtonIcon from "../../buttonIcon";
|
import ButtonIcon from "../../buttonIcon";
|
||||||
import I18n, { i18n, LangPackKey } from "../../../lib/langPack";
|
import I18n, { i18n, LangPackKey } from "../../../lib/langPack";
|
||||||
import { SettingSection } from "../../sidebarLeft";
|
import { generateDelimiter, SettingSection } from "../../sidebarLeft";
|
||||||
import Row from "../../row";
|
import Row from "../../row";
|
||||||
import { copyTextToClipboard } from "../../../helpers/clipboard";
|
import { copyTextToClipboard } from "../../../helpers/clipboard";
|
||||||
import { toast, toastNew } from "../../toast";
|
import { toast, toastNew } from "../../toast";
|
||||||
@ -572,10 +572,7 @@ class PeerProfile {
|
|||||||
|
|
||||||
this.section.content.append(this.phone.container, this.username.container, this.bio.container, this.notifications.container);
|
this.section.content.append(this.phone.container, this.username.container, this.bio.container, this.notifications.container);
|
||||||
|
|
||||||
const delimiter = document.createElement('div');
|
this.element.append(this.section.container, generateDelimiter());
|
||||||
delimiter.classList.add('gradient-delimiter');
|
|
||||||
|
|
||||||
this.element.append(this.section.container, delimiter);
|
|
||||||
|
|
||||||
this.notifications.checkboxField.input.addEventListener('change', (e) => {
|
this.notifications.checkboxField.input.addEventListener('change', (e) => {
|
||||||
if(!e.isTrusted) {
|
if(!e.isTrusted) {
|
||||||
|
@ -36,7 +36,7 @@ export default class AppUserPermissionsTab extends SliderSuperTabEventable {
|
|||||||
div.classList.add('chatlist-container');
|
div.classList.add('chatlist-container');
|
||||||
section.content.insertBefore(div, section.title);
|
section.content.insertBefore(div, section.title);
|
||||||
|
|
||||||
const list = appDialogsManager.createChatList();
|
const list = appDialogsManager.createChatList({new: true});
|
||||||
div.append(list);
|
div.append(list);
|
||||||
|
|
||||||
const {dom} = appDialogsManager.addDialogNew({
|
const {dom} = appDialogsManager.addDialogNew({
|
||||||
|
@ -12,6 +12,7 @@ import { insertInDescendSortedArray } from "../helpers/array";
|
|||||||
import isInDOM from "../helpers/dom/isInDOM";
|
import isInDOM from "../helpers/dom/isInDOM";
|
||||||
import positionElementByIndex from "../helpers/dom/positionElementByIndex";
|
import positionElementByIndex from "../helpers/dom/positionElementByIndex";
|
||||||
import replaceContent from "../helpers/dom/replaceContent";
|
import replaceContent from "../helpers/dom/replaceContent";
|
||||||
|
import { safeAssign } from "../helpers/object";
|
||||||
|
|
||||||
type SortedUser = {
|
type SortedUser = {
|
||||||
peerId: number,
|
peerId: number,
|
||||||
@ -19,14 +20,24 @@ type SortedUser = {
|
|||||||
dom: DialogDom
|
dom: DialogDom
|
||||||
};
|
};
|
||||||
export default class SortedUserList {
|
export default class SortedUserList {
|
||||||
public static SORT_INTERVAL = 30e3;
|
protected static SORT_INTERVAL = 30e3;
|
||||||
|
protected users: Map<number, SortedUser>;
|
||||||
|
protected sorted: Array<SortedUser>;
|
||||||
public list: HTMLUListElement;
|
public list: HTMLUListElement;
|
||||||
public users: Map<number, SortedUser>;
|
|
||||||
public sorted: Array<SortedUser>;
|
protected lazyLoadQueue: LazyLoadQueueIntersector;
|
||||||
public lazyLoadQueue: LazyLoadQueueIntersector;
|
protected avatarSize = 48;
|
||||||
|
protected rippleEnabled = true;
|
||||||
|
|
||||||
constructor() {
|
constructor(options: Partial<{
|
||||||
this.list = appDialogsManager.createChatList();
|
lazyLoadQueue: SortedUserList['lazyLoadQueue'],
|
||||||
|
avatarSize: SortedUserList['avatarSize'],
|
||||||
|
rippleEnabled: SortedUserList['rippleEnabled'],
|
||||||
|
new: boolean
|
||||||
|
}> = {}) {
|
||||||
|
safeAssign(this, options);
|
||||||
|
|
||||||
|
this.list = appDialogsManager.createChatList({new: options.new});
|
||||||
|
|
||||||
this.users = new Map();
|
this.users = new Map();
|
||||||
this.sorted = [];
|
this.sorted = [];
|
||||||
@ -76,10 +87,10 @@ export default class SortedUserList {
|
|||||||
dialog: peerId,
|
dialog: peerId,
|
||||||
container: false,
|
container: false,
|
||||||
drawStatus: false,
|
drawStatus: false,
|
||||||
avatarSize: 48,
|
avatarSize: this.avatarSize,
|
||||||
autonomous: true,
|
autonomous: true,
|
||||||
meAsSaved: false,
|
meAsSaved: false,
|
||||||
rippleEnabled: false,
|
rippleEnabled: this.rippleEnabled,
|
||||||
lazyLoadQueue: this.lazyLoadQueue
|
lazyLoadQueue: this.lazyLoadQueue
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -507,7 +507,7 @@ export function wrapDocument({message, withTime, fontWeight, voiceAsMusic, showS
|
|||||||
}
|
}
|
||||||
|
|
||||||
//let fileName = stringMiddleOverflow(doc.file_name || 'Unknown.file', 26);
|
//let fileName = stringMiddleOverflow(doc.file_name || 'Unknown.file', 26);
|
||||||
let fileName = doc.file_name || 'Unknown.file';
|
let fileName = doc.fileName || 'Unknown.file';
|
||||||
let size = formatBytes(doc.size);
|
let size = formatBytes(doc.size);
|
||||||
|
|
||||||
if(withTime) {
|
if(withTime) {
|
||||||
|
1
src/layer.d.ts
vendored
1
src/layer.d.ts
vendored
@ -3133,6 +3133,7 @@ export namespace Document {
|
|||||||
h?: number,
|
h?: number,
|
||||||
w?: number,
|
w?: number,
|
||||||
file_name?: string,
|
file_name?: string,
|
||||||
|
fileName?: string,
|
||||||
file?: File,
|
file?: File,
|
||||||
duration?: number,
|
duration?: number,
|
||||||
audioTitle?: string,
|
audioTitle?: string,
|
||||||
|
@ -35,7 +35,7 @@ import { LazyLoadQueueIntersector } from "../../components/lazyLoadQueue";
|
|||||||
import lottieLoader from "../lottieLoader";
|
import lottieLoader from "../lottieLoader";
|
||||||
import { wrapLocalSticker } from "../../components/wrappers";
|
import { wrapLocalSticker } from "../../components/wrappers";
|
||||||
import AppEditFolderTab from "../../components/sidebarLeft/tabs/editFolder";
|
import AppEditFolderTab from "../../components/sidebarLeft/tabs/editFolder";
|
||||||
import appSidebarLeft from "../../components/sidebarLeft";
|
import appSidebarLeft, { SettingSection } from "../../components/sidebarLeft";
|
||||||
import { attachClickEvent } from "../../helpers/dom/clickEvent";
|
import { attachClickEvent } from "../../helpers/dom/clickEvent";
|
||||||
import positionElementByIndex from "../../helpers/dom/positionElementByIndex";
|
import positionElementByIndex from "../../helpers/dom/positionElementByIndex";
|
||||||
import replaceContent from "../../helpers/dom/replaceContent";
|
import replaceContent from "../../helpers/dom/replaceContent";
|
||||||
@ -43,6 +43,8 @@ import ConnectionStatusComponent from "../../components/connectionStatus";
|
|||||||
import appChatsManager from "./appChatsManager";
|
import appChatsManager from "./appChatsManager";
|
||||||
import { renderImageFromUrlPromise } from "../../helpers/dom/renderImageFromUrl";
|
import { renderImageFromUrlPromise } from "../../helpers/dom/renderImageFromUrl";
|
||||||
import { fastRafPromise } from "../../helpers/schedulers";
|
import { fastRafPromise } from "../../helpers/schedulers";
|
||||||
|
import appPhotosManager from "./appPhotosManager";
|
||||||
|
import SortedUserList from "../../components/sortedUserList";
|
||||||
|
|
||||||
export type DialogDom = {
|
export type DialogDom = {
|
||||||
avatarEl: AvatarElement,
|
avatarEl: AvatarElement,
|
||||||
@ -106,6 +108,7 @@ export class AppDialogsManager {
|
|||||||
private lastActiveElements: Set<HTMLElement> = new Set();
|
private lastActiveElements: Set<HTMLElement> = new Set();
|
||||||
|
|
||||||
private offsets: {top: number, bottom: number} = {top: 0, bottom: 0};
|
private offsets: {top: number, bottom: number} = {top: 0, bottom: 0};
|
||||||
|
loadContacts: () => void;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.chatsPreloader = putPreloader(null, true);
|
this.chatsPreloader = putPreloader(null, true);
|
||||||
@ -436,7 +439,7 @@ export class AppDialogsManager {
|
|||||||
appDraftsManager.addMissedDialogs();
|
appDraftsManager.addMissedDialogs();
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.loadDialogs();
|
return this.onChatsScroll();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* private getOffset(side: 'top' | 'bottom'): {index: number, pos: number} {
|
/* private getOffset(side: 'top' | 'bottom'): {index: number, pos: number} {
|
||||||
@ -533,7 +536,7 @@ export class AppDialogsManager {
|
|||||||
this.offsets.top = this.offsets.bottom = 0;
|
this.offsets.top = this.offsets.bottom = 0;
|
||||||
this.loadDialogsPromise = undefined;
|
this.loadDialogsPromise = undefined;
|
||||||
this.chatList = this.chatLists[this.filterId];
|
this.chatList = this.chatLists[this.filterId];
|
||||||
this.loadDialogs();
|
this.onChatsScroll();
|
||||||
};
|
};
|
||||||
|
|
||||||
private setFilterUnreadCount(filterId: number, folder?: Dialog[]) {
|
private setFilterUnreadCount(filterId: number, folder?: Dialog[]) {
|
||||||
@ -593,7 +596,6 @@ export class AppDialogsManager {
|
|||||||
const scrollable = new Scrollable(null, 'CL', 500);
|
const scrollable = new Scrollable(null, 'CL', 500);
|
||||||
scrollable.container.addEventListener('scroll', this.onChatsRegularScroll);
|
scrollable.container.addEventListener('scroll', this.onChatsRegularScroll);
|
||||||
scrollable.container.dataset.filterId = '' + filterId;
|
scrollable.container.dataset.filterId = '' + filterId;
|
||||||
scrollable.container.append(list);
|
|
||||||
scrollable.onScrolledTop = this.onChatsScrollTop;
|
scrollable.onScrolledTop = this.onChatsScrollTop;
|
||||||
scrollable.onScrolledBottom = this.onChatsScroll;
|
scrollable.onScrolledBottom = this.onChatsScroll;
|
||||||
scrollable.setVirtualContainer(list);
|
scrollable.setVirtualContainer(list);
|
||||||
@ -627,6 +629,23 @@ export class AppDialogsManager {
|
|||||||
|
|
||||||
const ul = this.createChatList();
|
const ul = this.createChatList();
|
||||||
const scrollable = this.generateScrollable(ul, filter.id);
|
const scrollable = this.generateScrollable(ul, filter.id);
|
||||||
|
|
||||||
|
scrollable.container.classList.add('chatlist-parts');
|
||||||
|
|
||||||
|
/* const parts = document.createElement('div');
|
||||||
|
parts.classList.add('chatlist-parts'); */
|
||||||
|
|
||||||
|
const top = document.createElement('div');
|
||||||
|
top.classList.add('chatlist-top');
|
||||||
|
|
||||||
|
const bottom = document.createElement('div');
|
||||||
|
bottom.classList.add('chatlist-bottom');
|
||||||
|
|
||||||
|
top.append(ul);
|
||||||
|
scrollable.container.append(top, bottom);
|
||||||
|
/* parts.append(top, bottom);
|
||||||
|
scrollable.container.append(parts); */
|
||||||
|
|
||||||
const div = scrollable.container;
|
const div = scrollable.container;
|
||||||
//this.folders.container.append(div);
|
//this.folders.container.append(div);
|
||||||
positionElementByIndex(scrollable.container, this.folders.container, filter.orderIndex);
|
positionElementByIndex(scrollable.container, this.folders.container, filter.orderIndex);
|
||||||
@ -654,7 +673,7 @@ export class AppDialogsManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadDialogs(side: SliceSides = 'bottom') {
|
private loadDialogs(side: SliceSides) {
|
||||||
/* if(testScroll) {
|
/* if(testScroll) {
|
||||||
return;
|
return;
|
||||||
} */
|
} */
|
||||||
@ -779,13 +798,13 @@ export class AppDialogsManager {
|
|||||||
return {container, header, subtitle};
|
return {container, header, subtitle};
|
||||||
}
|
}
|
||||||
|
|
||||||
private onListLengthChange = () => {
|
private checkIfPlaceholderNeeded() {
|
||||||
//return;
|
|
||||||
if(this.filterId === 1) {
|
if(this.filterId === 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let placeholderContainer = (Array.from(this.chatList.parentElement.children) as HTMLElement[]).find(el => el.matches('.empty-placeholder'));
|
const part = this.chatList.parentElement as HTMLElement;
|
||||||
|
let placeholderContainer = (Array.from(part.children) as HTMLElement[]).find(el => el.matches('.empty-placeholder'));
|
||||||
const needPlaceholder = this.scroll.loadedAll.bottom && !this.chatList.childElementCount/* || true */;
|
const needPlaceholder = this.scroll.loadedAll.bottom && !this.chatList.childElementCount/* || true */;
|
||||||
// this.chatList.style.display = 'none';
|
// this.chatList.style.display = 'none';
|
||||||
|
|
||||||
@ -793,6 +812,7 @@ export class AppDialogsManager {
|
|||||||
return;
|
return;
|
||||||
} else if(!needPlaceholder) {
|
} else if(!needPlaceholder) {
|
||||||
if(placeholderContainer) {
|
if(placeholderContainer) {
|
||||||
|
part.classList.remove('with-placeholder');
|
||||||
placeholderContainer.remove();
|
placeholderContainer.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -863,7 +883,55 @@ export class AppDialogsManager {
|
|||||||
placeholderContainer.append(button);
|
placeholderContainer.append(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.chatList.parentElement.append(placeholderContainer);
|
part.append(placeholderContainer);
|
||||||
|
part.classList.add('with-placeholder');
|
||||||
|
}
|
||||||
|
|
||||||
|
private onListLengthChange = () => {
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.checkIfPlaceholderNeeded();
|
||||||
|
|
||||||
|
if(this.filterId > 0) return;
|
||||||
|
const bottom = this.chatList.parentElement.nextElementSibling as HTMLElement;
|
||||||
|
|
||||||
|
if(bottom.childElementCount) return;
|
||||||
|
|
||||||
|
bottom.parentElement.classList.add('with-contacts');
|
||||||
|
|
||||||
|
const section = new SettingSection({
|
||||||
|
name: 'Contacts',
|
||||||
|
noDelimiter: true,
|
||||||
|
fakeGradientDelimiter: true
|
||||||
|
});
|
||||||
|
|
||||||
|
section.container.classList.add('hide');
|
||||||
|
|
||||||
|
appUsersManager.getContacts(undefined, undefined, 'online').then(contacts => {
|
||||||
|
const sortedUserList = new SortedUserList({avatarSize: 42, new: true});
|
||||||
|
this.loadContacts = () => {
|
||||||
|
const pageCount = appPhotosManager.windowH / 60 | 0;
|
||||||
|
const arr = contacts.splice(0, pageCount);
|
||||||
|
|
||||||
|
arr.forEach((peerId) => {
|
||||||
|
sortedUserList.add(peerId);
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!contacts.length) {
|
||||||
|
this.loadContacts = undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.loadContacts();
|
||||||
|
|
||||||
|
const list = sortedUserList.list;
|
||||||
|
list.classList.add('chatlist-new');
|
||||||
|
this.setListClickListener(list);
|
||||||
|
section.content.append(list);
|
||||||
|
section.container.classList.remove('hide');
|
||||||
|
});
|
||||||
|
|
||||||
|
bottom.append(section.container);
|
||||||
};
|
};
|
||||||
|
|
||||||
public onChatsRegularScroll = () => {
|
public onChatsRegularScroll = () => {
|
||||||
@ -987,9 +1055,16 @@ export class AppDialogsManager {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public onChatsScroll = (side: SliceSides = 'bottom') => {
|
public onChatsScroll = (side: SliceSides = 'bottom') => {
|
||||||
if(this.scroll.loadedAll[side] || this.loadDialogsPromise) return;
|
if(this.scroll.loadedAll[side]) {
|
||||||
|
if(this.loadContacts) {
|
||||||
|
this.loadContacts();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
} else if(this.loadDialogsPromise) return this.loadDialogsPromise;
|
||||||
|
|
||||||
this.log('onChatsScroll', side);
|
this.log('onChatsScroll', side);
|
||||||
this.loadDialogs(side);
|
return this.loadDialogs(side);
|
||||||
};
|
};
|
||||||
|
|
||||||
public setListClickListener(list: HTMLUListElement, onFound?: () => void, withContext = false, autonomous = false, openInner = false) {
|
public setListClickListener(list: HTMLUListElement, onFound?: () => void, withContext = false, autonomous = false, openInner = false) {
|
||||||
@ -1050,15 +1125,20 @@ export class AppDialogsManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public createChatList(/* options: {
|
public createChatList(options: {
|
||||||
avatarSize?: number,
|
// avatarSize?: number,
|
||||||
handheldsSize?: number,
|
// handheldsSize?: number,
|
||||||
//size?: number,
|
// size?: number,
|
||||||
} = {} */) {
|
new?: boolean
|
||||||
|
} = {}) {
|
||||||
const list = document.createElement('ul');
|
const list = document.createElement('ul');
|
||||||
list.classList.add('chatlist'/* ,
|
list.classList.add('chatlist'/* ,
|
||||||
'chatlist-avatar-' + (options.avatarSize || 54) *//* , 'chatlist-' + (options.size || 72) */);
|
'chatlist-avatar-' + (options.avatarSize || 54) *//* , 'chatlist-' + (options.size || 72) */);
|
||||||
|
|
||||||
|
if(options.new) {
|
||||||
|
list.classList.add('chatlist-new');
|
||||||
|
}
|
||||||
|
|
||||||
/* if(options.handheldsSize) {
|
/* if(options.handheldsSize) {
|
||||||
list.classList.add('chatlist-handhelds-' + options.handheldsSize);
|
list.classList.add('chatlist-handhelds-' + options.handheldsSize);
|
||||||
} */
|
} */
|
||||||
|
@ -93,12 +93,13 @@ export class AppDocsManager {
|
|||||||
switch(attribute._) {
|
switch(attribute._) {
|
||||||
case 'documentAttributeFilename':
|
case 'documentAttributeFilename':
|
||||||
doc.file_name = RichTextProcessor.wrapPlainText(attribute.file_name);
|
doc.file_name = RichTextProcessor.wrapPlainText(attribute.file_name);
|
||||||
|
doc.fileName = RichTextProcessor.wrapEmojiText(attribute.file_name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'documentAttributeAudio':
|
case 'documentAttributeAudio':
|
||||||
doc.duration = attribute.duration;
|
doc.duration = attribute.duration;
|
||||||
doc.audioTitle = attribute.title;
|
doc.audioTitle = RichTextProcessor.wrapEmojiText(attribute.title);
|
||||||
doc.audioPerformer = attribute.performer;
|
doc.audioPerformer = RichTextProcessor.wrapEmojiText(attribute.performer);
|
||||||
doc.type = attribute.pFlags.voice && doc.mime_type === 'audio/ogg' ? 'voice' : 'audio';
|
doc.type = attribute.pFlags.voice && doc.mime_type === 'audio/ogg' ? 'voice' : 'audio';
|
||||||
/* if(apiDoc.type === 'audio') {
|
/* if(apiDoc.type === 'audio') {
|
||||||
apiDoc.supportsStreaming = true;
|
apiDoc.supportsStreaming = true;
|
||||||
@ -182,7 +183,7 @@ export class AppDocsManager {
|
|||||||
|
|
||||||
if(doc.type === 'voice' || doc.type === 'round') {
|
if(doc.type === 'voice' || doc.type === 'round') {
|
||||||
// browser will identify extension
|
// browser will identify extension
|
||||||
doc.file_name = doc.type + '_' + getFullDate(new Date(doc.date * 1000), {monthAsNumber: true, leadingZero: true}).replace(/[:\.]/g, '-').replace(', ', '_');
|
doc.file_name = doc.fileName = doc.type + '_' + getFullDate(new Date(doc.date * 1000), {monthAsNumber: true, leadingZero: true}).replace(/[:\.]/g, '-').replace(', ', '_');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(apiManager.isServiceWorkerOnline()) {
|
if(apiManager.isServiceWorkerOnline()) {
|
||||||
@ -201,7 +202,7 @@ export class AppDocsManager {
|
|||||||
// doc.url = ''; // * this will break upload urls
|
// doc.url = ''; // * this will break upload urls
|
||||||
|
|
||||||
if(!doc.file_name) {
|
if(!doc.file_name) {
|
||||||
doc.file_name = '';
|
doc.file_name = doc.fileName = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if(doc.mime_type === 'application/x-tgsticker' && doc.file_name === 'AnimatedSticker.tgs') {
|
if(doc.mime_type === 'application/x-tgsticker' && doc.file_name === 'AnimatedSticker.tgs') {
|
||||||
|
@ -2626,7 +2626,7 @@ export class AppMessagesManager {
|
|||||||
addPart(undefined, ((plain ? document.stickerEmojiRaw : document.stickerEmoji) || '') + 'Sticker');
|
addPart(undefined, ((plain ? document.stickerEmojiRaw : document.stickerEmoji) || '') + 'Sticker');
|
||||||
text = '';
|
text = '';
|
||||||
} else {
|
} else {
|
||||||
addPart(document.file_name, undefined, message.message);
|
addPart(undefined, plain ? document.file_name : RichTextProcessor.wrapEmojiText(document.file_name), message.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -261,7 +261,7 @@ export class AppUsersManager {
|
|||||||
return arr.filter(Boolean).join(' ');
|
return arr.filter(Boolean).join(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
public getContacts(query?: string, includeSaved = false) {
|
public getContacts(query?: string, includeSaved = false, sortBy: 'name' | 'online' | 'none' = 'name') {
|
||||||
return this.fillContacts().then(_contactsList => {
|
return this.fillContacts().then(_contactsList => {
|
||||||
let contactsList = [..._contactsList];
|
let contactsList = [..._contactsList];
|
||||||
if(query) {
|
if(query) {
|
||||||
@ -271,30 +271,27 @@ export class AppUsersManager {
|
|||||||
contactsList = filteredContactsList;
|
contactsList = filteredContactsList;
|
||||||
}
|
}
|
||||||
|
|
||||||
contactsList.sort((userId1: number, userId2: number) => {
|
if(sortBy === 'name') {
|
||||||
const sortName1 = (this.users[userId1] || {}).sortName || '';
|
contactsList.sort((userId1, userId2) => {
|
||||||
const sortName2 = (this.users[userId2] || {}).sortName || '';
|
const sortName1 = (this.users[userId1] || {}).sortName || '';
|
||||||
|
const sortName2 = (this.users[userId2] || {}).sortName || '';
|
||||||
return sortName1.localeCompare(sortName2);
|
return sortName1.localeCompare(sortName2);
|
||||||
});
|
});
|
||||||
|
} else if(sortBy === 'online') {
|
||||||
|
contactsList.sort((userId1, userId2) => {
|
||||||
|
const status1 = appUsersManager.getUserStatusForSort(appUsersManager.getUser(userId1).status);
|
||||||
|
const status2 = appUsersManager.getUserStatusForSort(appUsersManager.getUser(userId2).status);
|
||||||
|
return status2 - status1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
contactsList.findAndSplice(p => p === rootScope.myId);
|
||||||
if(includeSaved) {
|
if(includeSaved) {
|
||||||
if(this.testSelfSearch(query)) {
|
if(this.testSelfSearch(query)) {
|
||||||
contactsList.findAndSplice(p => p === rootScope.myId);
|
|
||||||
contactsList.unshift(rootScope.myId);
|
contactsList.unshift(rootScope.myId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* contactsList.sort((userId1: number, userId2: number) => {
|
|
||||||
const sortName1 = (this.users[userId1] || {}).sortName || '';
|
|
||||||
const sortName2 = (this.users[userId2] || {}).sortName || '';
|
|
||||||
if(sortName1 === sortName2) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sortName1 > sortName2 ? 1 : -1;
|
|
||||||
}); */
|
|
||||||
|
|
||||||
return contactsList;
|
return contactsList;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -748,7 +748,7 @@ namespace RichTextProcessor {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function wrapPlainText(text: any) {
|
export function wrapPlainText(text: string) {
|
||||||
if(emojiSupported) {
|
if(emojiSupported) {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
@ -757,32 +757,32 @@ namespace RichTextProcessor {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
text = text.replace(/\ufe0f/g, '', text);
|
text = text.replace(/\ufe0f/g, '');
|
||||||
var match;
|
var match;
|
||||||
var raw = text;
|
var raw = text;
|
||||||
var text: any = [],
|
const arr: string[] = [];
|
||||||
emojiTitle;
|
let emojiTitle;
|
||||||
fullRegExp.lastIndex = 0;
|
fullRegExp.lastIndex = 0;
|
||||||
while((match = raw.match(fullRegExp))) {
|
while((match = raw.match(fullRegExp))) {
|
||||||
text.push(raw.substr(0, match.index))
|
arr.push(raw.substr(0, match.index))
|
||||||
if(match[8]) {
|
if(match[8]) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const emojiCode = EmojiHelper.emojiMap[match[8]];
|
const emojiCode = EmojiHelper.emojiMap[match[8]];
|
||||||
if(emojiCode &&
|
if(emojiCode &&
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
(emojiTitle = emojiData[emojiCode][1][0])) {
|
(emojiTitle = emojiData[emojiCode][1][0])) {
|
||||||
text.push(':' + emojiTitle + ':');
|
arr.push(':' + emojiTitle + ':');
|
||||||
} else {
|
} else {
|
||||||
text.push(match[0]);
|
arr.push(match[0]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
text.push(match[0]);
|
arr.push(match[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
raw = raw.substr(match.index + match[0].length);
|
raw = raw.substr(match.index + match[0].length);
|
||||||
}
|
}
|
||||||
text.push(raw);
|
arr.push(raw);
|
||||||
return text.join('');
|
return arr.join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function wrapEmojiText(text: string) {
|
export function wrapEmojiText(text: string) {
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
{"name": "h", "type": "number"},
|
{"name": "h", "type": "number"},
|
||||||
{"name": "w", "type": "number"},
|
{"name": "w", "type": "number"},
|
||||||
{"name": "file_name", "type": "string"},
|
{"name": "file_name", "type": "string"},
|
||||||
|
{"name": "fileName", "type": "string"},
|
||||||
{"name": "file", "type": "File"},
|
{"name": "file", "type": "File"},
|
||||||
{"name": "duration", "type": "number"},
|
{"name": "duration", "type": "number"},
|
||||||
{"name": "audioTitle", "type": "string"},
|
{"name": "audioTitle", "type": "string"},
|
||||||
|
@ -399,6 +399,89 @@ ul.chatlist {
|
|||||||
li.is-muted .unread {
|
li.is-muted .unread {
|
||||||
background-color: var(--secondary-color);
|
background-color: var(--secondary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-parts {
|
||||||
|
/* width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column; */
|
||||||
|
|
||||||
|
&.with-contacts {
|
||||||
|
.chatlist-top:not(.with-placeholder) {
|
||||||
|
height: auto;
|
||||||
|
padding-bottom: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chatlist-top.with-placeholder {
|
||||||
|
height: 24.125rem;
|
||||||
|
|
||||||
|
.empty-placeholder-dialogs {
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// do not set position: relative here. will break chatlist slicing.
|
||||||
|
&-top {
|
||||||
|
// flex: 0 0 auto;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-bottom {
|
||||||
|
// flex: 1 1 auto;
|
||||||
|
max-height: 36.375rem;
|
||||||
|
|
||||||
|
.sidebar-left-section {
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chatlist-new {
|
||||||
|
padding: 0;
|
||||||
|
margin-top: -.5rem;
|
||||||
|
|
||||||
|
li {
|
||||||
|
height: 3.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-caption {
|
||||||
|
padding-left: 1.125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-subtitle {
|
||||||
|
margin-top: .0625rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// * supernew correct layout
|
||||||
|
&-new {
|
||||||
|
li {
|
||||||
|
height: 4.5rem;
|
||||||
|
padding: 0 .75rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-caption {
|
||||||
|
padding-left: .75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
height: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
line-height: var(--line-height) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-subtitle {
|
||||||
|
margin-top: .125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-last-message {
|
||||||
|
font-size: .875rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// use together like class="chatlist-container contacts-container"
|
// use together like class="chatlist-container contacts-container"
|
||||||
|
@ -830,6 +830,10 @@
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
padding: .5rem 0 1rem;
|
padding: .5rem 0 1rem;
|
||||||
|
|
||||||
|
&.with-fake-delimiter {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
@include respond-to(handhelds) {
|
@include respond-to(handhelds) {
|
||||||
padding-bottom: .5rem;
|
padding-bottom: .5rem;
|
||||||
}
|
}
|
||||||
@ -1182,6 +1186,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.empty-placeholder {
|
.empty-placeholder {
|
||||||
|
// left: 50%;
|
||||||
|
// transform: translate(-50%, -50%);
|
||||||
|
// position: absolute;
|
||||||
top: 40%;
|
top: 40%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -1190,6 +1197,7 @@
|
|||||||
width: 21rem !important;
|
width: 21rem !important;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0 1rem;
|
padding: 0 1rem;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
.media-sticker-wrapper {
|
.media-sticker-wrapper {
|
||||||
width: 128px;
|
width: 128px;
|
||||||
|
@ -708,35 +708,8 @@
|
|||||||
padding: 0 0 .5rem;
|
padding: 0 0 .5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
// * supernew and correct layout
|
.chatlist-new {
|
||||||
.chatlist {
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
li {
|
|
||||||
height: 72px;
|
|
||||||
padding: 0 .75rem;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-caption {
|
|
||||||
padding-left: .75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
line-height: 1.3125;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-subtitle {
|
|
||||||
margin-top: .125rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-last-message {
|
|
||||||
font-size: .875rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,12 +147,12 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
> div:not(.scroll-padding) {
|
/* > div:not(.scroll-padding) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
//overflow: hidden;
|
//overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* &[data-animation="tabs"] {
|
/* &[data-animation="tabs"] {
|
||||||
|
@ -1212,7 +1212,6 @@ middle-ellipsis-element {
|
|||||||
.gradient-delimiter {
|
.gradient-delimiter {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: .75rem;
|
height: .75rem;
|
||||||
display: flex;
|
|
||||||
background-color: var(--background-color-true);
|
background-color: var(--background-color-true);
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user