Browse Source

Respect read comments position

Fix bluring keyboard on Android
Fix reading messages when page was blured
Fix instant reading messages if there only one page of them
Split dom functions
master
Eduard Kuzmenko 4 years ago
parent
commit
b94dba3d9b
  1. 2
      src/components/animationIntersector.ts
  2. 4
      src/components/appMediaViewer.ts
  3. 3
      src/components/appNavigationController.ts
  4. 4
      src/components/appSearchSuper..ts
  5. 3
      src/components/appSelectPeers.ts
  6. 3
      src/components/audio.ts
  7. 3
      src/components/avatar.ts
  8. 3
      src/components/buttonMenu.ts
  9. 3
      src/components/buttonMenuToggle.ts
  10. 3
      src/components/chat/audio.ts
  11. 132
      src/components/chat/bubbles.ts
  12. 5
      src/components/chat/contextMenu.ts
  13. 4
      src/components/chat/dragAndDrop.ts
  14. 9
      src/components/chat/input.ts
  15. 6
      src/components/chat/markupTooltip.ts
  16. 3
      src/components/chat/pinnedContainer.ts
  17. 4
      src/components/chat/pinnedMessage.ts
  18. 3
      src/components/chat/search.ts
  19. 5
      src/components/chat/selection.ts
  20. 2
      src/components/chat/sendContextMenu.ts
  21. 4
      src/components/chat/topbar.ts
  22. 4
      src/components/emoticonsDropdown/index.ts
  23. 2
      src/components/gifsMasonry.ts
  24. 2
      src/components/horizontalMenu.ts
  25. 4
      src/components/inputField.ts
  26. 9
      src/components/languageChangeButton.ts
  27. 3
      src/components/misc.ts
  28. 2
      src/components/passwordInputField.ts
  29. 2
      src/components/peerTitle.ts
  30. 4
      src/components/poll.ts
  31. 5
      src/components/popups/createPoll.ts
  32. 2
      src/components/popups/index.ts
  33. 4
      src/components/popups/newMedia.ts
  34. 2
      src/components/popups/stickers.ts
  35. 4
      src/components/preloader.ts
  36. 2
      src/components/row.ts
  37. 2
      src/components/scrollable.ts
  38. 5
      src/components/sidebarLeft/index.ts
  39. 4
      src/components/sidebarLeft/tabs/2fa/email.ts
  40. 5
      src/components/sidebarLeft/tabs/2fa/emailConfirmation.ts
  41. 5
      src/components/sidebarLeft/tabs/2fa/enterPassword.ts
  42. 3
      src/components/sidebarLeft/tabs/2fa/hint.ts
  43. 2
      src/components/sidebarLeft/tabs/2fa/index.ts
  44. 2
      src/components/sidebarLeft/tabs/2fa/passwordSet.ts
  45. 3
      src/components/sidebarLeft/tabs/2fa/reEnterPassword.ts
  46. 3
      src/components/sidebarLeft/tabs/activeSessions.ts
  47. 2
      src/components/sidebarLeft/tabs/background.ts
  48. 5
      src/components/sidebarLeft/tabs/backgroundColor.ts
  49. 5
      src/components/sidebarLeft/tabs/blockedUsers.ts
  50. 4
      src/components/sidebarLeft/tabs/chatFolders.ts
  51. 2
      src/components/sidebarLeft/tabs/contacts.ts
  52. 1
      src/components/sidebarLeft/tabs/editFolder.ts
  53. 2
      src/components/sidebarLeft/tabs/editProfile.ts
  54. 2
      src/components/sidebarLeft/tabs/generalSettings.ts
  55. 2
      src/components/sidebarLeft/tabs/privacyAndSecurity.ts
  56. 3
      src/components/sidebarRight/tabs/chatType.ts
  57. 3
      src/components/sidebarRight/tabs/editChat.ts
  58. 3
      src/components/sidebarRight/tabs/editContact.ts
  59. 2
      src/components/sidebarRight/tabs/gifs.ts
  60. 3
      src/components/sidebarRight/tabs/groupPermissions.ts
  61. 4
      src/components/sidebarRight/tabs/sharedMedia.ts
  62. 2
      src/components/sidebarRight/tabs/stickers.ts
  63. 6
      src/components/sidebarRight/tabs/userPermissions.ts
  64. 2
      src/components/slider.ts
  65. 4
      src/components/sortedUserList.ts
  66. 2
      src/components/swipeHandler.ts
  67. 2
      src/components/transition.ts
  68. 4
      src/components/wrappers.ts
  69. 45
      src/helpers/calcImageInBox.ts
  70. 591
      src/helpers/dom.ts
  71. 14
      src/helpers/dom/blurActiveElement.ts
  72. 11
      src/helpers/dom/canFocus.ts
  73. 27
      src/helpers/dom/cancelEvent.ts
  74. 19
      src/helpers/dom/cancelSelection.ts
  75. 53
      src/helpers/dom/clickEvent.ts
  76. 15
      src/helpers/dom/disableTransition.ts
  77. 152
      src/helpers/dom/getRichValue.ts
  78. 27
      src/helpers/dom/getSelectedNodes.ts
  79. 17
      src/helpers/dom/getSelectedText.ts
  80. 48
      src/helpers/dom/handleScrollSideEvent.ts
  81. 12
      src/helpers/dom/htmlToDocumentFragment.ts
  82. 11
      src/helpers/dom/htmlToSpan.ts
  83. 25
      src/helpers/dom/isInDOM.ts
  84. 18
      src/helpers/dom/isInputEmpty.ts
  85. 18
      src/helpers/dom/isSelectionEmpty.ts
  86. 37
      src/helpers/dom/isSendShortcutPressed.ts
  87. 35
      src/helpers/dom/placeCaretAtEnd.ts
  88. 27
      src/helpers/dom/positionElementByIndex.ts
  89. 11
      src/helpers/dom/reflowScrollableElement.ts
  90. 20
      src/helpers/dom/replaceContent.ts
  91. 10
      src/helpers/dom/setInnerHTML.ts
  92. 15
      src/helpers/dom/toggleDisability.ts
  93. 16
      src/helpers/dom/whichChild.ts
  94. 2
      src/helpers/fastSmoothScroll.ts
  95. 17
      src/helpers/fillPropertyValue.ts
  96. 64
      src/helpers/generatePathData.ts
  97. 2
      src/helpers/sequentialDom.ts
  98. 3
      src/index.ts
  99. 4
      src/lib/appManagers/appDialogsManager.ts
  100. 7
      src/lib/appManagers/appImManager.ts
  101. Some files were not shown because too many files have changed in this diff Show More

2
src/components/animationIntersector.ts

@ -4,11 +4,11 @@ @@ -4,11 +4,11 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { isInDOM } from "../helpers/dom";
import { RLottiePlayer } from "../lib/lottieLoader";
import rootScope from "../lib/rootScope";
import { isSafari } from "../helpers/userAgent";
import { MOUNT_CLASS_TO } from "../config/debug";
import isInDOM from "../helpers/dom/isInDOM";
export interface AnimationItem {
el: HTMLElement,

4
src/components/appMediaViewer.ts

@ -17,7 +17,6 @@ import { logger } from "../lib/logger"; @@ -17,7 +17,6 @@ import { logger } from "../lib/logger";
import VideoPlayer from "../lib/mediaPlayer";
import { RichTextProcessor } from "../lib/richtextprocessor";
import rootScope from "../lib/rootScope";
import { cancelEvent, fillPropertyValue, generatePathData } from "../helpers/dom";
import animationIntersector from "./animationIntersector";
import appMediaPlaybackController from "./appMediaPlaybackController";
import AvatarElement from "./avatar";
@ -42,6 +41,9 @@ import renderImageFromUrl from "../helpers/dom/renderImageFromUrl"; @@ -42,6 +41,9 @@ import renderImageFromUrl from "../helpers/dom/renderImageFromUrl";
import findUpAsChild from "../helpers/dom/findUpAsChild";
import getVisibleRect from "../helpers/dom/getVisibleRect";
import appDownloadManager from "../lib/appManagers/appDownloadManager";
import { cancelEvent } from "../helpers/dom/cancelEvent";
import fillPropertyValue from "../helpers/fillPropertyValue";
import generatePathData from "../helpers/generatePathData";
// TODO: масштабирование картинок (не SVG) при ресайзе, и правильный возврат на исходную позицию
// TODO: картинки "обрезаются" если возвращаются или появляются с места, где есть их перекрытие (топбар, поле ввода)

3
src/components/appNavigationController.ts

@ -6,9 +6,10 @@ @@ -6,9 +6,10 @@
import { MOUNT_CLASS_TO } from "../config/debug";
import { isMobileSafari } from "../helpers/userAgent";
import { blurActiveElement, cancelEvent } from "../helpers/dom";
import { logger } from "../lib/logger";
import { doubleRaf } from "../helpers/schedulers";
import blurActiveElement from "../helpers/dom/blurActiveElement";
import { cancelEvent } from "../helpers/dom/cancelEvent";
export type NavigationItem = {
type: 'left' | 'right' | 'im' | 'chat' | 'popup' | 'media' | 'menu' | 'esg' | 'multiselect' | 'input-helper' | 'markup' | 'global-search',

4
src/components/appSearchSuper..ts

@ -5,11 +5,10 @@ @@ -5,11 +5,10 @@
*/
import { formatDateAccordingToToday, months } from "../helpers/date";
import { positionElementByIndex } from "../helpers/dom";
import { copy, getObjectKeysAndSort, safeAssign } from "../helpers/object";
import { escapeRegExp, limitSymbols } from "../helpers/string";
import appChatsManager from "../lib/appManagers/appChatsManager";
import appDialogsManager, { DialogDom } from "../lib/appManagers/appDialogsManager";
import appDialogsManager from "../lib/appManagers/appDialogsManager";
import appMessagesManager, { MyInputMessagesFilter, MyMessage } from "../lib/appManagers/appMessagesManager";
import appPeersManager from "../lib/appManagers/appPeersManager";
import appPhotosManager from "../lib/appManagers/appPhotosManager";
@ -39,6 +38,7 @@ import findUpTag from "../helpers/dom/findUpTag"; @@ -39,6 +38,7 @@ import findUpTag from "../helpers/dom/findUpTag";
import appSidebarRight from "./sidebarRight";
import mediaSizes from "../helpers/mediaSizes";
import appImManager from "../lib/appManagers/appImManager";
import positionElementByIndex from "../helpers/dom/positionElementByIndex";
//const testScroll = false;

3
src/components/appSelectPeers.ts

@ -10,7 +10,6 @@ import appMessagesManager, { Dialog } from "../lib/appManagers/appMessagesManage @@ -10,7 +10,6 @@ import appMessagesManager, { Dialog } from "../lib/appManagers/appMessagesManage
import appPhotosManager from "../lib/appManagers/appPhotosManager";
import appUsersManager from "../lib/appManagers/appUsersManager";
import rootScope from "../lib/rootScope";
import { cancelEvent, replaceContent } from "../helpers/dom";
import Scrollable from "./scrollable";
import { FocusDirection } from "../helpers/fastSmoothScroll";
import CheckboxField from "./checkboxField";
@ -20,6 +19,8 @@ import { i18n, LangPackKey, _i18n } from "../lib/langPack"; @@ -20,6 +19,8 @@ import { i18n, LangPackKey, _i18n } from "../lib/langPack";
import findUpAttribute from "../helpers/dom/findUpAttribute";
import findUpClassName from "../helpers/dom/findUpClassName";
import PeerTitle from "./peerTitle";
import { cancelEvent } from "../helpers/dom/cancelEvent";
import replaceContent from "../helpers/dom/replaceContent";
type PeerType = 'contacts' | 'dialogs' | 'channelParticipants';

3
src/components/audio.ts

@ -16,9 +16,10 @@ import { isSafari } from "../helpers/userAgent"; @@ -16,9 +16,10 @@ import { isSafari } from "../helpers/userAgent";
import appMessagesManager from "../lib/appManagers/appMessagesManager";
import rootScope from "../lib/rootScope";
import './middleEllipsis';
import { attachClickEvent, cancelEvent, detachClickEvent } from "../helpers/dom";
import { SearchSuperContext } from "./appSearchSuper.";
import { formatDateAccordingToToday } from "../helpers/date";
import { cancelEvent } from "../helpers/dom/cancelEvent";
import { attachClickEvent, detachClickEvent } from "../helpers/dom/clickEvent";
rootScope.on('messages_media_read', e => {
const {mids, peerId} = e;

3
src/components/avatar.ts

@ -7,12 +7,13 @@ @@ -7,12 +7,13 @@
import appMessagesManager from "../lib/appManagers/appMessagesManager";
import appProfileManager from "../lib/appManagers/appProfileManager";
import rootScope from "../lib/rootScope";
import { attachClickEvent, cancelEvent } from "../helpers/dom";
import AppMediaViewer, { AppMediaViewerAvatar } from "./appMediaViewer";
import { Message } from "../layer";
import appPeersManager from "../lib/appManagers/appPeersManager";
import appPhotosManager from "../lib/appManagers/appPhotosManager";
import type { LazyLoadQueueIntersector } from "./lazyLoadQueue";
import { attachClickEvent } from "../helpers/dom/clickEvent";
import { cancelEvent } from "../helpers/dom/cancelEvent";
const onAvatarUpdate = (peerId: number) => {
appProfileManager.removeFromAvatarsCache(peerId);

3
src/components/buttonMenu.ts

@ -4,7 +4,8 @@ @@ -4,7 +4,8 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { attachClickEvent, AttachClickOptions, cancelEvent, CLICK_EVENT_NAME } from "../helpers/dom";
import { cancelEvent } from "../helpers/dom/cancelEvent";
import { AttachClickOptions, attachClickEvent, CLICK_EVENT_NAME } from "../helpers/dom/clickEvent";
import ListenerSetter from "../helpers/listenerSetter";
import { i18n, LangPackKey } from "../lib/langPack";
import CheckboxField from "./checkboxField";

3
src/components/buttonMenuToggle.ts

@ -4,7 +4,8 @@ @@ -4,7 +4,8 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { AttachClickOptions, cancelEvent, CLICK_EVENT_NAME } from "../helpers/dom";
import { cancelEvent } from "../helpers/dom/cancelEvent";
import { AttachClickOptions, CLICK_EVENT_NAME } from "../helpers/dom/clickEvent";
import ListenerSetter from "../helpers/listenerSetter";
import ButtonIcon from "./buttonIcon";
import ButtonMenu, { ButtonMenuItemOptions } from "./buttonMenu";

3
src/components/chat/audio.ts

@ -9,12 +9,13 @@ import type { AppPeersManager } from "../../lib/appManagers/appPeersManager"; @@ -9,12 +9,13 @@ import type { AppPeersManager } from "../../lib/appManagers/appPeersManager";
import type ChatTopbar from "./topbar";
import { RichTextProcessor } from "../../lib/richtextprocessor";
import rootScope from "../../lib/rootScope";
import { attachClickEvent, cancelEvent } from "../../helpers/dom";
import appMediaPlaybackController from "../appMediaPlaybackController";
import DivAndCaption from "../divAndCaption";
import { formatDate } from "../wrappers";
import PinnedContainer from "./pinnedContainer";
import Chat from "./chat";
import { cancelEvent } from "../../helpers/dom/cancelEvent";
import { attachClickEvent } from "../../helpers/dom/clickEvent";
export default class ChatAudio extends PinnedContainer {
private toggleEl: HTMLElement;

132
src/components/chat/bubbles.ts

@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
*/
import type { AppImManager } from "../../lib/appManagers/appImManager";
import type { AppMessagesManager, HistoryResult, MyMessage } from "../../lib/appManagers/appMessagesManager";
import type { AppMessagesManager, HistoryResult, HistoryStorage, MyMessage } from "../../lib/appManagers/appMessagesManager";
import type { AppStickersManager } from "../../lib/appManagers/appStickersManager";
import type { AppUsersManager } from "../../lib/appManagers/appUsersManager";
import type { AppInlineBotsManager } from "../../lib/appManagers/appInlineBotsManager";
@ -15,7 +15,6 @@ import type { AppPeersManager } from "../../lib/appManagers/appPeersManager"; @@ -15,7 +15,6 @@ import type { AppPeersManager } from "../../lib/appManagers/appPeersManager";
import type sessionStorage from '../../lib/sessionStorage';
import type Chat from "./chat";
import { CHAT_ANIMATION_GROUP } from "../../lib/appManagers/appImManager";
import { cancelEvent, whichChild, attachClickEvent, positionElementByIndex, reflowScrollableElement, replaceContent, htmlToDocumentFragment, setInnerHTML } from "../../helpers/dom";
import { getObjectKeysAndSort } from "../../helpers/object";
import { isTouchSupported } from "../../helpers/touchSupport";
import { logger } from "../../lib/logger";
@ -60,6 +59,14 @@ import findUpTag from "../../helpers/dom/findUpTag"; @@ -60,6 +59,14 @@ import findUpTag from "../../helpers/dom/findUpTag";
import { toast } from "../toast";
import { getElementByPoint } from "../../helpers/dom/getElementByPoint";
import { getMiddleware } from "../../helpers/middleware";
import { cancelEvent } from "../../helpers/dom/cancelEvent";
import { attachClickEvent } from "../../helpers/dom/clickEvent";
import htmlToDocumentFragment from "../../helpers/dom/htmlToDocumentFragment";
import positionElementByIndex from "../../helpers/dom/positionElementByIndex";
import reflowScrollableElement from "../../helpers/dom/reflowScrollableElement";
import replaceContent from "../../helpers/dom/replaceContent";
import setInnerHTML from "../../helpers/dom/setInnerHTML";
import whichChild from "../../helpers/dom/whichChild";
const USE_MEDIA_TAILS = false;
const IGNORE_ACTIONS: Message.messageService['action']['_'][] = [/* 'messageActionHistoryClear' */];
@ -97,7 +104,9 @@ export default class ChatBubbles { @@ -97,7 +104,9 @@ export default class ChatBubbles {
private stickyIntersector: StickyIntersector;
private unreadedObserver: IntersectionObserver;
private unreaded: number[] = [];
private unreaded: Map<HTMLElement, number> = new Map();
private unreadedSeen: Set<number> = new Set();
private readPromise: Promise<void>;
public bubbleGroups: BubbleGroups;
@ -131,6 +140,7 @@ export default class ChatBubbles { @@ -131,6 +140,7 @@ export default class ChatBubbles {
private needReflowScroll: boolean;
private fetchNewPromise: Promise<void>;
private historyStorage: HistoryStorage;
constructor(private chat: Chat, private appMessagesManager: AppMessagesManager, private appStickersManager: AppStickersManager, private appUsersManager: AppUsersManager, private appInlineBotsManager: AppInlineBotsManager, private appPhotosManager: AppPhotosManager, private appDocsManager: AppDocsManager, private appPeersManager: AppPeersManager, private appChatsManager: AppChatsManager, private storage: typeof sessionStorage) {
//this.chat.log.error('Bubbles construction');
@ -492,48 +502,13 @@ export default class ChatBubbles { @@ -492,48 +502,13 @@ export default class ChatBubbles {
});
this.unreadedObserver = new IntersectionObserver((entries) => {
if(this.chat.appImManager.offline) { // ! but you can scroll the page without triggering 'focus', need something now
return;
}
const readed: number[] = [];
entries.forEach(entry => {
if(entry.isIntersecting) {
const target = entry.target as HTMLElement;
const mid = +target.dataset.mid;
readed.push(mid);
this.unreadedObserver.unobserve(target);
const mid = this.unreaded.get(target as HTMLElement);
this.onUnreadedInViewport(target, mid);
}
});
if(readed.length) {
let maxId = Math.max(...readed);
if(this.scrollable.loadedAll.bottom) {
const bubblesMaxId = Math.max(...Object.keys(this.bubbles).map(i => +i));
if(maxId >= bubblesMaxId) {
maxId = this.appMessagesManager.getHistoryStorage(this.peerId, this.chat.threadId).maxId || maxId;
}
}
let length = readed.length;
for(let i = this.unreaded.length - 1; i >= 0; --i) {
if(this.unreaded[i] <= maxId) {
length++;
this.unreaded.splice(i, 1);
}
}
if(DEBUG) {
this.log('will readHistory by ids:', maxId, length);
}
/* false && */ this.appMessagesManager.readHistory(this.peerId, maxId, this.chat.threadId).catch((err: any) => {
this.log.error('readHistory err:', err);
this.appMessagesManager.readHistory(this.peerId, maxId, this.chat.threadId);
});
}
});
if('ResizeObserver' in window) {
@ -635,6 +610,55 @@ export default class ChatBubbles { @@ -635,6 +610,55 @@ export default class ChatBubbles {
}
}
private onUnreadedInViewport(target: HTMLElement, mid: number) {
this.unreadedSeen.add(mid);
this.unreadedObserver.unobserve(target);
this.unreaded.delete(target);
this.readUnreaded();
}
private readUnreaded() {
if(this.readPromise) return;
const middleware = this.getMiddleware();
this.readPromise = rootScope.idle.focusPromise.then(() => {
if(!middleware()) return;
let maxId = Math.max(...Array.from(this.unreadedSeen));
// ? if message with maxId is not rendered ?
if(this.scrollable.loadedAll.bottom) {
const bubblesMaxId = Math.max(...Object.keys(this.bubbles).map(i => +i));
if(maxId >= bubblesMaxId) {
maxId = Math.max(this.appMessagesManager.getHistoryStorage(this.peerId, this.chat.threadId).maxId || 0, maxId);
}
}
this.unreaded.forEach((mid, target) => {
if(mid <= maxId) {
this.onUnreadedInViewport(target, mid);
}
});
this.unreadedSeen.clear();
if(DEBUG) {
this.log('will readHistory by maxId:', maxId);
}
return this.appMessagesManager.readHistory(this.peerId, maxId, this.chat.threadId).catch((err: any) => {
this.log.error('readHistory err:', err);
this.appMessagesManager.readHistory(this.peerId, maxId, this.chat.threadId);
}).finally(() => {
if(!middleware()) return;
this.readPromise = undefined;
if(this.unreadedSeen.size) {
this.readUnreaded();
}
});
});
}
public constructPinnedHelpers() {
this.listenerSetter.add(rootScope, 'peer_pinned_messages', (e) => {
const {peerId, mids, pinned} = e;
@ -1170,6 +1194,7 @@ export default class ChatBubbles { @@ -1170,6 +1194,7 @@ export default class ChatBubbles {
this.bubbleGroups.removeBubble(bubble);
if(this.unreadedObserver) {
this.unreadedObserver.unobserve(bubble);
this.unreaded.delete(bubble);
}
//this.unreaded.findAndSplice(mid => mid === id);
bubble.remove();
@ -1409,7 +1434,9 @@ export default class ChatBubbles { @@ -1409,7 +1434,9 @@ export default class ChatBubbles {
if(this.unreadedObserver) {
this.unreadedObserver.disconnect();
this.unreaded.length = 0;
this.unreaded.clear();
this.unreadedSeen.clear();
this.readPromise = undefined;
}
this.loadedTopTimes = this.loadedBottomTimes = 0;
@ -1435,8 +1462,8 @@ export default class ChatBubbles { @@ -1435,8 +1462,8 @@ export default class ChatBubbles {
return {cached: true, promise: this.chat.setPeerPromise};
} */
const historyStorage = this.appMessagesManager.getHistoryStorage(peerId, this.chat.threadId);
let topMessage = this.chat.type === 'pinned' ? this.appMessagesManager.pinnedMessages[peerId].maxId : historyStorage.maxId ?? 0;
this.historyStorage = this.appMessagesManager.getHistoryStorage(peerId, this.chat.threadId);
let topMessage = this.chat.type === 'pinned' ? this.appMessagesManager.pinnedMessages[peerId].maxId : this.historyStorage.maxId ?? 0;
const isTarget = lastMsgId !== undefined;
// * this one will fix topMessage for null message in history (e.g. channel comments with only 1 comment and it is a topMessage)
@ -1491,7 +1518,7 @@ export default class ChatBubbles { @@ -1491,7 +1518,7 @@ export default class ChatBubbles {
}
if(DEBUG) {
this.log('setPeer peerId:', this.peerId, historyStorage, lastMsgId, topMessage);
this.log('setPeer peerId:', this.peerId, this.historyStorage, lastMsgId, topMessage);
}
// add last message, bc in getHistory will load < max_id
@ -1666,7 +1693,11 @@ export default class ChatBubbles { @@ -1666,7 +1693,11 @@ export default class ChatBubbles {
});
};
f();
if(samePeer) {
setTimeout(f, 30e3);
} else {
f();
}
}
});
}
@ -1674,7 +1705,7 @@ export default class ChatBubbles { @@ -1674,7 +1705,7 @@ export default class ChatBubbles {
this.log('scrolledAllDown:', this.scrollable.loadedAll.bottom);
//if(!this.unreaded.length && dialog) { // lol
if(this.scrollable.loadedAll.bottom && topMessage) { // lol
if(this.scrollable.loadedAll.bottom && topMessage && !this.unreaded.size) { // lol
this.onScrolledAllDown();
}
@ -1874,13 +1905,12 @@ export default class ChatBubbles { @@ -1874,13 +1905,12 @@ export default class ChatBubbles {
contentWrapper.appendChild(bubbleContainer);
bubble.appendChild(contentWrapper);
if(!our && !message.pFlags.out) {
if(!our && !message.pFlags.out && this.unreadedObserver) {
//this.log('not our message', message, message.pFlags.unread);
if(message.pFlags.unread && this.unreadedObserver) {
const isUnread = message.pFlags.unread || (this.historyStorage.readMaxId !== undefined && this.historyStorage.readMaxId < message.mid);
if(isUnread) {
this.unreadedObserver.observe(bubble);
if(!this.unreaded.indexOf(message.mid)) {
this.unreaded.push(message.mid);
}
this.unreaded.set(bubble, message.mid);
}
}
} else {

5
src/components/chat/contextMenu.ts

@ -10,7 +10,6 @@ import type { AppPeersManager } from "../../lib/appManagers/appPeersManager"; @@ -10,7 +10,6 @@ import type { AppPeersManager } from "../../lib/appManagers/appPeersManager";
import type { AppPollsManager, Poll } from "../../lib/appManagers/appPollsManager";
import type Chat from "./chat";
import { isTouchSupported } from "../../helpers/touchSupport";
import { attachClickEvent, cancelEvent, cancelSelection, isSelectionEmpty } from "../../helpers/dom";
import ButtonMenu, { ButtonMenuItemOptions } from "../buttonMenu";
import { attachContextMenuListener, openBtnMenu, positionMenu } from "../misc";
import PopupDeleteMessages from "../popups/deleteMessages";
@ -21,6 +20,10 @@ import PopupSendNow from "../popups/sendNow"; @@ -21,6 +20,10 @@ import PopupSendNow from "../popups/sendNow";
import { toast } from "../toast";
import I18n, { LangPackKey } from "../../lib/langPack";
import findUpClassName from "../../helpers/dom/findUpClassName";
import { cancelEvent } from "../../helpers/dom/cancelEvent";
import cancelSelection from "../../helpers/dom/cancelSelection";
import { attachClickEvent } from "../../helpers/dom/clickEvent";
import isSelectionEmpty from "../../helpers/dom/isSelectionEmpty";
export default class ChatContextMenu {
private buttons: (ButtonMenuItemOptions & {verify: () => boolean, notDirect?: () => boolean, withSelection?: true})[];

4
src/components/chat/dragAndDrop.ts

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { generatePathData } from "../../helpers/dom";
import generatePathData from "../../helpers/generatePathData";
import { i18n, LangPackKey } from "../../lib/langPack";
export default class ChatDragAndDrop {
@ -90,4 +90,4 @@ export default class ChatDragAndDrop { @@ -90,4 +90,4 @@ export default class ChatDragAndDrop {
const d = generatePathData(pos, pos, sizeX, sizeY, radius, radius, radius, radius);
this.path.setAttributeNS(null, 'd', d);
}
}
}

9
src/components/chat/input.ts

@ -20,7 +20,6 @@ import apiManager from "../../lib/mtproto/mtprotoworker"; @@ -20,7 +20,6 @@ import apiManager from "../../lib/mtproto/mtprotoworker";
//import Recorder from '../opus-recorder/dist/recorder.min';
import opusDecodeController from "../../lib/opusDecodeController";
import RichTextProcessor from "../../lib/richtextprocessor";
import { attachClickEvent, blurActiveElement, cancelEvent, cancelSelection, getRichValue, isInputEmpty, markdownTags, MarkdownType, placeCaretAtEnd, isSendShortcutPressed } from "../../helpers/dom";
import { ButtonMenuItemOptions } from '../buttonMenu';
import emoticonsDropdown from "../emoticonsDropdown";
import PopupCreatePoll from "../popups/createPoll";
@ -48,6 +47,14 @@ import { i18n } from '../../lib/langPack'; @@ -48,6 +47,14 @@ import { i18n } from '../../lib/langPack';
import { generateTail } from './bubbles';
import findUpClassName from '../../helpers/dom/findUpClassName';
import ButtonCorner from '../buttonCorner';
import blurActiveElement from '../../helpers/dom/blurActiveElement';
import { cancelEvent } from '../../helpers/dom/cancelEvent';
import cancelSelection from '../../helpers/dom/cancelSelection';
import { attachClickEvent } from '../../helpers/dom/clickEvent';
import getRichValue, { MarkdownType, markdownTags } from '../../helpers/dom/getRichValue';
import isInputEmpty from '../../helpers/dom/isInputEmpty';
import isSendShortcutPressed from '../../helpers/dom/isSendShortcutPressed';
import placeCaretAtEnd from '../../helpers/dom/placeCaretAtEnd';
const RECORD_MIN_TIME = 500;
const POSTING_MEDIA_NOT_ALLOWED = 'Posting media content isn\'t allowed in this group.';

6
src/components/chat/markupTooltip.ts

@ -5,7 +5,6 @@ @@ -5,7 +5,6 @@
*/
import type { AppImManager } from "../../lib/appManagers/appImManager";
import { MarkdownType, cancelEvent, getSelectedNodes, markdownTags, attachClickEvent, isSelectionEmpty } from "../../helpers/dom";
import RichTextProcessor from "../../lib/richtextprocessor";
import ButtonIcon from "../buttonIcon";
import { clamp } from "../../helpers/number";
@ -13,6 +12,11 @@ import { isTouchSupported } from "../../helpers/touchSupport"; @@ -13,6 +12,11 @@ import { isTouchSupported } from "../../helpers/touchSupport";
import { isApple, isMobile } from "../../helpers/userAgent";
import appNavigationController from "../appNavigationController";
import { _i18n } from "../../lib/langPack";
import { cancelEvent } from "../../helpers/dom/cancelEvent";
import { attachClickEvent } from "../../helpers/dom/clickEvent";
import { MarkdownType, markdownTags } from "../../helpers/dom/getRichValue";
import getSelectedNodes from "../../helpers/dom/getSelectedNodes";
import isSelectionEmpty from "../../helpers/dom/isSelectionEmpty";
//import { logger } from "../../lib/logger";
export default class MarkupTooltip {

3
src/components/chat/pinnedContainer.ts

@ -7,10 +7,11 @@ @@ -7,10 +7,11 @@
import type Chat from "./chat";
import type ChatTopbar from "./topbar";
import mediaSizes from "../../helpers/mediaSizes";
import { attachClickEvent, cancelEvent } from "../../helpers/dom";
import DivAndCaption from "../divAndCaption";
import { ripple } from "../ripple";
import ListenerSetter from "../../helpers/listenerSetter";
import { cancelEvent } from "../../helpers/dom/cancelEvent";
import { attachClickEvent } from "../../helpers/dom/clickEvent";
//const classNames: string[] = [];
const classNames: string[] = ['is-pinned-message-shown', 'is-pinned-audio-shown'];

4
src/components/chat/pinnedMessage.ts

@ -12,13 +12,15 @@ import PinnedContainer from "./pinnedContainer"; @@ -12,13 +12,15 @@ import PinnedContainer from "./pinnedContainer";
import PinnedMessageBorder from "./pinnedMessageBorder";
import ReplyContainer, { wrapReplyDivAndCaption } from "./replyContainer";
import rootScope from "../../lib/rootScope";
import { attachClickEvent, cancelEvent, handleScrollSideEvent } from "../../helpers/dom";
import Chat from "./chat";
import ListenerSetter from "../../helpers/listenerSetter";
import ButtonIcon from "../buttonIcon";
import { debounce } from "../../helpers/schedulers";
import { getHeavyAnimationPromise } from "../../hooks/useHeavyAnimationCheck";
import { i18n } from "../../lib/langPack";
import { cancelEvent } from "../../helpers/dom/cancelEvent";
import { attachClickEvent } from "../../helpers/dom/clickEvent";
import handleScrollSideEvent from "../../helpers/dom/handleScrollSideEvent";
class AnimatedSuper {
static DURATION = 200;

3
src/components/chat/search.ts

@ -5,13 +5,14 @@ @@ -5,13 +5,14 @@
*/
import type ChatTopbar from "./topbar";
import { cancelEvent, whichChild } from "../../helpers/dom";
import AppSearch, { SearchGroup } from "../appSearch";
import PopupDatePicker from "../popups/datePicker";
import { ripple } from "../ripple";
import InputSearch from "../inputSearch";
import type Chat from "./chat";
import findUpTag from "../../helpers/dom/findUpTag";
import { cancelEvent } from "../../helpers/dom/cancelEvent";
import whichChild from "../../helpers/dom/whichChild";
export default class ChatSearch {
private element: HTMLElement;

5
src/components/chat/selection.ts

@ -9,7 +9,6 @@ import type ChatBubbles from "./bubbles"; @@ -9,7 +9,6 @@ import type ChatBubbles from "./bubbles";
import type ChatInput from "./input";
import type Chat from "./chat";
import { isTouchSupported } from "../../helpers/touchSupport";
import { blurActiveElement, cancelEvent, cancelSelection, getSelectedText } from "../../helpers/dom";
import Button from "../button";
import ButtonIcon from "../buttonIcon";
import CheckboxField from "../checkboxField";
@ -23,6 +22,10 @@ import appNavigationController from "../appNavigationController"; @@ -23,6 +22,10 @@ import appNavigationController from "../appNavigationController";
import { isMobileSafari } from "../../helpers/userAgent";
import I18n, { i18n, _i18n } from "../../lib/langPack";
import findUpClassName from "../../helpers/dom/findUpClassName";
import blurActiveElement from "../../helpers/dom/blurActiveElement";
import { cancelEvent } from "../../helpers/dom/cancelEvent";
import cancelSelection from "../../helpers/dom/cancelSelection";
import getSelectedText from "../../helpers/dom/getSelectedText";
const MAX_SELECTION_LENGTH = 100;
//const MIN_CLICK_MOVE = 32; // minimum bubble height

2
src/components/chat/sendContextMenu.ts

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { cancelEvent } from "../../helpers/dom";
import { cancelEvent } from "../../helpers/dom/cancelEvent";
import ListenerSetter from "../../helpers/listenerSetter";
import rootScope from "../../lib/rootScope";
import ButtonMenu, { ButtonMenuItemOptions } from "../buttonMenu";

4
src/components/chat/topbar.ts

@ -10,7 +10,6 @@ import type { AppMessagesManager } from "../../lib/appManagers/appMessagesManage @@ -10,7 +10,6 @@ import type { AppMessagesManager } from "../../lib/appManagers/appMessagesManage
import type { AppPeersManager } from "../../lib/appManagers/appPeersManager";
import type { AppSidebarRight } from "../sidebarRight";
import type Chat from "./chat";
import { cancelEvent, attachClickEvent, blurActiveElement, replaceContent } from "../../helpers/dom";
import mediaSizes, { ScreenSize } from "../../helpers/mediaSizes";
import { isSafari } from "../../helpers/userAgent";
import rootScope from "../../lib/rootScope";
@ -31,6 +30,9 @@ import AppPrivateSearchTab from "../sidebarRight/tabs/search"; @@ -31,6 +30,9 @@ import AppPrivateSearchTab from "../sidebarRight/tabs/search";
import PeerTitle from "../peerTitle";
import { i18n } from "../../lib/langPack";
import findUpClassName from "../../helpers/dom/findUpClassName";
import blurActiveElement from "../../helpers/dom/blurActiveElement";
import { cancelEvent } from "../../helpers/dom/cancelEvent";
import { attachClickEvent } from "../../helpers/dom/clickEvent";
export default class ChatTopbar {
container: HTMLDivElement;

4
src/components/emoticonsDropdown/index.ts

@ -8,7 +8,6 @@ import { isTouchSupported } from "../../helpers/touchSupport"; @@ -8,7 +8,6 @@ import { isTouchSupported } from "../../helpers/touchSupport";
import appChatsManager from "../../lib/appManagers/appChatsManager";
import appImManager from "../../lib/appManagers/appImManager";
import rootScope from "../../lib/rootScope";
import { attachClickEvent, blurActiveElement, whichChild } from "../../helpers/dom";
import animationIntersector from "../animationIntersector";
import { horizontalMenu } from "../horizontalMenu";
import LazyLoadQueue, { LazyLoadQueueIntersector } from "../lazyLoadQueue";
@ -25,6 +24,9 @@ import AppStickersTab from "../sidebarRight/tabs/stickers"; @@ -25,6 +24,9 @@ import AppStickersTab from "../sidebarRight/tabs/stickers";
import findUpClassName from "../../helpers/dom/findUpClassName";
import findUpTag from "../../helpers/dom/findUpTag";
import ListenerSetter from "../../helpers/listenerSetter";
import blurActiveElement from "../../helpers/dom/blurActiveElement";
import { attachClickEvent } from "../../helpers/dom/clickEvent";
import whichChild from "../../helpers/dom/whichChild";
export const EMOTICONSSTICKERGROUP = 'emoticons-dropdown';

2
src/components/gifsMasonry.ts

@ -4,7 +4,6 @@ @@ -4,7 +4,6 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { calcImageInBox } from "../helpers/dom";
import appDocsManager, {MyDocument} from "../lib/appManagers/appDocsManager";
import { wrapVideo } from "./wrappers";
import { LazyLoadQueueRepeat2 } from "./lazyLoadQueue";
@ -12,6 +11,7 @@ import animationIntersector from "./animationIntersector"; @@ -12,6 +11,7 @@ import animationIntersector from "./animationIntersector";
import Scrollable from "./scrollable";
import { CancellablePromise, deferredPromise } from "../helpers/cancellablePromise";
import renderImageFromUrl from "../helpers/dom/renderImageFromUrl";
import calcImageInBox from "../helpers/calcImageInBox";
const width = 400;
const maxSingleWidth = width - 100;

2
src/components/horizontalMenu.ts

@ -4,13 +4,13 @@ @@ -4,13 +4,13 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { whichChild } from "../helpers/dom";
import { TransitionSlider } from "./transition";
import { ScrollableX } from "./scrollable";
import rootScope from "../lib/rootScope";
import { fastRaf } from "../helpers/schedulers";
import { FocusDirection } from "../helpers/fastSmoothScroll";
import findUpAsChild from "../helpers/dom/findUpAsChild";
import whichChild from "../helpers/dom/whichChild";
export function horizontalMenu(tabs: HTMLElement, content: HTMLElement, onClick?: (id: number, tabContent: HTMLDivElement, animate: boolean) => void | boolean, onTransitionEnd?: () => void, transitionTime = 250, scrollableX?: ScrollableX) {
const selectTab = TransitionSlider(content, tabs || content.dataset.animation === 'tabs' ? 'tabs' : 'navigation', transitionTime, onTransitionEnd);

4
src/components/inputField.ts

@ -4,9 +4,9 @@ @@ -4,9 +4,9 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { getRichValue, isInputEmpty } from "../helpers/dom";
import getRichValue from "../helpers/dom/getRichValue";
import isInputEmpty from "../helpers/dom/isInputEmpty";
import { debounce } from "../helpers/schedulers";
import { checkRTL } from "../helpers/string";
import { i18n, LangPackKey, _i18n } from "../lib/langPack";
import RichTextProcessor from "../lib/richtextprocessor";

9
src/components/languageChangeButton.ts

@ -1,4 +1,11 @@ @@ -1,4 +1,11 @@
import { attachClickEvent, cancelEvent } from "../helpers/dom";
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { cancelEvent } from "../helpers/dom/cancelEvent";
import { attachClickEvent } from "../helpers/dom/clickEvent";
import { Config, LangPackDifference, LangPackString } from "../layer";
import I18n, { LangPackKey } from "../lib/langPack";
import apiManager from "../lib/mtproto/mtprotoworker";

3
src/components/misc.ts

@ -6,7 +6,8 @@ @@ -6,7 +6,8 @@
import { MOUNT_CLASS_TO } from "../config/debug";
import Countries, { Country, PhoneCodesMain } from "../countries";
import { cancelEvent, CLICK_EVENT_NAME } from "../helpers/dom";
import { cancelEvent } from "../helpers/dom/cancelEvent";
import { CLICK_EVENT_NAME } from "../helpers/dom/clickEvent";
import ListenerSetter from "../helpers/listenerSetter";
import mediaSizes from "../helpers/mediaSizes";
import { isTouchSupported } from "../helpers/touchSupport";

2
src/components/passwordInputField.ts

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { cancelEvent } from "../helpers/dom";
import { cancelEvent } from "../helpers/dom/cancelEvent";
import InputField, { InputFieldOptions } from "./inputField";
export default class PasswordInputField extends InputField {

2
src/components/peerTitle.ts

@ -7,8 +7,8 @@ @@ -7,8 +7,8 @@
import { MOUNT_CLASS_TO } from "../config/debug";
import appPeersManager from "../lib/appManagers/appPeersManager";
import rootScope from "../lib/rootScope";
import { replaceContent } from "../helpers/dom";
import { i18n } from "../lib/langPack";
import replaceContent from "../helpers/dom/replaceContent";
export type PeerTitleOptions = {
peerId: number,

4
src/components/poll.ts

@ -11,7 +11,6 @@ import appPollsManager, { Poll, PollResults } from "../lib/appManagers/appPollsM @@ -11,7 +11,6 @@ import appPollsManager, { Poll, PollResults } from "../lib/appManagers/appPollsM
import serverTimeManager from "../lib/mtproto/serverTimeManager";
import { RichTextProcessor } from "../lib/richtextprocessor";
import rootScope from "../lib/rootScope";
import { attachClickEvent, cancelEvent, detachClickEvent, replaceContent } from "../helpers/dom";
import { ripple } from "./ripple";
import appSidebarRight from "./sidebarRight";
import AppPollResultsTab from "./sidebarRight/tabs/pollResults";
@ -19,6 +18,9 @@ import { i18n, LangPackKey } from "../lib/langPack"; @@ -19,6 +18,9 @@ import { i18n, LangPackKey } from "../lib/langPack";
import { fastRaf } from "../helpers/schedulers";
import SetTransition from "./singleTransition";
import findUpClassName from "../helpers/dom/findUpClassName";
import { cancelEvent } from "../helpers/dom/cancelEvent";
import { attachClickEvent, detachClickEvent } from "../helpers/dom/clickEvent";
import replaceContent from "../helpers/dom/replaceContent";
let lineTotalLength = 0;
//const tailLength = 9;

5
src/components/popups/createPoll.ts

@ -7,7 +7,6 @@ @@ -7,7 +7,6 @@
import type { Poll } from "../../lib/appManagers/appPollsManager";
import type Chat from "../chat/chat";
import PopupElement from ".";
import { cancelEvent, getRichValue, isInputEmpty, whichChild } from "../../helpers/dom";
import CheckboxField from "../checkboxField";
import InputField from "../inputField";
import RadioField from "../radioField";
@ -16,6 +15,10 @@ import SendContextMenu from "../chat/sendContextMenu"; @@ -16,6 +15,10 @@ import SendContextMenu from "../chat/sendContextMenu";
import { MessageEntity } from "../../layer";
import I18n, { _i18n, i18n } from "../../lib/langPack";
import findUpTag from "../../helpers/dom/findUpTag";
import { cancelEvent } from "../../helpers/dom/cancelEvent";
import getRichValue from "../../helpers/dom/getRichValue";
import isInputEmpty from "../../helpers/dom/isInputEmpty";
import whichChild from "../../helpers/dom/whichChild";
const MAX_LENGTH_QUESTION = 255;
const MAX_LENGTH_OPTION = 100;

2
src/components/popups/index.ts

@ -5,12 +5,12 @@ @@ -5,12 +5,12 @@
*/
import rootScope from "../../lib/rootScope";
import { blurActiveElement } from "../../helpers/dom";
import { ripple } from "../ripple";
import animationIntersector from "../animationIntersector";
import appNavigationController, { NavigationItem } from "../appNavigationController";
import { i18n, LangPackKey } from "../../lib/langPack";
import findUpClassName from "../../helpers/dom/findUpClassName";
import blurActiveElement from "../../helpers/dom/blurActiveElement";
export type PopupButton = {
text?: string,

4
src/components/popups/newMedia.ts

@ -5,7 +5,6 @@ @@ -5,7 +5,6 @@
*/
import type Chat from "../chat/chat";
import { calcImageInBox, placeCaretAtEnd, isSendShortcutPressed } from "../../helpers/dom";
import InputField from "../inputField";
import PopupElement from ".";
import Scrollable from "../scrollable";
@ -17,6 +16,9 @@ import { createPosterFromVideo, onVideoLoad } from "../../helpers/files"; @@ -17,6 +16,9 @@ import { createPosterFromVideo, onVideoLoad } from "../../helpers/files";
import { MyDocument } from "../../lib/appManagers/appDocsManager";
import I18n, { i18n, LangPackKey } from "../../lib/langPack";
import appDownloadManager from "../../lib/appManagers/appDownloadManager";
import calcImageInBox from "../../helpers/calcImageInBox";
import isSendShortcutPressed from "../../helpers/dom/isSendShortcutPressed";
import placeCaretAtEnd from "../../helpers/dom/placeCaretAtEnd";
type SendFileParams = Partial<{
file: File,

2
src/components/popups/stickers.ts

@ -12,13 +12,13 @@ import { wrapSticker } from "../wrappers"; @@ -12,13 +12,13 @@ import { wrapSticker } from "../wrappers";
import LazyLoadQueue from "../lazyLoadQueue";
import { putPreloader } from "../misc";
import animationIntersector from "../animationIntersector";
import { toggleDisability } from "../../helpers/dom";
import appImManager from "../../lib/appManagers/appImManager";
import { StickerSet } from "../../layer";
import mediaSizes from "../../helpers/mediaSizes";
import { i18n } from "../../lib/langPack";
import Button from "../button";
import findUpClassName from "../../helpers/dom/findUpClassName";
import toggleDisability from "../../helpers/dom/toggleDisability";
const ANIMATION_GROUP = 'STICKERS-POPUP';

4
src/components/preloader.ts

@ -4,11 +4,13 @@ @@ -4,11 +4,13 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { isInDOM, cancelEvent, attachClickEvent } from "../helpers/dom";
import { CancellablePromise } from "../helpers/cancellablePromise";
import SetTransition from "./singleTransition";
import { fastRaf } from "../helpers/schedulers";
import { safeAssign } from "../helpers/object";
import { cancelEvent } from "../helpers/dom/cancelEvent";
import { attachClickEvent } from "../helpers/dom/clickEvent";
import isInDOM from "../helpers/dom/isInDOM";
const TRANSITION_TIME = 200;

2
src/components/row.ts

@ -10,7 +10,7 @@ import { ripple } from "./ripple"; @@ -10,7 +10,7 @@ import { ripple } from "./ripple";
import { SliderSuperTab } from "./slider";
import RadioForm from "./radioForm";
import { i18n, LangPackKey } from "../lib/langPack";
import { replaceContent } from "../helpers/dom";
import replaceContent from "../helpers/dom/replaceContent";
export default class Row {
public container: HTMLElement;

2
src/components/scrollable.ts

@ -8,7 +8,7 @@ import { isTouchSupported } from "../helpers/touchSupport"; @@ -8,7 +8,7 @@ import { isTouchSupported } from "../helpers/touchSupport";
import { logger, LogTypes } from "../lib/logger";
import fastSmoothScroll, { FocusDirection } from "../helpers/fastSmoothScroll";
import useHeavyAnimationCheck from "../hooks/useHeavyAnimationCheck";
import { cancelEvent } from "../helpers/dom";
import { cancelEvent } from "../helpers/dom/cancelEvent";
/*
var el = $0;
var height = 0;

5
src/components/sidebarLeft/index.ts

@ -34,7 +34,6 @@ import appNavigationController from "../appNavigationController"; @@ -34,7 +34,6 @@ import appNavigationController from "../appNavigationController";
import findUpClassName from "../../helpers/dom/findUpClassName";
import findUpTag from "../../helpers/dom/findUpTag";
import PeerTitle from "../peerTitle";
import { replaceContent } from "../../helpers/dom";
import App from "../../config/app";
import ButtonMenuToggle from "../buttonMenuToggle";
@ -607,3 +606,7 @@ export const generateSection = (appendTo: Scrollable, name?: LangPackKey, captio @@ -607,3 +606,7 @@ export const generateSection = (appendTo: Scrollable, name?: LangPackKey, captio
const appSidebarLeft = new AppSidebarLeft();
MOUNT_CLASS_TO.appSidebarLeft = appSidebarLeft;
export default appSidebarLeft;
function replaceContent(div: HTMLDivElement, title: HTMLElement) {
throw new Error("Function not implemented.");
}

4
src/components/sidebarLeft/tabs/2fa/email.ts

@ -11,13 +11,15 @@ import Button from "../../../button"; @@ -11,13 +11,15 @@ import Button from "../../../button";
import { SliderSuperTab } from "../../../slider";
import { wrapSticker } from "../../../wrappers";
import InputField from "../../../inputField";
import { attachClickEvent, cancelEvent, canFocus } from "../../../../helpers/dom";
import { putPreloader } from "../../../misc";
import passwordManager from "../../../../lib/mtproto/passwordManager";
import AppTwoStepVerificationSetTab from "./passwordSet";
import AppTwoStepVerificationEmailConfirmationTab from "./emailConfirmation";
import RichTextProcessor from "../../../../lib/richtextprocessor";
import PopupPeer from "../../../popups/peer";
import { cancelEvent } from "../../../../helpers/dom/cancelEvent";
import { canFocus } from "../../../../helpers/dom/canFocus";
import { attachClickEvent } from "../../../../helpers/dom/clickEvent";
export default class AppTwoStepVerificationEmailTab extends SliderSuperTab {
public inputField: InputField;

5
src/components/sidebarLeft/tabs/2fa/emailConfirmation.ts

@ -10,13 +10,16 @@ import appStickersManager from "../../../../lib/appManagers/appStickersManager"; @@ -10,13 +10,16 @@ import appStickersManager from "../../../../lib/appManagers/appStickersManager";
import Button from "../../../button";
import { SliderSuperTab } from "../../../slider";
import { wrapSticker } from "../../../wrappers";
import { attachClickEvent, canFocus, replaceContent, toggleDisability } from "../../../../helpers/dom";
import passwordManager from "../../../../lib/mtproto/passwordManager";
import AppTwoStepVerificationSetTab from "./passwordSet";
import CodeInputField from "../../../codeInputField";
import AppTwoStepVerificationEmailTab from "./email";
import { putPreloader } from "../../../misc";
import { i18n, _i18n } from "../../../../lib/langPack";
import { canFocus } from "../../../../helpers/dom/canFocus";
import { attachClickEvent } from "../../../../helpers/dom/clickEvent";
import replaceContent from "../../../../helpers/dom/replaceContent";
import toggleDisability from "../../../../helpers/dom/toggleDisability";
export default class AppTwoStepVerificationEmailConfirmationTab extends SliderSuperTab {
public codeInputField: CodeInputField;

5
src/components/sidebarLeft/tabs/2fa/enterPassword.ts

@ -6,7 +6,10 @@ @@ -6,7 +6,10 @@
import AppTwoStepVerificationTab from ".";
import { SettingSection } from "../..";
import { attachClickEvent, cancelEvent, canFocus, replaceContent } from "../../../../helpers/dom";
import { cancelEvent } from "../../../../helpers/dom/cancelEvent";
import { canFocus } from "../../../../helpers/dom/canFocus";
import { attachClickEvent } from "../../../../helpers/dom/clickEvent";
import replaceContent from "../../../../helpers/dom/replaceContent";
import { AccountPassword } from "../../../../layer";
import I18n, { i18n } from "../../../../lib/langPack";
import passwordManager from "../../../../lib/mtproto/passwordManager";

3
src/components/sidebarLeft/tabs/2fa/hint.ts

@ -12,9 +12,10 @@ import { SliderSuperTab } from "../../../slider"; @@ -12,9 +12,10 @@ import { SliderSuperTab } from "../../../slider";
import { wrapSticker } from "../../../wrappers";
import InputField from "../../../inputField";
import AppTwoStepVerificationEmailTab from "./email";
import { attachClickEvent, cancelEvent } from "../../../../helpers/dom";
import { toast } from "../../../toast";
import I18n from "../../../../lib/langPack";
import { cancelEvent } from "../../../../helpers/dom/cancelEvent";
import { attachClickEvent } from "../../../../helpers/dom/clickEvent";
export default class AppTwoStepVerificationHintTab extends SliderSuperTab {
public inputField: InputField;

2
src/components/sidebarLeft/tabs/2fa/index.ts

@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
*/
import { SettingSection } from "../..";
import { attachClickEvent } from "../../../../helpers/dom";
import { attachClickEvent } from "../../../../helpers/dom/clickEvent";
import { AccountPassword } from "../../../../layer";
import appStickersManager from "../../../../lib/appManagers/appStickersManager";
import { _i18n } from "../../../../lib/langPack";

2
src/components/sidebarLeft/tabs/2fa/passwordSet.ts

@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
*/
import { SettingSection } from "../..";
import { attachClickEvent } from "../../../../helpers/dom";
import { attachClickEvent } from "../../../../helpers/dom/clickEvent";
import appStickersManager from "../../../../lib/appManagers/appStickersManager";
import Button from "../../../button";
import { SliderSuperTab } from "../../../slider";

3
src/components/sidebarLeft/tabs/2fa/reEnterPassword.ts

@ -5,7 +5,6 @@ @@ -5,7 +5,6 @@
*/
import { SettingSection } from "../..";
import { attachClickEvent, cancelEvent } from "../../../../helpers/dom";
import { AccountPassword } from "../../../../layer";
import Button from "../../../button";
import PasswordInputField from "../../../passwordInputField";
@ -13,6 +12,8 @@ import { SliderSuperTab } from "../../../slider"; @@ -13,6 +12,8 @@ import { SliderSuperTab } from "../../../slider";
import TrackingMonkey from "../../../monkeys/tracking";
import AppTwoStepVerificationHintTab from "./hint";
import { InputState } from "../../../inputField";
import { cancelEvent } from "../../../../helpers/dom/cancelEvent";
import { attachClickEvent } from "../../../../helpers/dom/clickEvent";
export default class AppTwoStepVerificationReEnterPasswordTab extends SliderSuperTab {
public state: AccountPassword;

3
src/components/sidebarLeft/tabs/activeSessions.ts

@ -11,7 +11,6 @@ import Row from "../../row"; @@ -11,7 +11,6 @@ import Row from "../../row";
import { Authorization } from "../../../layer";
import { formatDateAccordingToToday } from "../../../helpers/date";
import { attachContextMenuListener, openBtnMenu, positionMenu } from "../../misc";
import { attachClickEvent, toggleDisability } from "../../../helpers/dom";
import ButtonMenu from "../../buttonMenu";
import apiManager from "../../../lib/mtproto/mtprotoworker";
import { toast } from "../../toast";
@ -19,6 +18,8 @@ import AppPrivacyAndSecurityTab from "./privacyAndSecurity"; @@ -19,6 +18,8 @@ import AppPrivacyAndSecurityTab from "./privacyAndSecurity";
import I18n from "../../../lib/langPack";
import PopupPeer from "../../popups/peer";
import findUpClassName from "../../../helpers/dom/findUpClassName";
import { attachClickEvent } from "../../../helpers/dom/clickEvent";
import toggleDisability from "../../../helpers/dom/toggleDisability";
export default class AppActiveSessionsTab extends SliderSuperTab {
public privacyTab: AppPrivacyAndSecurityTab;

2
src/components/sidebarLeft/tabs/background.ts

@ -8,7 +8,7 @@ import { generateSection } from ".."; @@ -8,7 +8,7 @@ import { generateSection } from "..";
import { averageColor } from "../../../helpers/averageColor";
import blur from "../../../helpers/blur";
import { deferredPromise } from "../../../helpers/cancellablePromise";
import { attachClickEvent } from "../../../helpers/dom";
import { attachClickEvent } from "../../../helpers/dom/clickEvent";
import findUpClassName from "../../../helpers/dom/findUpClassName";
import { requestFile } from "../../../helpers/files";
import highlightningColor from "../../../helpers/highlightningColor";

5
src/components/sidebarLeft/tabs/backgroundColor.ts

@ -1,6 +1,5 @@ @@ -1,6 +1,5 @@
import { SettingSection } from "..";
import { hexaToRgba } from "../../../helpers/color";
import { attachClickEvent } from "../../../helpers/dom";
import findUpClassName from "../../../helpers/dom/findUpClassName";
import highlightningColor from "../../../helpers/highlightningColor";
import { throttle } from "../../../helpers/schedulers";
@ -143,3 +142,7 @@ export default class AppBackgroundColorTab extends SliderSuperTab { @@ -143,3 +142,7 @@ export default class AppBackgroundColorTab extends SliderSuperTab {
return super.onCloseAfterTimeout();
}
}
function attachClickEvent(grid: HTMLDivElement, arg1: (e: any) => void, arg2: { listenerSetter: import("../../../helpers/listenerSetter").default; }) {
throw new Error("Function not implemented.");
}

5
src/components/sidebarLeft/tabs/blockedUsers.ts

@ -7,7 +7,6 @@ @@ -7,7 +7,6 @@
import { SliderSuperTab } from "../../slider";
import { SettingSection } from "..";
import { attachContextMenuListener, openBtnMenu, positionMenu } from "../../misc";
import { attachClickEvent } from "../../../helpers/dom";
import ButtonMenu from "../../buttonMenu";
import appDialogsManager from "../../../lib/appManagers/appDialogsManager";
import appUsersManager from "../../../lib/appManagers/appUsersManager";
@ -157,3 +156,7 @@ export default class AppBlockedUsersTab extends SliderSuperTab { @@ -157,3 +156,7 @@ export default class AppBlockedUsersTab extends SliderSuperTab {
return super.onCloseAfterTimeout();
}
}
function attachClickEvent(btnAdd: HTMLButtonElement, arg1: (e: any) => void, arg2: { listenerSetter: import("../../../helpers/listenerSetter").default; }) {
throw new Error("Function not implemented.");
}

4
src/components/sidebarLeft/tabs/chatFolders.ts

@ -7,7 +7,6 @@ @@ -7,7 +7,6 @@
import { SliderSuperTab } from "../../slider";
import lottieLoader, { RLottiePlayer } from "../../../lib/lottieLoader";
import { RichTextProcessor } from "../../../lib/richtextprocessor";
import { attachClickEvent, cancelEvent, positionElementByIndex } from "../../../helpers/dom";
import { toast } from "../../toast";
import type { MyDialogFilter } from "../../../lib/storages/filters";
import type { DialogFilterSuggested, DialogFilter } from "../../../layer";
@ -22,6 +21,9 @@ import AppEditFolderTab from "./editFolder"; @@ -22,6 +21,9 @@ import AppEditFolderTab from "./editFolder";
import Row from "../../row";
import { SettingSection } from "..";
import { i18n, i18n_, LangPackKey, join } from "../../../lib/langPack";
import { cancelEvent } from "../../../helpers/dom/cancelEvent";
import { attachClickEvent } from "../../../helpers/dom/clickEvent";
import positionElementByIndex from "../../../helpers/dom/positionElementByIndex";
export default class AppChatFoldersTab extends SliderSuperTab {
private createFolderBtn: HTMLElement;

2
src/components/sidebarLeft/tabs/contacts.ts

@ -10,8 +10,8 @@ import appUsersManager from "../../../lib/appManagers/appUsersManager"; @@ -10,8 +10,8 @@ import appUsersManager from "../../../lib/appManagers/appUsersManager";
import appPhotosManager from "../../../lib/appManagers/appPhotosManager";
import rootScope from "../../../lib/rootScope";
import InputSearch from "../../inputSearch";
import { canFocus } from "../../../helpers/dom";
import { isMobile } from "../../../helpers/userAgent";
import { canFocus } from "../../../helpers/dom/canFocus";
// TODO: поиск по людям глобальный, если не нашло в контактах никого

1
src/components/sidebarLeft/tabs/editFolder.ts

@ -8,7 +8,6 @@ import { deepEqual, copy } from "../../../helpers/object"; @@ -8,7 +8,6 @@ import { deepEqual, copy } from "../../../helpers/object";
import appDialogsManager from "../../../lib/appManagers/appDialogsManager";
import { MyDialogFilter as DialogFilter } from "../../../lib/storages/filters";
import lottieLoader, { RLottiePlayer } from "../../../lib/lottieLoader";
import { ripple } from "../../ripple";
import { SliderSuperTab } from "../../slider";
import { toast } from "../../toast";
import appMessagesManager from "../../../lib/appManagers/appMessagesManager";

2
src/components/sidebarLeft/tabs/editProfile.ts

@ -8,10 +8,10 @@ import appProfileManager from "../../../lib/appManagers/appProfileManager"; @@ -8,10 +8,10 @@ import appProfileManager from "../../../lib/appManagers/appProfileManager";
import appUsersManager from "../../../lib/appManagers/appUsersManager";
import InputField from "../../inputField";
import { SliderSuperTab } from "../../slider";
import { attachClickEvent } from "../../../helpers/dom";
import EditPeer from "../../editPeer";
import { UsernameInputField } from "../../usernameInputField";
import { i18n, i18n_ } from "../../../lib/langPack";
import { attachClickEvent } from "../../../helpers/dom/clickEvent";
// TODO: аватарка не поменяется в этой вкладке после изменения почему-то (если поставить в другом клиенте, и потом тут проверить, для этого ещё вышел в чатлист)

2
src/components/sidebarLeft/tabs/generalSettings.ts

@ -14,9 +14,9 @@ import appStateManager from "../../../lib/appManagers/appStateManager"; @@ -14,9 +14,9 @@ import appStateManager from "../../../lib/appManagers/appStateManager";
import rootScope from "../../../lib/rootScope";
import { isApple } from "../../../helpers/userAgent";
import Row from "../../row";
import { attachClickEvent } from "../../../helpers/dom";
import AppBackgroundTab from "./background";
import { LangPackKey, _i18n } from "../../../lib/langPack";
import { attachClickEvent } from "../../../helpers/dom/clickEvent";
export class RangeSettingSelector {
public container: HTMLDivElement;

2
src/components/sidebarLeft/tabs/privacyAndSecurity.ts

@ -26,7 +26,7 @@ import appUsersManager from "../../../lib/appManagers/appUsersManager"; @@ -26,7 +26,7 @@ import appUsersManager from "../../../lib/appManagers/appUsersManager";
import rootScope from "../../../lib/rootScope";
import { convertKeyToInputKey } from "../../../helpers/string";
import { i18n, LangPackKey, _i18n } from "../../../lib/langPack";
import { replaceContent } from "../../../helpers/dom";
import replaceContent from "../../../helpers/dom/replaceContent";
export default class AppPrivacyAndSecurityTab extends SliderSuperTab {
private activeSessionsRow: Row;

3
src/components/sidebarRight/tabs/chatType.ts

@ -5,7 +5,6 @@ @@ -5,7 +5,6 @@
*/
import { copyTextToClipboard } from "../../../helpers/clipboard";
import { attachClickEvent, toggleDisability } from "../../../helpers/dom";
import { randomLong } from "../../../helpers/random";
import { Chat, ChatFull, ExportedChatInvite } from "../../../layer";
import appChatsManager from "../../../lib/appManagers/appChatsManager";
@ -21,6 +20,8 @@ import { SliderSuperTabEventable } from "../../sliderTab"; @@ -21,6 +20,8 @@ import { SliderSuperTabEventable } from "../../sliderTab";
import I18n from "../../../lib/langPack";
import PopupPeer from "../../popups/peer";
import ButtonCorner from "../../buttonCorner";
import { attachClickEvent } from "../../../helpers/dom/clickEvent";
import toggleDisability from "../../../helpers/dom/toggleDisability";
export default class AppChatTypeTab extends SliderSuperTabEventable {
public chatId: number;

3
src/components/sidebarRight/tabs/editChat.ts

@ -12,7 +12,6 @@ import Row from "../../row"; @@ -12,7 +12,6 @@ import Row from "../../row";
import Button from "../../button";
import appChatsManager, { ChatRights } from "../../../lib/appManagers/appChatsManager";
import appProfileManager from "../../../lib/appManagers/appProfileManager";
import { attachClickEvent, toggleDisability } from "../../../helpers/dom";
import { Chat } from "../../../layer";
import AppChatTypeTab from "./chatType";
import rootScope from "../../../lib/rootScope";
@ -21,6 +20,8 @@ import { i18n, LangPackKey } from "../../../lib/langPack"; @@ -21,6 +20,8 @@ import { i18n, LangPackKey } from "../../../lib/langPack";
import PopupDeleteDialog from "../../popups/deleteDialog";
import { addCancelButton } from "../../popups";
import PopupPeer from "../../popups/peer";
import { attachClickEvent } from "../../../helpers/dom/clickEvent";
import toggleDisability from "../../../helpers/dom/toggleDisability";
export default class AppEditChatTab extends SliderSuperTab {
private chatNameInputField: InputField;

3
src/components/sidebarRight/tabs/editContact.ts

@ -11,7 +11,6 @@ import { SettingSection } from "../../sidebarLeft"; @@ -11,7 +11,6 @@ import { SettingSection } from "../../sidebarLeft";
import Row from "../../row";
import CheckboxField from "../../checkboxField";
import Button from "../../button";
import { attachClickEvent, toggleDisability } from "../../../helpers/dom";
import appUsersManager from "../../../lib/appManagers/appUsersManager";
import appNotificationsManager from "../../../lib/appManagers/appNotificationsManager";
import PeerTitle from "../../peerTitle";
@ -21,6 +20,8 @@ import appPeersManager from "../../../lib/appManagers/appPeersManager"; @@ -21,6 +20,8 @@ import appPeersManager from "../../../lib/appManagers/appPeersManager";
import PopupPeer from "../../popups/peer";
import { addCancelButton } from "../../popups";
import { i18n } from "../../../lib/langPack";
import { attachClickEvent } from "../../../helpers/dom/clickEvent";
import toggleDisability from "../../../helpers/dom/toggleDisability";
export default class AppEditContactTab extends SliderSuperTab {
private nameInputField: InputField;

2
src/components/sidebarRight/tabs/gifs.ts

@ -11,11 +11,11 @@ import appSidebarRight from ".."; @@ -11,11 +11,11 @@ import appSidebarRight from "..";
import appUsersManager from "../../../lib/appManagers/appUsersManager";
import appInlineBotsManager, { AppInlineBotsManager } from "../../../lib/appManagers/appInlineBotsManager";
import GifsMasonry from "../../gifsMasonry";
import { attachClickEvent } from "../../../helpers/dom";
import appImManager from "../../../lib/appManagers/appImManager";
import type { MyDocument } from "../../../lib/appManagers/appDocsManager";
import mediaSizes from "../../../helpers/mediaSizes";
import findUpClassName from "../../../helpers/dom/findUpClassName";
import { attachClickEvent } from "../../../helpers/dom/clickEvent";
const ANIMATIONGROUP = 'GIFS-SEARCH';

3
src/components/sidebarRight/tabs/groupPermissions.ts

@ -4,8 +4,9 @@ @@ -4,8 +4,9 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { attachClickEvent, replaceContent } from "../../../helpers/dom";
import { attachClickEvent } from "../../../helpers/dom/clickEvent";
import findUpTag from "../../../helpers/dom/findUpTag";
import replaceContent from "../../../helpers/dom/replaceContent";
import ListenerSetter from "../../../helpers/listenerSetter";
import ScrollableLoader from "../../../helpers/listLoader";
import { ChannelParticipant, Chat, ChatBannedRights, Update } from "../../../layer";

4
src/components/sidebarRight/tabs/sharedMedia.ts

@ -15,7 +15,6 @@ import AppSearchSuper, { SearchSuperType } from "../../appSearchSuper."; @@ -15,7 +15,6 @@ import AppSearchSuper, { SearchSuperType } from "../../appSearchSuper.";
import AvatarElement, { openAvatarViewer } from "../../avatar";
import SidebarSlider, { SliderSuperTab } from "../../slider";
import CheckboxField from "../../checkboxField";
import { attachClickEvent, replaceContent, cancelEvent } from "../../../helpers/dom";
import appSidebarRight from "..";
import { TransitionSlider } from "../../transition";
import appNotificationsManager from "../../../lib/appManagers/appNotificationsManager";
@ -46,6 +45,9 @@ import { isTouchSupported } from "../../../helpers/touchSupport"; @@ -46,6 +45,9 @@ import { isTouchSupported } from "../../../helpers/touchSupport";
import { isFirefox } from "../../../helpers/userAgent";
import appDownloadManager from "../../../lib/appManagers/appDownloadManager";
import ButtonCorner from "../../buttonCorner";
import { cancelEvent } from "../../../helpers/dom/cancelEvent";
import { attachClickEvent } from "../../../helpers/dom/clickEvent";
import replaceContent from "../../../helpers/dom/replaceContent";
let setText = (text: string, row: Row) => {
//fastRaf(() => {

2
src/components/sidebarRight/tabs/stickers.ts

@ -7,7 +7,6 @@ @@ -7,7 +7,6 @@
import { SliderSuperTab } from "../../slider";
import InputSearch from "../../inputSearch";
import LazyLoadQueue from "../../lazyLoadQueue";
import { attachClickEvent } from "../../../helpers/dom";
import appImManager from "../../../lib/appManagers/appImManager";
import appStickersManager from "../../../lib/appManagers/appStickersManager";
import PopupStickers from "../../popups/stickers";
@ -19,6 +18,7 @@ import { StickerSet, StickerSetCovered } from "../../../layer"; @@ -19,6 +18,7 @@ import { StickerSet, StickerSetCovered } from "../../../layer";
import { forEachReverse } from "../../../helpers/array";
import { i18n } from "../../../lib/langPack";
import findUpClassName from "../../../helpers/dom/findUpClassName";
import { attachClickEvent } from "../../../helpers/dom/clickEvent";
export default class AppStickersTab extends SliderSuperTab {
private inputSearch: InputSearch;

6
src/components/sidebarRight/tabs/userPermissions.ts

@ -4,16 +4,14 @@ @@ -4,16 +4,14 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { attachClickEvent, toggleDisability } from "../../../helpers/dom";
import { attachClickEvent } from "../../../helpers/dom/clickEvent";
import toggleDisability from "../../../helpers/dom/toggleDisability";
import { deepEqual } from "../../../helpers/object";
import { ChannelParticipant } from "../../../layer";
import appChatsManager from "../../../lib/appManagers/appChatsManager";
import appDialogsManager from "../../../lib/appManagers/appDialogsManager";
import appPeersManager from "../../../lib/appManagers/appPeersManager";
import appUsersManager from "../../../lib/appManagers/appUsersManager";
import Button from "../../button";
import { addCancelButton } from "../../popups";
import PopupPeer from "../../popups/peer";
import { SettingSection } from "../../sidebarLeft";
import { SliderSuperTabEventable } from "../../sliderTab";
import { ChatPermissions } from "./groupPermissions";

2
src/components/slider.ts

@ -4,12 +4,12 @@ @@ -4,12 +4,12 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { attachClickEvent } from "../helpers/dom";
import { horizontalMenu } from "./horizontalMenu";
import { TransitionSlider } from "./transition";
import appNavigationController, { NavigationItem } from "./appNavigationController";
import SliderSuperTab, { SliderSuperTabConstructable, SliderTab } from "./sliderTab";
import { safeAssign } from "../helpers/object";
import { attachClickEvent } from "../helpers/dom/clickEvent";
const TRANSITION_TIME = 250;

4
src/components/sortedUserList.ts

@ -6,10 +6,12 @@ @@ -6,10 +6,12 @@
import type { LazyLoadQueueIntersector } from "./lazyLoadQueue";
import appDialogsManager, { DialogDom } from "../lib/appManagers/appDialogsManager";
import { isInDOM, positionElementByIndex, replaceContent } from "../helpers/dom";
import { getHeavyAnimationPromise } from "../hooks/useHeavyAnimationCheck";
import appUsersManager from "../lib/appManagers/appUsersManager";
import { insertInDescendSortedArray } from "../helpers/array";
import isInDOM from "../helpers/dom/isInDOM";
import positionElementByIndex from "../helpers/dom/positionElementByIndex";
import replaceContent from "../helpers/dom/replaceContent";
type SortedUser = {
peerId: number,

2
src/components/swipeHandler.ts

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { cancelEvent } from "../helpers/dom";
import { cancelEvent } from "../helpers/dom/cancelEvent";
import { safeAssign } from "../helpers/object";
import { isTouchSupported } from "../helpers/touchSupport";

2
src/components/transition.ts

@ -4,10 +4,10 @@ @@ -4,10 +4,10 @@
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { whichChild } from "../helpers/dom";
import rootScope from "../lib/rootScope";
import { CancellablePromise, deferredPromise } from "../helpers/cancellablePromise";
import { dispatchHeavyAnimationEvent } from "../hooks/useHeavyAnimationCheck";
import whichChild from "../helpers/dom/whichChild";
function slideNavigation(tabContent: HTMLElement, prevTabContent: HTMLElement, toRight: boolean) {
const width = prevTabContent.getBoundingClientRect().width;

4
src/components/wrappers.ts

@ -17,7 +17,6 @@ import appDocsManager, { MyDocument } from "../lib/appManagers/appDocsManager"; @@ -17,7 +17,6 @@ import appDocsManager, { MyDocument } from "../lib/appManagers/appDocsManager";
import appMessagesManager from '../lib/appManagers/appMessagesManager';
import appPhotosManager, { MyPhoto } from '../lib/appManagers/appPhotosManager';
import LottieLoader from '../lib/lottieLoader';
import { attachClickEvent, cancelEvent, isInDOM } from "../helpers/dom";
import webpWorkerController from '../lib/webp/webpWorkerController';
import animationIntersector from './animationIntersector';
import appMediaPlaybackController from './appMediaPlaybackController';
@ -40,6 +39,9 @@ import sequentialDom from '../helpers/sequentialDom'; @@ -40,6 +39,9 @@ import sequentialDom from '../helpers/sequentialDom';
import { fastRaf } from '../helpers/schedulers';
import appDownloadManager from '../lib/appManagers/appDownloadManager';
import appStickersManager from '../lib/appManagers/appStickersManager';
import { cancelEvent } from '../helpers/dom/cancelEvent';
import { attachClickEvent } from '../helpers/dom/clickEvent';
import isInDOM from '../helpers/dom/isInDOM';
const MAX_VIDEO_AUTOPLAY_SIZE = 50 * 1024 * 1024; // 50 MB

45
src/helpers/calcImageInBox.ts

@ -0,0 +1,45 @@ @@ -0,0 +1,45 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*
* Originally from:
* https://github.com/zhukov/webogram
* Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>
* https://github.com/zhukov/webogram/blob/master/LICENSE
*/
import { MOUNT_CLASS_TO } from "../config/debug";
export default function calcImageInBox(imageW: number, imageH: number, boxW: number, boxH: number, noZoom = true) {
if(imageW < boxW && imageH < boxH && noZoom) {
return {w: imageW, h: imageH};
}
let boxedImageW = boxW;
let boxedImageH = boxH;
if((imageW / imageH) > (boxW / boxH)) {
boxedImageH = (imageH * boxW / imageW) | 0;
} else {
boxedImageW = (imageW * boxH / imageH) | 0;
if(boxedImageW > boxW) {
boxedImageH = (boxedImageH * boxW / boxedImageW) | 0;
boxedImageW = boxW;
}
}
// if (Config.Navigator.retina) {
// imageW = Math.floor(imageW / 2)
// imageH = Math.floor(imageH / 2)
// }
if(noZoom && boxedImageW >= imageW && boxedImageH >= imageH) {
boxedImageW = imageW;
boxedImageH = imageH;
}
return {w: boxedImageW, h: boxedImageH};
}
MOUNT_CLASS_TO.calcImageInBox = calcImageInBox;

591
src/helpers/dom.ts

@ -9,30 +9,6 @@ @@ -9,30 +9,6 @@
* https://github.com/zhukov/webogram/blob/master/LICENSE
*/
import { MessageEntity } from "../layer";
import RichTextProcessor from "../lib/richtextprocessor";
import ListenerSetter from "./listenerSetter";
import { isTouchSupported } from "./touchSupport";
import { isApple, isMobile, isMobileSafari } from "./userAgent";
import rootScope from "../lib/rootScope";
import { MOUNT_CLASS_TO } from "../config/debug";
import { doubleRaf } from "./schedulers";
/* export function isInDOM(element: Element, parentNode?: HTMLElement): boolean {
if(!element) {
return false;
}
parentNode = parentNode || document.body;
if(element === parentNode) {
return true;
}
return isInDOM(element.parentNode as HTMLElement, parentNode);
} */
export function isInDOM(element: Element): boolean {
return element?.isConnected;
}
/* export function checkDragEvent(e: any) {
if(!e || e.target && (e.target.tagName === 'IMG' || e.target.tagName === 'A')) return false
if(e.dataTransfer && e.dataTransfer.types) {
@ -48,46 +24,6 @@ export function isInDOM(element: Element): boolean { @@ -48,46 +24,6 @@ export function isInDOM(element: Element): boolean {
return false;
} */
export function cancelEvent(event: Event) {
event = event || window.event;
if(event) {
// @ts-ignore
event = event.originalEvent || event;
try {
if(event.stopPropagation) event.stopPropagation();
if(event.preventDefault) event.preventDefault();
event.returnValue = false;
event.cancelBubble = true;
} catch(err) {}
}
return false;
}
export function placeCaretAtEnd(el: HTMLElement) {
if(isTouchSupported) {
return;
}
el.focus();
if(typeof window.getSelection !== "undefined" && typeof document.createRange !== "undefined") {
var range = document.createRange();
range.selectNodeContents(el);
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
// @ts-ignore
} else if(typeof document.body.createTextRange !== "undefined") {
// @ts-ignore
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.collapse(false);
textRange.select();
}
}
/* export function getFieldSelection(field: any) {
if(field.selectionStart) {
return field.selectionStart;
@ -120,154 +56,6 @@ export function placeCaretAtEnd(el: HTMLElement) { @@ -120,154 +56,6 @@ export function placeCaretAtEnd(el: HTMLElement) {
return len;
} */
export function getRichValue(field: HTMLElement, entities?: MessageEntity[]) {
if(!field) {
return '';
}
const lines: string[] = [];
const line: string[] = [];
getRichElementValue(field, lines, line, undefined, undefined, entities);
if(line.length) {
lines.push(line.join(''));
}
let value = lines.join('\n');
value = value.replace(/\u00A0/g, ' ');
if(entities) {
RichTextProcessor.combineSameEntities(entities);
}
//console.log('getRichValue:', value, entities);
return value;
}
MOUNT_CLASS_TO.getRichValue = getRichValue;
export type MarkdownType = 'bold' | 'italic' | 'underline' | 'strikethrough' | 'monospace' | 'link';
export type MarkdownTag = {
match: string,
entityName: 'messageEntityBold' | 'messageEntityUnderline' | 'messageEntityItalic' | 'messageEntityPre' | 'messageEntityStrike' | 'messageEntityTextUrl';
};
export const markdownTags: {[type in MarkdownType]: MarkdownTag} = {
bold: {
match: '[style*="font-weight"], b',
entityName: 'messageEntityBold'
},
underline: {
match: '[style*="underline"], u',
entityName: 'messageEntityUnderline'
},
italic: {
match: '[style*="italic"], i',
entityName: 'messageEntityItalic'
},
monospace: {
match: '[style*="monospace"], [face="monospace"]',
entityName: 'messageEntityPre'
},
strikethrough: {
match: '[style*="line-through"], strike',
entityName: 'messageEntityStrike'
},
link: {
match: 'A',
entityName: 'messageEntityTextUrl'
}
};
export function getRichElementValue(node: HTMLElement, lines: string[], line: string[], selNode?: Node, selOffset?: number, entities?: MessageEntity[], offset = {offset: 0}) {
if(node.nodeType === 3) { // TEXT
if(selNode === node) {
const value = node.nodeValue;
line.push(value.substr(0, selOffset) + '\x01' + value.substr(selOffset));
} else {
const nodeValue = node.nodeValue;
line.push(nodeValue);
if(entities && nodeValue.trim()) {
if(node.parentNode) {
const parentElement = node.parentElement;
for(const type in markdownTags) {
const tag = markdownTags[type as MarkdownType];
const closest = parentElement.closest(tag.match + ', [contenteditable]');
if(closest && closest.getAttribute('contenteditable') === null) {
if(tag.entityName === 'messageEntityTextUrl') {
entities.push({
_: tag.entityName as any,
url: (parentElement as HTMLAnchorElement).href,
offset: offset.offset,
length: nodeValue.length
});
} else {
entities.push({
_: tag.entityName as any,
offset: offset.offset,
length: nodeValue.length
});
}
}
}
}
}
offset.offset += nodeValue.length;
}
return;
}
if(node.nodeType !== 1) { // NON-ELEMENT
return;
}
const isSelected = (selNode === node);
const isBlock = node.tagName === 'DIV' || node.tagName === 'P';
if(isBlock && line.length || node.tagName === 'BR') {
lines.push(line.join(''));
line.splice(0, line.length);
} else if(node.tagName === 'IMG') {
const alt = (node as HTMLImageElement).alt;
if(alt) {
line.push(alt);
offset.offset += alt.length;
}
}
if(isSelected && !selOffset) {
line.push('\x01');
}
let curChild = node.firstChild as HTMLElement;
while(curChild) {
getRichElementValue(curChild, lines, line, selNode, selOffset, entities, offset);
curChild = curChild.nextSibling as any;
}
if(isSelected && selOffset) {
line.push('\x01');
}
if(isBlock && line.length) {
lines.push(line.join(''));
line.splice(0, line.length);
}
}
export function isInputEmpty(element: HTMLElement) {
if(element.hasAttribute('contenteditable') || element.tagName !== 'INPUT') {
/* const value = element.innerText;
return !value.trim() && !serializeNodes(Array.from(element.childNodes)).trim(); */
return !getRichValue(element).trim();
} else {
return !(element as HTMLInputElement).value.trim();
}
}
/* export function serializeNodes(nodes: Node[]): string {
return nodes.reduce((str, child: any) => {
//console.log('childNode', str, child, typeof(child), typeof(child) === 'string', child.innerText);
@ -293,242 +81,6 @@ export function isInputEmpty(element: HTMLElement) { @@ -293,242 +81,6 @@ export function isInputEmpty(element: HTMLElement) {
}
} */
// generate a path's arc data parameter
// http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands
var arcParameter = function(rx: number, ry: number, xAxisRotation: number, largeArcFlag: number, sweepFlag: number, x: number, y: number) {
return [rx, ',', ry, ' ',
xAxisRotation, ' ',
largeArcFlag, ',',
sweepFlag, ' ',
x, ',', y ].join('');
};
export function generatePathData(x: number, y: number, width: number, height: number, tl: number, tr: number, br: number, bl: number) {
const data: string[] = [];
// start point in top-middle of the rectangle
data.push('M' + (x + width / 2) + ',' + y);
// next we go to the right
data.push('H' + (x + width - tr));
if(tr > 0) {
// now we draw the arc in the top-right corner
data.push('A' + arcParameter(tr, tr, 0, 0, 1, (x + width), (y + tr)));
}
// next we go down
data.push('V' + (y + height - br));
if(br > 0) {
// now we draw the arc in the lower-right corner
data.push('A' + arcParameter(br, br, 0, 0, 1, (x + width - br), (y + height)));
}
// now we go to the left
data.push('H' + (x + bl));
if(bl > 0) {
// now we draw the arc in the lower-left corner
data.push('A' + arcParameter(bl, bl, 0, 0, 1, (x + 0), (y + height - bl)));
}
// next we go up
data.push('V' + (y + tl));
if(tl > 0) {
// now we draw the arc in the top-left corner
data.push('A' + arcParameter(tl, tl, 0, 0, 1, (x + tl), (y + 0)));
}
// and we close the path
data.push('Z');
return data.join(' ');
};
MOUNT_CLASS_TO.generatePathData = generatePathData;
export function whichChild(elem: Node) {
if(!elem.parentNode) {
return -1;
}
let i = 0;
// @ts-ignore
while((elem = elem.previousElementSibling) !== null) ++i;
return i;
};
export function fillPropertyValue(str: string) {
let splitted = str.split(' ');
if(splitted.length !== 4) {
if(!splitted[0]) splitted[0] = '0px';
for(let i = splitted.length; i < 4; ++i) {
splitted[i] = splitted[i % 2] || splitted[0] || '0px';
}
}
return splitted;
}
export function calcImageInBox(imageW: number, imageH: number, boxW: number, boxH: number, noZoom = true) {
if(imageW < boxW && imageH < boxH && noZoom) {
return {w: imageW, h: imageH};
}
let boxedImageW = boxW;
let boxedImageH = boxH;
if((imageW / imageH) > (boxW / boxH)) {
boxedImageH = (imageH * boxW / imageW) | 0;
} else {
boxedImageW = (imageW * boxH / imageH) | 0;
if(boxedImageW > boxW) {
boxedImageH = (boxedImageH * boxW / boxedImageW) | 0;
boxedImageW = boxW;
}
}
// if (Config.Navigator.retina) {
// imageW = Math.floor(imageW / 2)
// imageH = Math.floor(imageH / 2)
// }
if(noZoom && boxedImageW >= imageW && boxedImageH >= imageH) {
boxedImageW = imageW;
boxedImageH = imageH;
}
return {w: boxedImageW, h: boxedImageH};
}
MOUNT_CLASS_TO.calcImageInBox = calcImageInBox;
export function positionElementByIndex(element: HTMLElement, container: HTMLElement, pos: number, prevPos?: number) {
if(prevPos === undefined) {
prevPos = element.parentElement === container ? whichChild(element) : -1;
}
if(prevPos === pos) {
return false;
} else if(prevPos !== -1 && prevPos < pos) { // was higher
pos += 1;
}
if(container.childElementCount > pos) {
container.insertBefore(element, container.children[pos]);
} else {
container.append(element);
}
return true;
}
export function cancelSelection() {
if(window.getSelection) {
if(window.getSelection().empty) { // Chrome
window.getSelection().empty();
} else if(window.getSelection().removeAllRanges) { // Firefox
window.getSelection().removeAllRanges();
}
// @ts-ignore
} else if(document.selection) { // IE?
// @ts-ignore
document.selection.empty();
}
}
//(window as any).splitStringByLength = splitStringByLength;
export function getSelectedText(): string {
if(window.getSelection) {
return window.getSelection().toString();
// @ts-ignore
} else if(document.selection) {
// @ts-ignore
return document.selection.createRange().text;
}
return '';
}
export function blurActiveElement() {
if(document.activeElement && (document.activeElement as HTMLInputElement).blur) {
(document.activeElement as HTMLInputElement).blur();
return true;
}
return false;
}
export const CLICK_EVENT_NAME: 'mousedown' | 'touchend' | 'click' = (isTouchSupported ? 'mousedown' : 'click') as any;
export type AttachClickOptions = AddEventListenerOptions & Partial<{listenerSetter: ListenerSetter, touchMouseDown: true}>;
export const attachClickEvent = (elem: HTMLElement, callback: (e: TouchEvent | MouseEvent) => void, options: AttachClickOptions = {}) => {
const add = options.listenerSetter ? options.listenerSetter.add.bind(options.listenerSetter, elem) : elem.addEventListener.bind(elem);
const remove = options.listenerSetter ? options.listenerSetter.removeManual.bind(options.listenerSetter, elem) : elem.removeEventListener.bind(elem);
options.touchMouseDown = true;
/* if(options.touchMouseDown && CLICK_EVENT_NAME === 'touchend') {
add('mousedown', callback, options);
} else if(CLICK_EVENT_NAME === 'touchend') {
const o = {...options, once: true};
const onTouchStart = (e: TouchEvent) => {
const onTouchMove = (e: TouchEvent) => {
remove('touchmove', onTouchMove, o);
remove('touchend', onTouchEnd, o);
};
const onTouchEnd = (e: TouchEvent) => {
remove('touchmove', onTouchMove, o);
callback(e);
if(options.once) {
remove('touchstart', onTouchStart);
}
};
add('touchend', onTouchEnd, o);
add('touchmove', onTouchMove, o);
};
add('touchstart', onTouchStart);
} else {
add(CLICK_EVENT_NAME, callback, options);
} */
add(CLICK_EVENT_NAME, callback, options);
};
export const detachClickEvent = (elem: HTMLElement, callback: (e: TouchEvent | MouseEvent) => void, options?: AddEventListenerOptions) => {
if(CLICK_EVENT_NAME === 'touchend') {
elem.removeEventListener('touchstart', callback, options);
} else {
elem.removeEventListener(CLICK_EVENT_NAME, callback, options);
}
};
export const getSelectedNodes = () => {
const nodes: Node[] = [];
const selection = window.getSelection();
for(let i = 0; i < selection.rangeCount; ++i) {
const range = selection.getRangeAt(i);
let {startContainer, endContainer} = range;
if(endContainer.nodeType !== 3) endContainer = endContainer.firstChild;
while(startContainer && startContainer !== endContainer) {
nodes.push(startContainer.nodeType === 3 ? startContainer : startContainer.firstChild);
startContainer = startContainer.nextSibling;
}
if(nodes[nodes.length - 1] !== endContainer) {
nodes.push(endContainer);
}
}
// * filter null's due to <br>
return nodes.filter(node => !!node);
};
/* export const isSelectionSingle = (input: Element = document.activeElement) => {
const nodes = getSelectedNodes();
const parents = [...new Set(nodes.map(node => node.parentNode))];
@ -547,46 +99,6 @@ export const getSelectedNodes = () => { @@ -547,46 +99,6 @@ export const getSelectedNodes = () => {
return single;
}; */
export const handleScrollSideEvent = (elem: HTMLElement, side: 'top' | 'bottom', callback: () => void, listenerSetter: ListenerSetter) => {
if(isTouchSupported) {
let lastY: number;
const options = {passive: true};
listenerSetter.add(elem, 'touchstart', (e) => {
if(e.touches.length > 1) {
onTouchEnd();
return;
}
lastY = e.touches[0].clientY;
listenerSetter.add(elem, 'touchmove', onTouchMove, options);
listenerSetter.add(elem, 'touchend', onTouchEnd, options);
}, options);
const onTouchMove = (e: TouchEvent) => {
const clientY = e.touches[0].clientY;
const isDown = clientY < lastY;
if(side === 'bottom' && isDown) callback();
else if(side === 'top' && !isDown) callback();
lastY = clientY;
//alert('isDown: ' + !!isDown);
};
const onTouchEnd = () => {
listenerSetter.removeManual(elem, 'touchmove', onTouchMove, options);
listenerSetter.removeManual(elem, 'touchend', onTouchEnd, options);
};
} else {
listenerSetter.add(elem, 'wheel', (e) => {
const isDown = e.deltaY > 0;
//this.log('wheel', e, isDown);
if(side === 'bottom' && isDown) callback();
else if(side === 'top' && !isDown) callback();
}, {passive: true});
}
};
/* export function radiosHandleChange(inputs: HTMLInputElement[], onChange: (value: string) => void) {
inputs.forEach(input => {
input.addEventListener('change', () => {
@ -597,105 +109,4 @@ export const handleScrollSideEvent = (elem: HTMLElement, side: 'top' | 'bottom', @@ -597,105 +109,4 @@ export const handleScrollSideEvent = (elem: HTMLElement, side: 'top' | 'bottom',
});
} */
export function isSendShortcutPressed(e: KeyboardEvent) {
if(e.key === 'Enter' && !isMobile && !e.isComposing) {
/* if(e.ctrlKey || e.metaKey) {
this.messageInput.innerHTML += '<br>';
placeCaretAtEnd(this.message)
return;
} */
if(rootScope.settings.sendShortcut === 'enter') {
if(e.shiftKey || e.ctrlKey || e.metaKey) {
return;
}
return true;
} else {
const secondaryKey = isApple ? e.metaKey : e.ctrlKey;
if(e.shiftKey || (isApple ? e.ctrlKey : e.metaKey)) {
return;
}
if(secondaryKey) {
return true;
}
}
}
return false;
}
export function reflowScrollableElement(element: HTMLElement) {
element.style.display = 'none';
void element.offsetLeft; // reflow
element.style.display = '';
}
export function isSelectionEmpty(selection = window.getSelection()) {
if(!selection || !selection.rangeCount) {
return true;
}
const selectionRange = selection.getRangeAt(0);
if(!selectionRange.toString() || !selectionRange.START_TO_END) {
return true;
}
return false;
}
export function disableTransition(elements: HTMLElement[]) {
elements.forEach(el => el.classList.add('no-transition'));
doubleRaf().then(() => {
elements.forEach(el => el.classList.remove('no-transition'));
});
}
export function toggleDisability(elements: HTMLElement[], disable: boolean) {
if(disable) {
elements.forEach(el => el.setAttribute('disabled', 'true'));
} else {
elements.forEach(el => el.removeAttribute('disabled'));
}
return () => toggleDisability(elements, !disable);
}
export function canFocus(isFirstInput: boolean) {
return !isMobileSafari || !isFirstInput;
}
export function htmlToDocumentFragment(html: string) {
var template = document.createElement('template');
html = html.trim(); // Never return a text node of whitespace as the result
template.innerHTML = html;
return template.content;
}
export function htmlToSpan(html: string) {
const span = document.createElement('span');
span.innerHTML = html;
return span;
}
export function replaceContent(elem: HTMLElement, node: string | Node) {
// * children.length doesn't count text nodes
const firstChild = elem.firstChild;
if(firstChild) {
if(elem.lastChild === firstChild) {
firstChild.replaceWith(node);
} else {
elem.textContent = '';
elem.append(node);
}
} else {
elem.append(node);
}
}
export function setInnerHTML(elem: HTMLElement, html: string) {
elem.setAttribute('dir', 'auto');
elem.innerHTML = html;
}
export default {};

14
src/helpers/dom/blurActiveElement.ts

@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
export default function blurActiveElement() {
if(document.activeElement && (document.activeElement as HTMLInputElement).blur) {
(document.activeElement as HTMLInputElement).blur();
return true;
}
return false;
}

11
src/helpers/dom/canFocus.ts

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { isMobileSafari } from "../userAgent";
export function canFocus(isFirstInput: boolean) {
return !isMobileSafari || !isFirstInput;
}

27
src/helpers/dom/cancelEvent.ts

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*
* Originally from:
* https://github.com/zhukov/webogram
* Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>
* https://github.com/zhukov/webogram/blob/master/LICENSE
*/
export function cancelEvent(event: Event) {
event = event || window.event;
if(event) {
// @ts-ignore
event = event.originalEvent || event;
try {
if(event.stopPropagation) event.stopPropagation();
if(event.preventDefault) event.preventDefault();
event.returnValue = false;
event.cancelBubble = true;
} catch(err) {}
}
return false;
}

19
src/helpers/dom/cancelSelection.ts

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
export default function cancelSelection() {
if(window.getSelection) {
if(window.getSelection().empty) { // Chrome
window.getSelection().empty();
} else if(window.getSelection().removeAllRanges) { // Firefox
window.getSelection().removeAllRanges();
}
// @ts-ignore
} else if(document.selection) { // IE?
// @ts-ignore
document.selection.empty();
}
}

53
src/helpers/dom/clickEvent.ts

@ -0,0 +1,53 @@ @@ -0,0 +1,53 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import type ListenerSetter from "../listenerSetter";
import { isTouchSupported } from "../touchSupport";
export const CLICK_EVENT_NAME: 'mousedown' | 'touchend' | 'click' = (isTouchSupported ? 'mousedown' : 'click') as any;
export type AttachClickOptions = AddEventListenerOptions & Partial<{listenerSetter: ListenerSetter, touchMouseDown: true}>;
export function attachClickEvent(elem: HTMLElement, callback: (e: TouchEvent | MouseEvent) => void, options: AttachClickOptions = {}) {
const add = options.listenerSetter ? options.listenerSetter.add.bind(options.listenerSetter, elem) : elem.addEventListener.bind(elem);
const remove = options.listenerSetter ? options.listenerSetter.removeManual.bind(options.listenerSetter, elem) : elem.removeEventListener.bind(elem);
options.touchMouseDown = true;
/* if(options.touchMouseDown && CLICK_EVENT_NAME === 'touchend') {
add('mousedown', callback, options);
} else if(CLICK_EVENT_NAME === 'touchend') {
const o = {...options, once: true};
const onTouchStart = (e: TouchEvent) => {
const onTouchMove = (e: TouchEvent) => {
remove('touchmove', onTouchMove, o);
remove('touchend', onTouchEnd, o);
};
const onTouchEnd = (e: TouchEvent) => {
remove('touchmove', onTouchMove, o);
callback(e);
if(options.once) {
remove('touchstart', onTouchStart);
}
};
add('touchend', onTouchEnd, o);
add('touchmove', onTouchMove, o);
};
add('touchstart', onTouchStart);
} else {
add(CLICK_EVENT_NAME, callback, options);
} */
add(CLICK_EVENT_NAME, callback, options);
}
export function detachClickEvent(elem: HTMLElement, callback: (e: TouchEvent | MouseEvent) => void, options?: AddEventListenerOptions) {
if(CLICK_EVENT_NAME === 'touchend') {
elem.removeEventListener('touchstart', callback, options);
} else {
elem.removeEventListener(CLICK_EVENT_NAME, callback, options);
}
}

15
src/helpers/dom/disableTransition.ts

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { doubleRaf } from "../schedulers";
export default function disableTransition(elements: HTMLElement[]) {
elements.forEach(el => el.classList.add('no-transition'));
doubleRaf().then(() => {
elements.forEach(el => el.classList.remove('no-transition'));
});
}

152
src/helpers/dom/getRichValue.ts

@ -0,0 +1,152 @@ @@ -0,0 +1,152 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*
* Originally from:
* https://github.com/zhukov/webogram
* Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>
* https://github.com/zhukov/webogram/blob/master/LICENSE
*/
import { MOUNT_CLASS_TO } from "../../config/debug";
import { MessageEntity } from "../../layer";
import RichTextProcessor from "../../lib/richtextprocessor";
export default function getRichValue(field: HTMLElement, entities?: MessageEntity[]) {
if(!field) {
return '';
}
const lines: string[] = [];
const line: string[] = [];
getRichElementValue(field, lines, line, undefined, undefined, entities);
if(line.length) {
lines.push(line.join(''));
}
let value = lines.join('\n');
value = value.replace(/\u00A0/g, ' ');
if(entities) {
RichTextProcessor.combineSameEntities(entities);
}
//console.log('getRichValue:', value, entities);
return value;
}
MOUNT_CLASS_TO.getRichValue = getRichValue;
export type MarkdownType = 'bold' | 'italic' | 'underline' | 'strikethrough' | 'monospace' | 'link';
export type MarkdownTag = {
match: string,
entityName: 'messageEntityBold' | 'messageEntityUnderline' | 'messageEntityItalic' | 'messageEntityPre' | 'messageEntityStrike' | 'messageEntityTextUrl';
};
export const markdownTags: {[type in MarkdownType]: MarkdownTag} = {
bold: {
match: '[style*="font-weight"], b',
entityName: 'messageEntityBold'
},
underline: {
match: '[style*="underline"], u',
entityName: 'messageEntityUnderline'
},
italic: {
match: '[style*="italic"], i',
entityName: 'messageEntityItalic'
},
monospace: {
match: '[style*="monospace"], [face="monospace"]',
entityName: 'messageEntityPre'
},
strikethrough: {
match: '[style*="line-through"], strike',
entityName: 'messageEntityStrike'
},
link: {
match: 'A',
entityName: 'messageEntityTextUrl'
}
};
function getRichElementValue(node: HTMLElement, lines: string[], line: string[], selNode?: Node, selOffset?: number, entities?: MessageEntity[], offset = {offset: 0}) {
if(node.nodeType === 3) { // TEXT
if(selNode === node) {
const value = node.nodeValue;
line.push(value.substr(0, selOffset) + '\x01' + value.substr(selOffset));
} else {
const nodeValue = node.nodeValue;
line.push(nodeValue);
if(entities && nodeValue.trim()) {
if(node.parentNode) {
const parentElement = node.parentElement;
for(const type in markdownTags) {
const tag = markdownTags[type as MarkdownType];
const closest = parentElement.closest(tag.match + ', [contenteditable]');
if(closest && closest.getAttribute('contenteditable') === null) {
if(tag.entityName === 'messageEntityTextUrl') {
entities.push({
_: tag.entityName as any,
url: (parentElement as HTMLAnchorElement).href,
offset: offset.offset,
length: nodeValue.length
});
} else {
entities.push({
_: tag.entityName as any,
offset: offset.offset,
length: nodeValue.length
});
}
}
}
}
}
offset.offset += nodeValue.length;
}
return;
}
if(node.nodeType !== 1) { // NON-ELEMENT
return;
}
const isSelected = (selNode === node);
const isBlock = node.tagName === 'DIV' || node.tagName === 'P';
if(isBlock && line.length || node.tagName === 'BR') {
lines.push(line.join(''));
line.splice(0, line.length);
} else if(node.tagName === 'IMG') {
const alt = (node as HTMLImageElement).alt;
if(alt) {
line.push(alt);
offset.offset += alt.length;
}
}
if(isSelected && !selOffset) {
line.push('\x01');
}
let curChild = node.firstChild as HTMLElement;
while(curChild) {
getRichElementValue(curChild, lines, line, selNode, selOffset, entities, offset);
curChild = curChild.nextSibling as any;
}
if(isSelected && selOffset) {
line.push('\x01');
}
if(isBlock && line.length) {
lines.push(line.join(''));
line.splice(0, line.length);
}
}

27
src/helpers/dom/getSelectedNodes.ts

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
export default function getSelectedNodes() {
const nodes: Node[] = [];
const selection = window.getSelection();
for(let i = 0; i < selection.rangeCount; ++i) {
const range = selection.getRangeAt(i);
let {startContainer, endContainer} = range;
if(endContainer.nodeType !== 3) endContainer = endContainer.firstChild;
while(startContainer && startContainer !== endContainer) {
nodes.push(startContainer.nodeType === 3 ? startContainer : startContainer.firstChild);
startContainer = startContainer.nextSibling;
}
if(nodes[nodes.length - 1] !== endContainer) {
nodes.push(endContainer);
}
}
// * filter null's due to <br>
return nodes.filter(node => !!node);
}

17
src/helpers/dom/getSelectedText.ts

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
export default function getSelectedText(): string {
if(window.getSelection) {
return window.getSelection().toString();
// @ts-ignore
} else if(document.selection) {
// @ts-ignore
return document.selection.createRange().text;
}
return '';
}

48
src/helpers/dom/handleScrollSideEvent.ts

@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import type ListenerSetter from "../listenerSetter";
import { isTouchSupported } from "../touchSupport";
export default function handleScrollSideEvent(elem: HTMLElement, side: 'top' | 'bottom', callback: () => void, listenerSetter: ListenerSetter) {
if(isTouchSupported) {
let lastY: number;
const options = {passive: true};
listenerSetter.add(elem, 'touchstart', (e) => {
if(e.touches.length > 1) {
onTouchEnd();
return;
}
lastY = e.touches[0].clientY;
listenerSetter.add(elem, 'touchmove', onTouchMove, options);
listenerSetter.add(elem, 'touchend', onTouchEnd, options);
}, options);
const onTouchMove = (e: TouchEvent) => {
const clientY = e.touches[0].clientY;
const isDown = clientY < lastY;
if(side === 'bottom' && isDown) callback();
else if(side === 'top' && !isDown) callback();
lastY = clientY;
//alert('isDown: ' + !!isDown);
};
const onTouchEnd = () => {
listenerSetter.removeManual(elem, 'touchmove', onTouchMove, options);
listenerSetter.removeManual(elem, 'touchend', onTouchEnd, options);
};
} else {
listenerSetter.add(elem, 'wheel', (e) => {
const isDown = e.deltaY > 0;
//this.log('wheel', e, isDown);
if(side === 'bottom' && isDown) callback();
else if(side === 'top' && !isDown) callback();
}, {passive: true});
}
}

12
src/helpers/dom/htmlToDocumentFragment.ts

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
export default function htmlToDocumentFragment(html: string) {
var template = document.createElement('template');
html = html.trim(); // Never return a text node of whitespace as the result
template.innerHTML = html;
return template.content;
}

11
src/helpers/dom/htmlToSpan.ts

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
export default function htmlToSpan(html: string) {
const span = document.createElement('span');
span.innerHTML = html;
return span;
}

25
src/helpers/dom/isInDOM.ts

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*
* Originally from:
* https://github.com/zhukov/webogram
* Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>
* https://github.com/zhukov/webogram/blob/master/LICENSE
*/
/* export function isInDOM(element: Element, parentNode?: HTMLElement): boolean {
if(!element) {
return false;
}
parentNode = parentNode || document.body;
if(element === parentNode) {
return true;
}
return isInDOM(element.parentNode as HTMLElement, parentNode);
} */
export default function isInDOM(element: Element): boolean {
return element?.isConnected;
}

18
src/helpers/dom/isInputEmpty.ts

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import getRichValue from "./getRichValue";
export default function isInputEmpty(element: HTMLElement) {
if(element.hasAttribute('contenteditable') || element.tagName !== 'INPUT') {
/* const value = element.innerText;
return !value.trim() && !serializeNodes(Array.from(element.childNodes)).trim(); */
return !getRichValue(element).trim();
} else {
return !(element as HTMLInputElement).value.trim();
}
}

18
src/helpers/dom/isSelectionEmpty.ts

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
export default function isSelectionEmpty(selection = window.getSelection()) {
if(!selection || !selection.rangeCount) {
return true;
}
const selectionRange = selection.getRangeAt(0);
if(!selectionRange.toString() || !selectionRange.START_TO_END) {
return true;
}
return false;
}

37
src/helpers/dom/isSendShortcutPressed.ts

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import rootScope from "../../lib/rootScope";
import { isMobile, isApple } from "../userAgent";
export default function isSendShortcutPressed(e: KeyboardEvent) {
if(e.key === 'Enter' && !isMobile && !e.isComposing) {
/* if(e.ctrlKey || e.metaKey) {
this.messageInput.innerHTML += '<br>';
placeCaretAtEnd(this.message)
return;
} */
if(rootScope.settings.sendShortcut === 'enter') {
if(e.shiftKey || e.ctrlKey || e.metaKey) {
return;
}
return true;
} else {
const secondaryKey = isApple ? e.metaKey : e.ctrlKey;
if(e.shiftKey || (isApple ? e.ctrlKey : e.metaKey)) {
return;
}
if(secondaryKey) {
return true;
}
}
}
return false;
}

35
src/helpers/dom/placeCaretAtEnd.ts

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*
* Originally from:
* https://github.com/zhukov/webogram
* Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>
* https://github.com/zhukov/webogram/blob/master/LICENSE
*/
import { isTouchSupported } from "../touchSupport";
export default function placeCaretAtEnd(el: HTMLElement) {
if(isTouchSupported) {
return;
}
el.focus();
if(typeof window.getSelection !== "undefined" && typeof document.createRange !== "undefined") {
var range = document.createRange();
range.selectNodeContents(el);
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
// @ts-ignore
} else if(typeof document.body.createTextRange !== "undefined") {
// @ts-ignore
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.collapse(false);
textRange.select();
}
}

27
src/helpers/dom/positionElementByIndex.ts

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import whichChild from "./whichChild";
export default function positionElementByIndex(element: HTMLElement, container: HTMLElement, pos: number, prevPos?: number) {
if(prevPos === undefined) {
prevPos = element.parentElement === container ? whichChild(element) : -1;
}
if(prevPos === pos) {
return false;
} else if(prevPos !== -1 && prevPos < pos) { // was higher
pos += 1;
}
if(container.childElementCount > pos) {
container.insertBefore(element, container.children[pos]);
} else {
container.append(element);
}
return true;
}

11
src/helpers/dom/reflowScrollableElement.ts

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
export default function reflowScrollableElement(element: HTMLElement) {
element.style.display = 'none';
void element.offsetLeft; // reflow
element.style.display = '';
}

20
src/helpers/dom/replaceContent.ts

@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
export default function replaceContent(elem: HTMLElement, node: string | Node) {
// * children.length doesn't count text nodes
const firstChild = elem.firstChild;
if(firstChild) {
if(elem.lastChild === firstChild) {
firstChild.replaceWith(node);
} else {
elem.textContent = '';
elem.append(node);
}
} else {
elem.append(node);
}
}

10
src/helpers/dom/setInnerHTML.ts

@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
export default function setInnerHTML(elem: HTMLElement, html: string) {
elem.setAttribute('dir', 'auto');
elem.innerHTML = html;
}

15
src/helpers/dom/toggleDisability.ts

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
export default function toggleDisability(elements: HTMLElement[], disable: boolean) {
if(disable) {
elements.forEach(el => el.setAttribute('disabled', 'true'));
} else {
elements.forEach(el => el.removeAttribute('disabled'));
}
return () => toggleDisability(elements, !disable);
}

16
src/helpers/dom/whichChild.ts

@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
export default function whichChild(elem: Node) {
if(!elem.parentNode) {
return -1;
}
let i = 0;
// @ts-ignore
while((elem = elem.previousElementSibling) !== null) ++i;
return i;
}

2
src/helpers/fastSmoothScroll.ts

@ -10,7 +10,7 @@ import { dispatchHeavyAnimationEvent } from '../hooks/useHeavyAnimationCheck'; @@ -10,7 +10,7 @@ import { dispatchHeavyAnimationEvent } from '../hooks/useHeavyAnimationCheck';
import { fastRaf } from './schedulers';
import { animateSingle, cancelAnimationByKey } from './animation';
import rootScope from '../lib/rootScope';
import { isInDOM } from './dom';
import isInDOM from './dom/isInDOM';
const MAX_DISTANCE = 1500;
const MIN_JS_DURATION = 250;

17
src/helpers/fillPropertyValue.ts

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
export default function fillPropertyValue(str: string) {
let splitted = str.split(' ');
if(splitted.length !== 4) {
if(!splitted[0]) splitted[0] = '0px';
for(let i = splitted.length; i < 4; ++i) {
splitted[i] = splitted[i % 2] || splitted[0] || '0px';
}
}
return splitted;
}

64
src/helpers/generatePathData.ts

@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@
/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
// generate a path's arc data parameter
import { MOUNT_CLASS_TO } from "../config/debug";
// http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands
function arcParameter(rx: number, ry: number, xAxisRotation: number, largeArcFlag: number, sweepFlag: number, x: number, y: number) {
return [rx, ',', ry, ' ',
xAxisRotation, ' ',
largeArcFlag, ',',
sweepFlag, ' ',
x, ',', y ].join('');
}
export default function generatePathData(x: number, y: number, width: number, height: number, tl: number, tr: number, br: number, bl: number) {
const data: string[] = [];
// start point in top-middle of the rectangle
data.push('M' + (x + width / 2) + ',' + y);
// next we go to the right
data.push('H' + (x + width - tr));
if(tr > 0) {
// now we draw the arc in the top-right corner
data.push('A' + arcParameter(tr, tr, 0, 0, 1, (x + width), (y + tr)));
}
// next we go down
data.push('V' + (y + height - br));
if(br > 0) {
// now we draw the arc in the lower-right corner
data.push('A' + arcParameter(br, br, 0, 0, 1, (x + width - br), (y + height)));
}
// now we go to the left
data.push('H' + (x + bl));
if(bl > 0) {
// now we draw the arc in the lower-left corner
data.push('A' + arcParameter(bl, bl, 0, 0, 1, (x + 0), (y + height - bl)));
}
// next we go up
data.push('V' + (y + tl));
if(tl > 0) {
// now we draw the arc in the top-left corner
data.push('A' + arcParameter(tl, tl, 0, 0, 1, (x + tl), (y + 0)));
}
// and we close the path
data.push('Z');
return data.join(' ');
}
MOUNT_CLASS_TO.generatePathData = generatePathData;

2
src/helpers/sequentialDom.ts

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
import { fastRaf } from "./schedulers";
import { CancellablePromise, deferredPromise } from "./cancellablePromise";
import { isInDOM } from "./dom";
import { MOUNT_CLASS_TO } from "../config/debug";
import isInDOM from "./dom/isInDOM";
class SequentialDom {
private promises: Partial<{

3
src/index.ts

@ -5,6 +5,7 @@ @@ -5,6 +5,7 @@
*/
import App from './config/app';
import blurActiveElement from './helpers/dom/blurActiveElement';
import findUpClassName from './helpers/dom/findUpClassName';
import fixSafariStickyInput from './helpers/dom/fixSafariStickyInput';
import { isMobileSafari } from './helpers/userAgent';
@ -64,6 +65,8 @@ console.timeEnd('get storage1'); */ @@ -64,6 +65,8 @@ console.timeEnd('get storage1'); */
const vh = (setViewportVH && !rootScope.default.overlayIsActive ? w.height || w.innerHeight : window.innerHeight) * 0.01;
if(lastVH === vh) {
return;
} else if(lastVH < vh) {
blurActiveElement(); // (Android) fix blur when keyboard is being closed
}
lastVH = vh;

4
src/lib/appManagers/appDialogsManager.ts

@ -16,7 +16,6 @@ import { isSafari } from "../../helpers/userAgent"; @@ -16,7 +16,6 @@ import { isSafari } from "../../helpers/userAgent";
import { logger, LogTypes } from "../logger";
import { RichTextProcessor } from "../richtextprocessor";
import rootScope from "../rootScope";
import { attachClickEvent, positionElementByIndex, replaceContent } from "../../helpers/dom";
import apiUpdatesManager from "./apiUpdatesManager";
import appPeersManager from './appPeersManager';
import appImManager from "./appImManager";
@ -40,6 +39,9 @@ import lottieLoader from "../lottieLoader"; @@ -40,6 +39,9 @@ import lottieLoader from "../lottieLoader";
import { wrapLocalSticker } from "../../components/wrappers";
import AppEditFolderTab from "../../components/sidebarLeft/tabs/editFolder";
import appSidebarLeft from "../../components/sidebarLeft";
import { attachClickEvent } from "../../helpers/dom/clickEvent";
import positionElementByIndex from "../../helpers/dom/positionElementByIndex";
import replaceContent from "../../helpers/dom/replaceContent";
export type DialogDom = {
avatarEl: AvatarElement,

7
src/lib/appManagers/appImManager.ts

@ -24,7 +24,6 @@ import appPhotosManager from './appPhotosManager'; @@ -24,7 +24,6 @@ import appPhotosManager from './appPhotosManager';
import appProfileManager from './appProfileManager';
import appStickersManager from './appStickersManager';
import appWebPagesManager from './appWebPagesManager';
import { blurActiveElement, cancelEvent, disableTransition, placeCaretAtEnd, replaceContent, whichChild } from '../../helpers/dom';
import PopupNewMedia from '../../components/popups/newMedia';
import MarkupTooltip from '../../components/chat/markupTooltip';
import { isTouchSupported } from '../../helpers/touchSupport';
@ -51,6 +50,12 @@ import { getFilesFromEvent } from '../../helpers/files'; @@ -51,6 +50,12 @@ import { getFilesFromEvent } from '../../helpers/files';
import PeerTitle from '../../components/peerTitle';
import PopupPeer from '../../components/popups/peer';
import { SliceEnd } from '../../helpers/slicedArray';
import blurActiveElement from '../../helpers/dom/blurActiveElement';
import { cancelEvent } from '../../helpers/dom/cancelEvent';
import disableTransition from '../../helpers/dom/disableTransition';
import placeCaretAtEnd from '../../helpers/dom/placeCaretAtEnd';
import replaceContent from '../../helpers/dom/replaceContent';
import whichChild from '../../helpers/dom/whichChild';
//console.log('appImManager included33!');

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save