Browse Source

Chat move up animation

Rolled back reply wrapper to height animation
Preserve topbar with opened keyboard on iOS
Fix stickers size on iOS
Fix inputs size on handhelds
Fix saving scroll on ESG opening
master
Eduard Kuzmenko 3 years ago
parent
commit
cc1ab7ec6a
  1. 103
      src/components/chat/bubbles.ts
  2. 153
      src/components/chat/input.ts
  3. 1
      src/components/chat/pinnedContainer.ts
  4. 5
      src/components/chat/pinnedMessage.ts
  5. 3
      src/components/chat/topbar.ts
  6. 25
      src/components/emoticonsDropdown/index.ts
  7. 6
      src/components/sidebarLeft/tabs/editFolder.ts
  8. 5
      src/components/sidebarLeft/tabs/editProfile.ts
  9. 3
      src/components/sidebarLeft/tabs/includedChats.ts
  10. 8
      src/components/wrappers.ts
  11. 29
      src/helpers/dom.ts
  12. 4
      src/helpers/fastSmoothScroll.ts
  13. 23
      src/helpers/mediaSizes.ts
  14. 3
      src/lib/appManagers/AppInlineBotsManager.ts
  15. 2
      src/lib/appManagers/appDraftsManager.ts
  16. 4
      src/lib/appManagers/appImManager.ts
  17. 55
      src/lib/appManagers/appMessagesManager.ts
  18. 6
      src/lib/appManagers/appPollsManager.ts
  19. 4
      src/lib/richtextprocessor.ts
  20. 5
      src/lib/rootScope.ts
  21. 4
      src/pages/pageIm.ts
  22. 101
      src/scss/partials/_chat.scss
  23. 3
      src/scss/partials/_chatTopbar.scss
  24. 9
      src/scss/partials/_input.scss
  25. 8
      src/scss/partials/_leftSidebar.scss
  26. 1
      src/scss/partials/_slider.scss
  27. 1
      src/scss/partials/pages/_pages.scss

103
src/components/chat/bubbles.ts

@ -89,7 +89,7 @@ export default class ChatBubbles { @@ -89,7 +89,7 @@ export default class ChatBubbles {
private preloader: ProgressivePreloader = null;
private scrolledAll: boolean;
private scrolledAllDown: boolean;
public scrolledAllDown: boolean;
private loadedTopTimes = 0;
private loadedBottomTimes = 0;
@ -495,6 +495,93 @@ export default class ChatBubbles { @@ -495,6 +495,93 @@ export default class ChatBubbles {
});
}
});
if('ResizeObserver' in window) {
let wasHeight = this.scrollable.container.offsetHeight;
let resizing = false;
let skip = false;
let scrolled = 0;
let part = 0;
let rAF = 0;
const onResizeEnd = () => {
//this.log('resize end', scrolled, this.scrollable.scrollTop);
if(part) {
this.scrollable.scrollTop += Math.round(part);
}
wasHeight = this.scrollable.container.offsetHeight;
scrolled = 0;
rAF = 0;
part = 0;
resizing = false;
skip = false;
};
const setEndRAF = (single: boolean) => {
if(rAF) window.cancelAnimationFrame(rAF);
rAF = window.requestAnimationFrame(single ? onResizeEnd : () => {
rAF = window.requestAnimationFrame(onResizeEnd);
//this.log('resize after RAF', part);
});
};
// @ts-ignore
const resizeObserver = new ResizeObserver((entries) => {
if(skip) {
setEndRAF(false);
return;
}
const entry = entries[0];
const height = entry.contentRect.height;/* Math.ceil(entry.contentRect.height); */
if(!wasHeight) {
wasHeight = height;
return;
}
const realDiff = wasHeight - height;
let diff = realDiff + part;
const _part = diff % 1;
diff -= _part;
if(!resizing) {
resizing = true;
//this.log('resize start', realDiff, this.scrollable.isScrolledDown);
if(realDiff < 0 && this.scrollable.isScrolledDown) {
skip = true;
setEndRAF(false);
return;
}
}
scrolled += diff;
//this.log('resize', wasHeight - height, diff, this.scrollable.container.offsetHeight, this.scrollable.isScrolledDown, height, wasHeight/* , entry */);
if(diff) {
const needScrollTop = this.scrollable.scrollTop + diff;
this.scrollable.scrollTop = needScrollTop;
/* if(rAF) window.cancelAnimationFrame(rAF);
rAF = window.requestAnimationFrame(() => {
this.scrollable.scrollTop = needScrollTop;
setEndRAF(true);
//this.log('resize after RAF', part);
}); */
} //else {
setEndRAF(false);
//}
part = _part;
wasHeight = height;
});
resizeObserver.observe(this.bubblesContainer);
}
}
public constructPinnedHelpers() {
@ -2429,12 +2516,12 @@ export default class ChatBubbles { @@ -2429,12 +2516,12 @@ export default class ChatBubbles {
} */
// touchSupport for safari iOS
isTouchSupported && isApple && (this.scrollable.container.style.overflow = 'hidden');
//isTouchSupported && isApple && (this.scrollable.container.style.overflow = 'hidden');
this.scrollable.scrollTop = newScrollTop;
//this.scrollable.scrollTop = this.scrollable.scrollHeight;
isTouchSupported && isApple && (this.scrollable.container.style.overflow = '');
//isTouchSupported && isApple && (this.scrollable.container.style.overflow = '');
if(isSafari && !isAppleMobile) { // * fix blinking and jumping
if(isSafari/* && !isAppleMobile */) { // * fix blinking and jumping
this.scrollable.container.style.display = 'none';
void this.scrollable.container.offsetLeft; // reflow
this.scrollable.container.style.display = '';
@ -2667,8 +2754,8 @@ export default class ChatBubbles { @@ -2667,8 +2754,8 @@ export default class ChatBubbles {
const bottomIds = isAdditionRender ? [] : sortedMids.slice(0, sortedMids.findIndex(mid => targetMid >= mid)).reverse();
this.log('getHistory: targeting mid:', targetMid, maxId, additionMsgId,
topIds.map(m => this.appMessagesManager.getLocalMessageId(m)),
bottomIds.map(m => this.appMessagesManager.getLocalMessageId(m)));
topIds.map(m => this.appMessagesManager.getServerMessageId(m)),
bottomIds.map(m => this.appMessagesManager.getServerMessageId(m)));
const setBubbles: HTMLElement[] = [];
@ -2839,6 +2926,10 @@ export default class ChatBubbles { @@ -2839,6 +2926,10 @@ export default class ChatBubbles {
}
public setUnreadDelimiter() {
if(!(this.chat.type === 'chat' || this.chat.type === 'discussion')) {
return;
}
if(this.attachedUnreadBubble) {
return;
}

153
src/components/chat/input.ts

@ -13,7 +13,7 @@ import apiManager from "../../lib/mtproto/mtprotoworker"; @@ -13,7 +13,7 @@ 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, findUpClassName, getRichValue, getSelectedNodes, isInputEmpty, markdownTags, MarkdownType, placeCaretAtEnd, isSendShortcutPressed } from "../../helpers/dom";
import { attachClickEvent, blurActiveElement, cancelEvent, cancelSelection, findUpClassName, getRichValue, getSelectedNodes, isInputEmpty, markdownTags, MarkdownType, placeCaretAtEnd, isSendShortcutPressed, fixSafariStickyInput } from "../../helpers/dom";
import { ButtonMenuItemOptions } from '../buttonMenu';
import emoticonsDropdown from "../emoticonsDropdown";
import PopupCreatePoll from "../popups/createPoll";
@ -36,6 +36,7 @@ import rootScope from '../../lib/rootScope'; @@ -36,6 +36,7 @@ import rootScope from '../../lib/rootScope';
import PopupPinMessage from '../popups/unpinMessage';
import { debounce } from '../../helpers/schedulers';
import { tsNow } from '../../helpers/date';
import { isSafari } from '../../helpers/userAgent';
const RECORD_MIN_TIME = 500;
const POSTING_MEDIA_NOT_ALLOWED = 'Posting media content isn\'t allowed in this group.';
@ -88,9 +89,9 @@ export default class ChatInput { @@ -88,9 +89,9 @@ export default class ChatInput {
private recordRippleEl: HTMLElement;
private recordStartTime = 0;
private scrollTop = 0;
private scrollOffsetTop = 0;
private scrollDiff = 0;
// private scrollTop = 0;
// private scrollOffsetTop = 0;
// private scrollDiff = 0;
public helperType: Exclude<ChatInputHelperType, 'webpage'>;
private helperFunc: () => void;
@ -137,7 +138,7 @@ export default class ChatInput { @@ -137,7 +138,7 @@ export default class ChatInput {
this.goDownUnreadBadge = document.createElement('span');
this.goDownUnreadBadge.classList.add('badge', 'badge-24', 'badge-green');
this.goDownBtn.append(this.goDownUnreadBadge);
this.chatInput.append(this.goDownBtn);
this.inputContainer.append(this.goDownBtn);
attachClickEvent(this.goDownBtn, (e) => {
cancelEvent(e);
@ -145,6 +146,71 @@ export default class ChatInput { @@ -145,6 +146,71 @@ export default class ChatInput {
}, {listenerSetter: this.listenerSetter});
// * constructor end
/* let setScrollTopTimeout: number;
// @ts-ignore
let height = window.visualViewport.height; */
// @ts-ignore
// this.listenerSetter.add(window.visualViewport, 'resize', () => {
// const scrollable = this.chat.bubbles.scrollable;
// const wasScrolledDown = scrollable.isScrolledDown;
// /* if(wasScrolledDown) {
// this.saveScroll();
// } */
// // @ts-ignore
// let newHeight = window.visualViewport.height;
// const diff = height - newHeight;
// const scrollTop = scrollable.scrollTop;
// const needScrollTop = wasScrolledDown ? scrollable.scrollHeight : scrollTop + diff; // * wasScrolledDown это проверка для десктоп хрома, когда пропадает панель загрузок снизу
// console.log('resize before', scrollable.scrollTop, scrollable.container.clientHeight, scrollable.scrollHeight, wasScrolledDown, scrollable.lastScrollTop, diff, needScrollTop);
// scrollable.scrollTop = needScrollTop;
// if(setScrollTopTimeout) clearTimeout(setScrollTopTimeout);
// setScrollTopTimeout = window.setTimeout(() => {
// const diff = height - newHeight;
// const isScrolledDown = scrollable.scrollHeight - Math.round(scrollable.scrollTop + scrollable.container.offsetHeight + diff) <= 1;
// height = newHeight;
// scrollable.scrollTop = needScrollTop;
// console.log('resize after', scrollable.scrollTop, scrollable.container.clientHeight, scrollable.scrollHeight, scrollable.isScrolledDown, scrollable.lastScrollTop, isScrolledDown);
// /* if(isScrolledDown) {
// scrollable.scrollTop = scrollable.scrollHeight;
// } */
// //scrollable.scrollTop += diff;
// setScrollTopTimeout = 0;
// }, 0);
// });
// ! Can't use it with resizeObserver
/* this.listenerSetter.add(window.visualViewport, 'resize', () => {
const scrollable = this.chat.bubbles.scrollable;
const wasScrolledDown = scrollable.isScrolledDown;
// @ts-ignore
let newHeight = window.visualViewport.height;
const diff = height - newHeight;
const needScrollTop = wasScrolledDown ? scrollable.scrollHeight : scrollable.scrollTop + diff; // * wasScrolledDown это проверка для десктоп хрома, когда пропадает панель загрузок снизу
//console.log('resize before', scrollable.scrollTop, scrollable.container.clientHeight, scrollable.scrollHeight, wasScrolledDown, scrollable.lastScrollTop, diff, needScrollTop);
scrollable.scrollTop = needScrollTop;
height = newHeight;
if(setScrollTopTimeout) clearTimeout(setScrollTopTimeout);
setScrollTopTimeout = window.setTimeout(() => { // * try again for scrolled down Android Chrome
scrollable.scrollTop = needScrollTop;
//console.log('resize after', scrollable.scrollTop, scrollable.container.clientHeight, scrollable.scrollHeight, scrollable.isScrolledDown, scrollable.lastScrollTop, isScrolledDown);
setScrollTopTimeout = 0;
}, 0);
}); */
}
public constructPeerHelpers() {
@ -650,13 +716,19 @@ export default class ChatInput { @@ -650,13 +716,19 @@ export default class ChatInput {
if(isTouchSupported) {
attachClickEvent(this.messageInput, (e) => {
this.appImManager.selectTab(1); // * set chat tab for album orientation
this.saveScroll();
//this.saveScroll();
emoticonsDropdown.toggle(false);
}, {listenerSetter: this.listenerSetter});
this.listenerSetter.add(window, 'resize', () => {
/* this.listenerSetter.add(window, 'resize', () => {
this.restoreScroll();
});
}); */
/* if(isSafari) {
this.listenerSetter.add(this.messageInput, 'focusin', () => {
fixSafariStickyInput(this.messageInput);
});
} */
}
/* this.listenerSetter.add(this.messageInput, 'beforeinput', (e: Event) => {
@ -673,6 +745,14 @@ export default class ChatInput { @@ -673,6 +745,14 @@ export default class ChatInput {
}
}); */
this.listenerSetter.add(this.messageInput, 'input', this.onMessageInput);
if(this.chat.type === 'chat' || this.chat.type === 'discussion') {
this.listenerSetter.add(this.messageInput, 'focusin', () => {
if(this.chat.bubbles.scrolledAllDown) {
this.appMessagesManager.readAllHistory(this.chat.peerId, this.chat.threadId);
}
});
}
}
private prepareDocumentExecute = () => {
@ -1170,10 +1250,7 @@ export default class ChatInput { @@ -1170,10 +1250,7 @@ export default class ChatInput {
public onMessageSent(clearInput = true, clearReply?: boolean) {
if(this.chat.type !== 'scheduled') {
const historyStorage = this.appMessagesManager.getHistoryStorage(this.chat.peerId, this.chat.threadId);
if(historyStorage.maxId) {
this.appMessagesManager.readHistory(this.chat.peerId, historyStorage.maxId, this.chat.threadId); // lol
}
this.appMessagesManager.readAllHistory(this.chat.peerId, this.chat.threadId, true);
}
this.scheduleDate = undefined;
@ -1407,30 +1484,30 @@ export default class ChatInput { @@ -1407,30 +1484,30 @@ export default class ChatInput {
}, 0);
}
public saveScroll() {
this.scrollTop = this.chat.bubbles.scrollable.container.scrollTop;
this.scrollOffsetTop = this.chatInput.offsetTop;
}
public restoreScroll() {
if(this.chatInput.style.display) return;
//console.log('input resize', offsetTop, this.chatInput.offsetTop);
let newOffsetTop = this.chatInput.offsetTop;
let container = this.chat.bubbles.scrollable.container;
let scrollTop = container.scrollTop;
let clientHeight = container.clientHeight;
let maxScrollTop = container.scrollHeight;
if(newOffsetTop < this.scrollOffsetTop) {
this.scrollDiff = this.scrollOffsetTop - newOffsetTop;
container.scrollTop += this.scrollDiff;
} else if(scrollTop != this.scrollTop) {
let endDiff = maxScrollTop - (scrollTop + clientHeight);
if(endDiff < this.scrollDiff/* && false */) {
//container.scrollTop -= endDiff;
} else {
container.scrollTop -= this.scrollDiff;
}
}
}
// public saveScroll() {
// this.scrollTop = this.chat.bubbles.scrollable.container.scrollTop;
// this.scrollOffsetTop = this.chatInput.offsetTop;
// }
// public restoreScroll() {
// if(this.chatInput.style.display) return;
// //console.log('input resize', offsetTop, this.chatInput.offsetTop);
// let newOffsetTop = this.chatInput.offsetTop;
// let container = this.chat.bubbles.scrollable.container;
// let scrollTop = container.scrollTop;
// let clientHeight = container.clientHeight;
// let maxScrollTop = container.scrollHeight;
// if(newOffsetTop < this.scrollOffsetTop) {
// this.scrollDiff = this.scrollOffsetTop - newOffsetTop;
// container.scrollTop += this.scrollDiff;
// } else if(scrollTop != this.scrollTop) {
// let endDiff = maxScrollTop - (scrollTop + clientHeight);
// if(endDiff < this.scrollDiff/* && false */) {
// //container.scrollTop -= endDiff;
// } else {
// container.scrollTop -= this.scrollDiff;
// }
// }
// }
}

1
src/components/chat/pinnedContainer.ts

@ -61,6 +61,7 @@ export default class PinnedContainer { @@ -61,6 +61,7 @@ export default class PinnedContainer {
}
this.divAndCaption.container.classList.toggle('is-floating', mediaSizes.isMobile);
this.topbar.container.classList.toggle('is-pinned-floating', mediaSizes.isMobile);
const scrollable = this.chat.bubbles.scrollable;

5
src/components/chat/pinnedMessage.ts

@ -550,11 +550,6 @@ export default class ChatPinnedMessage { @@ -550,11 +550,6 @@ export default class ChatPinnedMessage {
}
}
public onChangeScreen(from: ScreenSize, to: ScreenSize) {
this.pinnedMessageContainer.divAndCaption.container.classList.toggle('is-floating', to == ScreenSize.mobile
/* || (!this.chatAudio.divAndCaption.container.classList.contains('hide') && to == ScreenSize.medium) */);
}
public _setPinnedMessage() {
/////this.log('setting pinned message', message);
//return;

3
src/components/chat/topbar.ts

@ -328,8 +328,9 @@ export default class ChatTopbar { @@ -328,8 +328,9 @@ export default class ChatTopbar {
};
private onChangeScreen = (from: ScreenSize, to: ScreenSize) => {
this.container.classList.toggle('is-pinned-floating', mediaSizes.isMobile);
this.chatAudio && this.chatAudio.divAndCaption.container.classList.toggle('is-floating', to == ScreenSize.mobile);
this.pinnedMessage && this.pinnedMessage.onChangeScreen(from, to);
this.pinnedMessage && this.pinnedMessage.pinnedMessageContainer.divAndCaption.container.classList.toggle('is-floating', to == ScreenSize.mobile);
this.setUtilsWidth(true);
};

25
src/components/emoticonsDropdown/index.ts

@ -3,7 +3,7 @@ import appChatsManager from "../../lib/appManagers/appChatsManager"; @@ -3,7 +3,7 @@ import appChatsManager from "../../lib/appManagers/appChatsManager";
import appImManager from "../../lib/appManagers/appImManager";
import { MOUNT_CLASS_TO } from "../../lib/mtproto/mtproto_config";
import rootScope from "../../lib/rootScope";
import { findUpClassName, findUpTag, whichChild } from "../../helpers/dom";
import { blurActiveElement, findUpClassName, findUpTag, whichChild } from "../../helpers/dom";
import animationIntersector from "../animationIntersector";
import { horizontalMenu } from "../horizontalMenu";
import LazyLoadQueue, { LazyLoadQueueIntersector } from "../lazyLoadQueue";
@ -219,10 +219,10 @@ export class EmoticonsDropdown { @@ -219,10 +219,10 @@ export class EmoticonsDropdown {
if(isTouchSupported) {
if(willBeActive) {
appImManager.chat.input.saveScroll();
// @ts-ignore
document.activeElement.blur();
await pause(100);
//appImManager.chat.input.saveScroll();
if(blurActiveElement()) {
await pause(100);
}
}
}
@ -253,6 +253,13 @@ export class EmoticonsDropdown { @@ -253,6 +253,13 @@ export class EmoticonsDropdown {
this.events.onOpenAfter.forEach(cb => cb());
}, isTouchSupported ? 0 : 200);
// ! can't use together with resizeObserver
/* if(isTouchSupported) {
const height = this.element.scrollHeight + appImManager.chat.input.inputContainer.scrollHeight - 10;
console.log('[ESG]: toggle: enable height', height);
appImManager.chat.bubbles.scrollable.scrollTop += height;
} */
/* if(touchSupport) {
this.restoreScroll();
} */
@ -283,6 +290,14 @@ export class EmoticonsDropdown { @@ -283,6 +290,14 @@ export class EmoticonsDropdown {
this.events.onCloseAfter.forEach(cb => cb());
}, isTouchSupported ? 0 : 200);
/* if(isTouchSupported) {
const scrollHeight = this.container.scrollHeight;
if(scrollHeight) {
const height = this.container.scrollHeight + appImManager.chat.input.inputContainer.scrollHeight - 10;
appImManager.chat.bubbles.scrollable.scrollTop -= height;
}
} */
/* if(touchSupport) {
this.restoreScroll();
} */

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

@ -24,7 +24,6 @@ export default class AppEditFolderTab extends SliderSuperTab { @@ -24,7 +24,6 @@ export default class AppEditFolderTab extends SliderSuperTab {
private confirmBtn: HTMLElement;
private menuBtn: HTMLElement;
private nameInput: HTMLElement;
private nameInputField: InputField;
private include_peers: HTMLElement;
@ -49,7 +48,7 @@ export default class AppEditFolderTab extends SliderSuperTab { @@ -49,7 +48,7 @@ export default class AppEditFolderTab extends SliderSuperTab {
this.stickerContainer = document.createElement('div');
this.stickerContainer.classList.add('sticker-container');
this.confirmBtn = ButtonIcon('check1 btn-confirm hide');
this.confirmBtn = ButtonIcon('check btn-confirm hide blue');
const deleteFolderButton: ButtonMenuItemOptions = {
icon: 'delete danger',
text: 'Delete Folder',
@ -76,7 +75,6 @@ export default class AppEditFolderTab extends SliderSuperTab { @@ -76,7 +75,6 @@ export default class AppEditFolderTab extends SliderSuperTab {
label: 'Folder Name',
maxLength: MAX_FOLDER_NAME_LENGTH
});
this.nameInput = this.nameInputField.input;
inputWrapper.append(this.nameInputField.container);
@ -220,7 +218,7 @@ export default class AppEditFolderTab extends SliderSuperTab { @@ -220,7 +218,7 @@ export default class AppEditFolderTab extends SliderSuperTab {
});
});
this.nameInput.addEventListener('input', () => {
this.nameInputField.input.addEventListener('input', () => {
this.filter.title = this.nameInputField.value;
this.editCheckForChange();
});

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

@ -6,10 +6,9 @@ import RichTextProcessor from "../../../lib/richtextprocessor"; @@ -6,10 +6,9 @@ import RichTextProcessor from "../../../lib/richtextprocessor";
import rootScope from "../../../lib/rootScope";
import AvatarElement from "../../avatar";
import InputField from "../../inputField";
import Scrollable from "../../scrollable";
import SidebarSlider, { SliderSuperTab } from "../../slider";
import AvatarEdit from "../../avatarEdit";
import ButtonIcon from "../../buttonIcon";
import Button from "../../button";
// TODO: аватарка не поменяется в этой вкладке после изменения почему-то (если поставить в другом клиенте, и потом тут проверить, для этого ещё вышел в чатлист)
@ -48,7 +47,7 @@ export default class AppEditProfileTab extends SliderSuperTab { @@ -48,7 +47,7 @@ export default class AppEditProfileTab extends SliderSuperTab {
this.container.classList.add('edit-profile-container');
this.title.innerText = 'Edit Profile';
//this.scrollWrapper = this.container.querySelector('.scroll-wrapper');
this.nextBtn = ButtonIcon('check btn-circle btn-corner');
this.nextBtn = Button('btn-circle btn-corner tgico-check');
this.content.append(this.nextBtn);
this.avatarElem = document.createElement('avatar-element') as AvatarElement;

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

@ -8,7 +8,6 @@ import { MyDialogFilter as DialogFilter } from "../../../lib/storages/filters"; @@ -8,7 +8,6 @@ import { MyDialogFilter as DialogFilter } from "../../../lib/storages/filters";
import rootScope from "../../../lib/rootScope";
import { copy } from "../../../helpers/object";
import ButtonIcon from "../../buttonIcon";
import { FocusDirection } from "../../../helpers/fastSmoothScroll";
import { fastRaf } from "../../../helpers/schedulers";
import CheckboxField from "../../checkbox";
import Button from "../../button";
@ -28,7 +27,7 @@ export default class AppIncludedChatsTab extends SliderSuperTab { @@ -28,7 +27,7 @@ export default class AppIncludedChatsTab extends SliderSuperTab {
init() {
this.content.remove();
this.container.classList.add('included-chatlist-container');
this.confirmBtn = ButtonIcon('check1 btn-confirm', {noRipple: true});
this.confirmBtn = ButtonIcon('check btn-confirm blue', {noRipple: true});
this.confirmBtn.style.display = 'none';
this.header.append(this.confirmBtn);

8
src/components/wrappers.ts

@ -116,6 +116,8 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai @@ -116,6 +116,8 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
//video.muted = true;
const globalVideo = appMediaPlaybackController.addMedia(message.peerId, doc, message.mid);
video.classList.add('z-depth-1');
video.addEventListener('canplay', () => {
if(globalVideo.currentTime > 0) {
video.currentTime = globalVideo.currentTime;
@ -350,7 +352,7 @@ export function wrapDocument({message, withTime, fontWeight, voiceAsMusic, showS @@ -350,7 +352,7 @@ export function wrapDocument({message, withTime, fontWeight, voiceAsMusic, showS
const uploading = message.pFlags.is_outgoing;
const doc = message.media.document || message.media.webpage.document;
const doc = (message.media.document || message.media.webpage.document) as MyDocument;
if(doc.type === 'audio' || doc.type === 'voice') {
const audioElement = new AudioElement();
audioElement.setAttribute('message-id', '' + message.mid);
@ -458,6 +460,10 @@ export function wrapDocument({message, withTime, fontWeight, voiceAsMusic, showS @@ -458,6 +460,10 @@ export function wrapDocument({message, withTime, fontWeight, voiceAsMusic, showS
attachClickEvent(docDiv, (e) => {
preloader.onClick(e);
});
/* if(doc.downloaded) {
downloadDiv.classList.add('downloaded');
} */
} else if(message.media?.preloader) {
const icoDiv = docDiv.querySelector('.document-ico');
message.media.preloader.attach(icoDiv, false);

29
src/helpers/dom.ts

@ -3,7 +3,7 @@ import { MOUNT_CLASS_TO } from "../lib/mtproto/mtproto_config"; @@ -3,7 +3,7 @@ import { MOUNT_CLASS_TO } from "../lib/mtproto/mtproto_config";
import RichTextProcessor from "../lib/richtextprocessor";
import ListenerSetter from "./listenerSetter";
import { isTouchSupported } from "./touchSupport";
import { isSafari, isApple } from "./userAgent";
import { isApple } from "./userAgent";
import rootScope from "../lib/rootScope";
/* export function isInDOM(element: Element, parentNode?: HTMLElement): boolean {
@ -54,6 +54,10 @@ export function cancelEvent(event: Event) { @@ -54,6 +54,10 @@ export function cancelEvent(event: Event) {
}
export function placeCaretAtEnd(el: HTMLElement) {
if(isTouchSupported) {
return;
}
el.focus();
if(typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") {
var range = document.createRange();
@ -486,7 +490,30 @@ export function getSelectedText(): string { @@ -486,7 +490,30 @@ export function getSelectedText(): string {
export function blurActiveElement() {
if(document.activeElement && (document.activeElement as HTMLInputElement).blur) {
(document.activeElement as HTMLInputElement).blur();
return true;
}
return false;
}
export function fixSafariStickyInput(input: HTMLElement) {
input.style.transform = 'translateY(-99999px)';
/* input.style.position = 'fixed';
input.style.top = '-99999px';
input.style.left = '0'; */
input.focus();
setTimeout(() => {
//fastSmoothScroll(findUpClassName(input, 'scrollable-y') || window as any, document.activeElement as HTMLElement, 'start', 4, undefined, FocusDirection.Static);
/* input.style.position = '';
input.style.top = ''; */
input.style.transform = '';
//fastSmoothScroll(findUpClassName(input, 'scrollable-y') || window as any, document.activeElement as HTMLElement, 'start', 4, undefined, FocusDirection.Static);
/* setTimeout(() => {
fastSmoothScroll(findUpClassName(input, 'scrollable-y') || window as any, document.activeElement as HTMLElement, 'start', 4);
}, 50); */
}, 0);
}
export const CLICK_EVENT_NAME: 'mousedown' | 'touchend' | 'click' = (isTouchSupported ? 'mousedown' : 'click') as any;

4
src/helpers/fastSmoothScroll.ts

@ -43,7 +43,7 @@ export default function fastSmoothScroll( @@ -43,7 +43,7 @@ export default function fastSmoothScroll(
return Promise.resolve(); */
}
if(axis === 'y' && isInDOM(element)) {
if(axis === 'y' && isInDOM(element) && container.getBoundingClientRect) {
const elementRect = element.getBoundingClientRect();
const containerRect = container.getBoundingClientRect();
@ -102,7 +102,7 @@ function scrollWithJs( @@ -102,7 +102,7 @@ function scrollWithJs(
//const { offsetTop: elementTop, offsetHeight: elementHeight } = element;
const elementRect = element.getBoundingClientRect();
const containerRect = container.getBoundingClientRect();
const containerRect = container.getBoundingClientRect ? container.getBoundingClientRect() : document.body.getBoundingClientRect();
//const transformable = container.firstElementChild as HTMLElement;

23
src/helpers/mediaSizes.ts

@ -42,7 +42,10 @@ class MediaSizes extends EventListenerBase<{ @@ -42,7 +42,10 @@ class MediaSizes extends EventListenerBase<{
width: 293,
height: 0
},
esgSticker: {}
esgSticker: {
width: 68,
height: 68
}
},
desktop: {
regular: {
@ -57,18 +60,28 @@ class MediaSizes extends EventListenerBase<{ @@ -57,18 +60,28 @@ class MediaSizes extends EventListenerBase<{
width: 451,
height: 0
},
esgSticker: {}
esgSticker: {
width: 80,
height: 80
}
}
};
public isMobile = false;
public active: Sizes;
public activeScreen: ScreenSize;
public rAF: number;
constructor() {
super();
window.addEventListener('resize', this.handleResize);
window.addEventListener('resize', () => {
if(this.rAF) window.cancelAnimationFrame(this.rAF);
this.rAF = window.requestAnimationFrame(() => {
this.handleResize();
this.rAF = 0;
});
});
this.handleResize();
}
@ -90,8 +103,8 @@ class MediaSizes extends EventListenerBase<{ @@ -90,8 +103,8 @@ class MediaSizes extends EventListenerBase<{
this.active = this.isMobile ? this.sizes.handhelds : this.sizes.desktop;
//console.time('esg');
const computedStyle = window.getComputedStyle(document.documentElement);
this.active.esgSticker.width = parseFloat(computedStyle.getPropertyValue('--esg-sticker-size'));
//const computedStyle = window.getComputedStyle(document.documentElement);
//this.active.esgSticker.width = parseFloat(computedStyle.getPropertyValue('--esg-sticker-size'));
//console.timeEnd('esg');
if(wasScreen != activeScreen) {

3
src/lib/appManagers/AppInlineBotsManager.ts

@ -6,6 +6,7 @@ import { RichTextProcessor } from "../richtextprocessor"; @@ -6,6 +6,7 @@ import { RichTextProcessor } from "../richtextprocessor";
import appDocsManager from "./appDocsManager";
import appPhotosManager from "./appPhotosManager";
import appUsersManager from "./appUsersManager";
import appMessagesManager from "./appMessagesManager";
export class AppInlineBotsManager {
private inlineResults: {[qId: string]: BotInlineResult} = {};
@ -271,7 +272,7 @@ export class AppInlineBotsManager { @@ -271,7 +272,7 @@ export class AppInlineBotsManager {
public callbackButtonClick(peerId: number, mid: number, button: any) {
return apiManagerProxy.invokeApi('messages.getBotCallbackAnswer', {
peer: appPeersManager.getInputPeerById(peerId),
msg_id: mid,
msg_id: appMessagesManager.getServerMessageId(mid),
data: button.data
}, {timeout: 1, stopTime: -1, noErrorBox: true}).then((callbackAnswer) => {
if(typeof callbackAnswer.message === 'string' && callbackAnswer.message.length) {

2
src/lib/appManagers/appDraftsManager.ts

@ -189,7 +189,7 @@ export class AppDraftsManager { @@ -189,7 +189,7 @@ export class AppDraftsManager {
let entities: MessageEntity[] = localDraft.entities;
if(localDraft.reply_to_msg_id) {
params.reply_to_msg_id = appMessagesManager.getLocalMessageId(localDraft.reply_to_msg_id);
params.reply_to_msg_id = appMessagesManager.getServerMessageId(localDraft.reply_to_msg_id);
}
if(entities?.length) {

4
src/lib/appManagers/appImManager.ts

@ -258,7 +258,7 @@ export class AppImManager { @@ -258,7 +258,7 @@ export class AppImManager {
}
}
if(chat.input.messageInput && e.target !== chat.input.messageInput && target.tagName !== 'INPUT' && !target.hasAttribute('contenteditable')) {
if(chat.input.messageInput && e.target !== chat.input.messageInput && target.tagName !== 'INPUT' && !target.hasAttribute('contenteditable') && !isTouchSupported) {
chat.input.messageInput.focus();
placeCaretAtEnd(chat.input.messageInput);
}
@ -455,6 +455,8 @@ export class AppImManager { @@ -455,6 +455,8 @@ export class AppImManager {
document.body.classList.remove(RIGHT_COLUMN_ACTIVE_CLASSNAME);
}
rootScope.broadcast('im_tab_change', id);
//this._selectTab(id, mediaSizes.isMobile);
//document.body.classList.toggle(RIGHT_COLUMN_ACTIVE_CLASSNAME, id == 2);
}

55
src/lib/appManagers/appMessagesManager.ts

@ -451,7 +451,7 @@ export class AppMessagesManager { @@ -451,7 +451,7 @@ export class AppMessagesManager {
const messageId = this.generateTempMessageId(peerId);
const randomIdS = randomLong();
const replyToMsgId = options.replyToMsgId ? this.getLocalMessageId(options.replyToMsgId) : undefined;
const replyToMsgId = options.replyToMsgId ? this.getServerMessageId(options.replyToMsgId) : undefined;
const isChannel = appPeersManager.isChannel(peerId);
const isBroadcast = appPeersManager.isBroadcast(peerId);
@ -607,7 +607,7 @@ export class AppMessagesManager { @@ -607,7 +607,7 @@ export class AppMessagesManager {
const messageId = this.generateTempMessageId(peerId);
const randomIdS = randomLong();
const pFlags = this.generateFlags(peerId);
const replyToMsgId = options.replyToMsgId ? this.getLocalMessageId(options.replyToMsgId) : undefined;
const replyToMsgId = options.replyToMsgId ? this.getServerMessageId(options.replyToMsgId) : undefined;
const isChannel = appPeersManager.isChannel(peerId);
const isMegagroup = isChannel && appPeersManager.isMegagroup(peerId);
const asChannel = !!(isChannel && !isMegagroup);
@ -1004,7 +1004,7 @@ export class AppMessagesManager { @@ -1004,7 +1004,7 @@ export class AppMessagesManager {
}
peerId = appPeersManager.getPeerMigratedTo(peerId) || peerId;
const replyToMsgId = options.replyToMsgId ? this.getLocalMessageId(options.replyToMsgId) : undefined;
const replyToMsgId = options.replyToMsgId ? this.getServerMessageId(options.replyToMsgId) : undefined;
let caption = options.caption || '';
let entities = options.entities || [];
@ -1155,7 +1155,7 @@ export class AppMessagesManager { @@ -1155,7 +1155,7 @@ export class AppMessagesManager {
//this.checkSendOptions(options);
const messageId = this.generateTempMessageId(peerId);
const randomIdS = randomLong();
const replyToMsgId = options.replyToMsgId ? this.getLocalMessageId(options.replyToMsgId) : undefined;
const replyToMsgId = options.replyToMsgId ? this.getServerMessageId(options.replyToMsgId) : undefined;
const isChannel = appPeersManager.isChannel(peerId);
const isMegagroup = isChannel && appPeersManager.isMegagroup(peerId);
const asChannel = isChannel && !isMegagroup ? true : false;
@ -1639,7 +1639,7 @@ export class AppMessagesManager { @@ -1639,7 +1639,7 @@ export class AppMessagesManager {
// ! это может случиться, если запрос идёт не по папке 0, а по 1. почему-то read'ов нет
// ! в итоге, чтобы получить 1 диалог, делается первый запрос по папке 0, потом запрос для архивных по папке 1, и потом ещё перезагрузка архивного диалога
if(!this.getLocalMessageId(dialog.read_inbox_max_id) && !this.getLocalMessageId(dialog.read_outbox_max_id)) {
if(!this.getServerMessageId(dialog.read_inbox_max_id) && !this.getServerMessageId(dialog.read_outbox_max_id)) {
noIdsDialogs[dialog.peerId] = dialog;
this.log.error('noIdsDialogs', dialog);
@ -1692,7 +1692,7 @@ export class AppMessagesManager { @@ -1692,7 +1692,7 @@ export class AppMessagesManager {
scheduleDate: number
}> = {}) {
peerId = appPeersManager.getPeerMigratedTo(peerId) || peerId;
msgIds = msgIds.slice().sort((a, b) => a - b).map(mid => this.getLocalMessageId(mid));
msgIds = msgIds.slice().sort((a, b) => a - b).map(mid => this.getServerMessageId(mid));
const randomIds: string[] = msgIds.map(() => randomLong());
@ -1911,7 +1911,7 @@ export class AppMessagesManager { @@ -1911,7 +1911,7 @@ export class AppMessagesManager {
unpin,
silent,
pm_oneside: oneSide,
id: this.getLocalMessageId(mid)
id: this.getServerMessageId(mid)
}).then(updates => {
//this.log('pinned updates:', updates);
apiUpdatesManager.processUpdateMessage(updates);
@ -2023,7 +2023,7 @@ export class AppMessagesManager { @@ -2023,7 +2023,7 @@ export class AppMessagesManager {
/**
* * will ignore outgoing offset
*/
public getLocalMessageId(messageId: number) {
public getServerMessageId(messageId: number) {
const q = AppMessagesManager.MESSAGE_ID_OFFSET;
if(messageId <= q) {
return messageId;
@ -2039,7 +2039,7 @@ export class AppMessagesManager { @@ -2039,7 +2039,7 @@ export class AppMessagesManager {
}
public incrementMessageId(messageId: number, increment: number) {
return this.generateMessageId(this.getLocalMessageId(messageId) + increment);
return this.generateMessageId(this.getServerMessageId(messageId) + increment);
}
public saveMessages(messages: any[], options: Partial<{
@ -3109,12 +3109,12 @@ export class AppMessagesManager { @@ -3109,12 +3109,12 @@ export class AppMessagesManager {
min_date: minDate,
max_date: maxDate,
limit,
offset_id: this.getLocalMessageId(maxId) || 0,
offset_id: this.getServerMessageId(maxId) || 0,
add_offset: backLimit ? -backLimit : 0,
max_id: 0,
min_id: 0,
hash: 0,
top_msg_id: this.getLocalMessageId(threadId) || 0
top_msg_id: this.getServerMessageId(threadId) || 0
}, {
//timeout: APITIMEOUT,
noErrorBox: true
@ -3223,7 +3223,7 @@ export class AppMessagesManager { @@ -3223,7 +3223,7 @@ export class AppMessagesManager {
public getDiscussionMessage(peerId: number, mid: number) {
return apiManager.invokeApi('messages.getDiscussionMessage', {
peer: appPeersManager.getInputPeerById(peerId),
msg_id: this.getLocalMessageId(mid)
msg_id: this.getServerMessageId(mid)
}).then(result => {
appChatsManager.saveApiChats(result.chats);
appUsersManager.saveApiUsers(result.users);
@ -3290,7 +3290,7 @@ export class AppMessagesManager { @@ -3290,7 +3290,7 @@ export class AppMessagesManager {
public deleteMessages(peerId: number, mids: number[], revoke?: true) {
let promise: Promise<any>;
const localMessageIds = mids.map(mid => this.getLocalMessageId(mid));
const localMessageIds = mids.map(mid => this.getServerMessageId(mid));
if(peerId < 0 && appPeersManager.isChannel(peerId)) {
const channelId = -peerId;
@ -3365,8 +3365,8 @@ export class AppMessagesManager { @@ -3365,8 +3365,8 @@ export class AppMessagesManager {
if(!historyStorage.readPromise) {
apiPromise = apiManager.invokeApi('messages.readDiscussion', {
peer: appPeersManager.getInputPeerById(peerId),
msg_id: this.getLocalMessageId(threadId),
read_max_id: this.getLocalMessageId(maxId)
msg_id: this.getServerMessageId(threadId),
read_max_id: this.getServerMessageId(maxId)
});
}
@ -3383,7 +3383,7 @@ export class AppMessagesManager { @@ -3383,7 +3383,7 @@ export class AppMessagesManager {
if(!historyStorage.readPromise) {
apiPromise = apiManager.invokeApi('channels.readHistory', {
channel: appChatsManager.getChannelInput(-peerId),
max_id: this.getLocalMessageId(maxId)
max_id: this.getServerMessageId(maxId)
});
}
@ -3399,7 +3399,7 @@ export class AppMessagesManager { @@ -3399,7 +3399,7 @@ export class AppMessagesManager {
if(!historyStorage.readPromise) {
apiPromise = apiManager.invokeApi('messages.readHistory', {
peer: appPeersManager.getInputPeerById(peerId),
max_id: this.getLocalMessageId(maxId)
max_id: this.getServerMessageId(maxId)
}).then((affectedMessages) => {
apiUpdatesManager.processUpdateMessage({
_: 'updateShort',
@ -3439,8 +3439,15 @@ export class AppMessagesManager { @@ -3439,8 +3439,15 @@ export class AppMessagesManager {
return historyStorage.readPromise = apiPromise;
}
public readAllHistory(peerId: number, threadId?: number, force = false) {
const historyStorage = this.getHistoryStorage(peerId, threadId);
if(historyStorage.maxId) {
this.readHistory(peerId, historyStorage.maxId, threadId, force); // lol
}
}
public readMessages(peerId: number, msgIds: number[]) {
msgIds = msgIds.map(mid => this.getLocalMessageId(mid));
msgIds = msgIds.map(mid => this.getServerMessageId(mid));
if(peerId < 0 && appPeersManager.isChannel(peerId)) {
const channelId = -peerId;
apiManager.invokeApi('channels.readMessageContents', {
@ -4394,7 +4401,7 @@ export class AppMessagesManager { @@ -4394,7 +4401,7 @@ export class AppMessagesManager {
sessionStorage.set({max_seen_msg: maxId});
apiManager.invokeApi('messages.receivedMessages', {
max_id: this.getLocalMessageId(maxId)
max_id: this.getServerMessageId(maxId)
});
}
@ -4430,7 +4437,7 @@ export class AppMessagesManager { @@ -4430,7 +4437,7 @@ export class AppMessagesManager {
public sendScheduledMessages(peerId: number, mids: number[]) {
return apiManager.invokeApi('messages.sendScheduledMessages', {
peer: appPeersManager.getInputPeerById(peerId),
id: mids.map(mid => this.getLocalMessageId(mid))
id: mids.map(mid => this.getServerMessageId(mid))
}).then(updates => {
apiUpdatesManager.processUpdateMessage(updates);
});
@ -4439,7 +4446,7 @@ export class AppMessagesManager { @@ -4439,7 +4446,7 @@ export class AppMessagesManager {
public deleteScheduledMessages(peerId: number, mids: number[]) {
return apiManager.invokeApi('messages.deleteScheduledMessages', {
peer: appPeersManager.getInputPeerById(peerId),
id: mids.map(mid => this.getLocalMessageId(mid))
id: mids.map(mid => this.getServerMessageId(mid))
}).then(updates => {
apiUpdatesManager.processUpdateMessage(updates);
});
@ -4607,8 +4614,8 @@ export class AppMessagesManager { @@ -4607,8 +4614,8 @@ export class AppMessagesManager {
const options = {
peer: appPeersManager.getInputPeerById(peerId),
msg_id: this.getLocalMessageId(threadId) || 0,
offset_id: this.getLocalMessageId(maxId) || 0,
msg_id: this.getServerMessageId(threadId) || 0,
offset_id: this.getServerMessageId(maxId) || 0,
offset_date: offsetDate,
add_offset: offset,
limit,
@ -4690,7 +4697,7 @@ export class AppMessagesManager { @@ -4690,7 +4697,7 @@ export class AppMessagesManager {
const msgIds: InputMessage[] = mids.map((msgId: number) => {
return {
_: 'inputMessageID',
id: this.getLocalMessageId(msgId)
id: this.getServerMessageId(msgId)
};
});

6
src/lib/appManagers/appPollsManager.ts

@ -185,7 +185,7 @@ export class AppPollsManager { @@ -185,7 +185,7 @@ export class AppPollsManager {
return apiManager.invokeApi('messages.sendVote', {
peer: inputPeer,
msg_id: appMessagesManager.getLocalMessageId(message.mid),
msg_id: appMessagesManager.getServerMessageId(message.mid),
options
}).then(updates => {
this.log('sendVote updates:', updates);
@ -198,7 +198,7 @@ export class AppPollsManager { @@ -198,7 +198,7 @@ export class AppPollsManager {
return apiManager.invokeApi('messages.getPollResults', {
peer: inputPeer,
msg_id: appMessagesManager.getLocalMessageId(message.mid)
msg_id: appMessagesManager.getServerMessageId(message.mid)
}).then(updates => {
apiUpdatesManager.processUpdateMessage(updates);
this.log('getResults updates:', updates);
@ -208,7 +208,7 @@ export class AppPollsManager { @@ -208,7 +208,7 @@ export class AppPollsManager {
public getVotes(message: any, option?: Uint8Array, offset?: string, limit = 20) {
return apiManager.invokeApi('messages.getPollVotes', {
peer: appPeersManager.getInputPeerById(message.peerId),
id: appMessagesManager.getLocalMessageId(message.mid),
id: appMessagesManager.getServerMessageId(message.mid),
option,
offset,
limit

4
src/lib/richtextprocessor.ts

@ -584,10 +584,8 @@ namespace RichTextProcessor { @@ -584,10 +584,8 @@ namespace RichTextProcessor {
return '';
}
let entities = (options.entities || []).slice();
return wrapRichText(text, {
entities,
entities: options.entities,
noLinks: true,
wrappingDraft: true,
passEntities: {

5
src/lib/rootScope.ts

@ -82,7 +82,10 @@ type BroadcastEvents = { @@ -82,7 +82,10 @@ type BroadcastEvents = {
'draft_updated': {peerId: number, threadId: number, draft: MyDraftMessage | undefined},
'event-heavy-animation-start': void,
'event-heavy-animation-end': void
'event-heavy-animation-end': void,
'im_mount': void,
'im_tab_change': number
};
class RootScope extends EventListenerBase<any> {

4
src/pages/pageIm.ts

@ -9,6 +9,10 @@ let onFirstMount = () => { @@ -9,6 +9,10 @@ let onFirstMount = () => {
// ! TOO SLOW
/* appStateManager.saveState(); */
import('../lib/rootScope').then(m => {
m.default.broadcast('im_mount');
});
const promise = import('../lib/appManagers/appDialogsManager');
promise.finally(async() => {
//alert('pageIm!');

101
src/scss/partials/_chat.scss

@ -11,6 +11,7 @@ $chat-helper-size: 39px; @@ -11,6 +11,7 @@ $chat-helper-size: 39px;
.chat-input {
--translateY: 0;
--bottom: #{$chat-padding-handhelds};
display: flex;
width: 100%;
max-width: 100%;
@ -38,6 +39,14 @@ $chat-helper-size: 39px; @@ -38,6 +39,14 @@ $chat-helper-size: 39px;
max-width: var(--messages-container-width) !important;
}
@include respond-to(not-handhelds) {
--bottom: 21px;
}
@include respond-to(esg-bottom) {
--bottom: #{$chat-padding-handhelds};
}
@include respond-to(medium-screens) {
width: calc(100% - var(--right-column-width)) !important;
//transition: transform var(--layer-transition);
@ -69,19 +78,13 @@ $chat-helper-size: 39px; @@ -69,19 +78,13 @@ $chat-helper-size: 39px;
padding: 0 var(--padding-horizontal);
flex: 0 0 auto;
position: relative;
padding-bottom: var(--bottom);
@include respond-to(not-handhelds) {
--padding-horizontal: #{$chat-padding};
padding-bottom: 21px;
}
@include respond-to(handhelds) {
padding-bottom: $chat-padding-handhelds;
}
@include respond-to(esg-bottom) {
padding-bottom: $chat-padding-handhelds;
.btn-circle {
height: $chat-input-handhelds-size;
width: $chat-input-handhelds-size;
@ -394,9 +397,13 @@ $chat-helper-size: 39px; @@ -394,9 +397,13 @@ $chat-helper-size: 39px;
//max-width: 28.75rem;
}
.reply-wrapper {
/* .reply-wrapper {
transform: none !important;
border-radius: inherit;
} */
.reply-wrapper {
height: 0 !important;
}
.btn-send {
@ -627,7 +634,7 @@ $chat-helper-size: 39px; @@ -627,7 +634,7 @@ $chat-helper-size: 39px;
&.is-centering {
html:not(.is-safari) & {
transition: width .2s, border-bottom-right-radius .1s, transform .2s;
transition: width .2s, max-height .2s, border-bottom-right-radius .1s, transform .2s;
&:after {
transition: transform .1s;
@ -759,21 +766,28 @@ $chat-helper-size: 39px; @@ -759,21 +766,28 @@ $chat-helper-size: 39px;
.reply-wrapper {
justify-content: flex-start;
overflow: hidden;
transition: transform var(--layer-transition), border-radius var(--layer-transition);
/* transition: transform var(--layer-transition), border-radius var(--layer-transition);
position: absolute;
left: 0;
top: 0;
//height: calc(#{$chat-helper-size} + .3125rem);
height: 100%;
z-index: 1; */
height: 0;
width: calc(100% - var(--padding-horizontal) * 2);
padding: 0;
margin-top: .3125rem;//var(--padding-vertical);
margin-bottom: -.3125rem;
transition: height var(--layer-transition);
//height: calc(#{$chat-helper-size} + .3125rem);
align-items: flex-start;
z-index: 1;
user-select: none;
z-index: 2;
body.animation-level-0 & {
transition: none;
}
@include respond-to(handhelds) {
/* @include respond-to(handhelds) {
padding-top: .25rem;
}
@ -781,6 +795,10 @@ $chat-helper-size: 39px; @@ -781,6 +795,10 @@ $chat-helper-size: 39px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
transform: translateY(#{-$chat-helper-size});
} */
.chat.is-helper-active & {
height: 39px;
}
/* &.active {
@ -910,23 +928,14 @@ $chat-helper-size: 39px; @@ -910,23 +928,14 @@ $chat-helper-size: 39px;
color: $color-blue;
}
}
img.emoji {
height: 24px;
width: 24px;
}
}
.bubbles {
--translateY: 0;
/* overflow-y: scroll;
scrollbar-width: none;
-ms-overflow-style: none; */
width: 100%;
height: 100%;
max-height: 100%;
flex: 1 1 auto; /* Lets middle column shrink/grow to available width */
//overflow: hidden;
flex: 1 1 auto;
position: relative;
transform: translateY(var(--translateY));
@ -940,17 +949,20 @@ $chat-helper-size: 39px; @@ -940,17 +949,20 @@ $chat-helper-size: 39px;
-webkit-mask-image: -webkit-radial-gradient(circle, white 100%, black 100%); // fix safari overflow
} */
.chat.is-helper-active & {
&:not(.is-selecting), &.is-selecting.backwards {
--translateY: -#{$chat-helper-size};
.bubbles-inner {
transform: translateY(calc(var(--translateY) * -1));
//margin-top: $chat-helper-size;
//transition: none;
}
}
}
// .chat.is-helper-active & {
// &:not(.is-selecting), &.is-selecting.backwards {
// /* --translateY: -#{$chat-helper-size};
// .bubbles-inner {
// transform: translateY(calc(var(--translateY) * -1));
// //margin-top: $chat-helper-size;
// //transition: none;
// } */
// /* > .scrollable {
// margin-bottom: $chat-helper-size;
// } */
// }
// }
&.is-chat-input-hidden.is-selecting:not(.backwards) {
--translateY: -79px;
@ -976,23 +988,9 @@ $chat-helper-size: 39px; @@ -976,23 +988,9 @@ $chat-helper-size: 39px;
> .scrollable {
height: auto;
/* position: absolute;
bottom: 0;
left: 0; */
//position: relative; // неизвестно зачем это было
//display: flex; // for end
//flex-direction: unset;
display: block;
//transform: none;
/* display: flex;
flex-direction: column;
justify-content: flex-end; */
// * scrollbar takes some width, don't need to set padding for iOS
/* html.is-safari:not(.is-ios) & {
padding-left: 6px;
} */
/* margin-bottom: 0;
transition: margin-bottom var(--layer-transition) */
}
//}
@ -1144,7 +1142,8 @@ $chat-helper-size: 39px; @@ -1144,7 +1142,8 @@ $chat-helper-size: 39px;
align-items: center;
justify-content: center;
right: var(--chat-input-padding);
top: calc((var(--chat-input-size) * -1) - 6px);
//top: calc((var(--chat-input-size) * -1) - 6px);
bottom: calc(var(--chat-input-size) + var(--bottom) + 10px);
cursor: default;
opacity: 0;
z-index: 2;

3
src/scss/partials/_chatTopbar.scss

@ -8,12 +8,13 @@ @@ -8,12 +8,13 @@
max-height: 3.5rem;
// border-bottom: 1px solid #DADCE0;
@include respond-to(handhelds) {
&.is-pinned-floating {
&.is-pinned-audio-shown, &.is-pinned-message-shown:not(.hide-pinned) {
margin-bottom: 52px;
/* & + .bubbles {
margin-top: 52px;
} */
& ~ .drops-container {
--pinned-floating-height: 52px;
}

9
src/scss/partials/_input.scss

@ -59,12 +59,13 @@ @@ -59,12 +59,13 @@
&-input {
--padding: 1rem;
--padding-horizontal: 1rem;
--border-width: 1px;
--border-width-top: 2px;
border: var(--border-width) solid #DADCE0;
border-radius: $border-radius-medium;
//padding: 0 1rem;
padding: calc(var(--padding) - var(--border-width-top)) calc(var(--padding) - var(--border-width));
padding: calc(var(--padding) - var(--border-width-top)) calc(var(--padding-horizontal) - var(--border-width));
box-sizing: border-box;
width: 100%;
min-height: var(--height);
@ -75,6 +76,10 @@ @@ -75,6 +76,10 @@
/* overflow: hidden;
white-space: nowrap; */
@include respond-to(handhelds) {
--padding: .875rem;
}
body.animation-level-0 & {
transition: none;
}
@ -136,7 +141,7 @@ @@ -136,7 +141,7 @@
}
&:focus ~ label, &:valid ~ label, &:not(:empty) ~ label, &:disabled ~ label {
transform: translate(-.3125rem, calc(var(--height) / -2 + .125rem)) scale(.75);
transform: translate(-.25rem, calc(var(--height) / -2 + .125rem)) scale(.75);
padding: 0 6px;
opacity: 1;
}

8
src/scss/partials/_leftSidebar.scss

@ -107,6 +107,10 @@ @@ -107,6 +107,10 @@
.folders-tabs-scrollable .menu-horizontal-div-item:first-child {
margin-left: .6875rem;
@include respond-to(handhelds) {
margin-left: .1875rem;
}
}
.item-main {
@ -712,10 +716,6 @@ @@ -712,10 +716,6 @@
}
}
.sidebar-header .tgico-check1 {
color: #50a2e9;
}
.popup-forward, .included-chatlist-container {
.selector {
ul {

1
src/scss/partials/_slider.scss

@ -84,6 +84,7 @@ @@ -84,6 +84,7 @@
display: grid;
//grid-template-columns: 1fr;
grid-template-columns: 100%;
grid-template-rows: 100%;
/* @include respond-to(not-handhelds) {
overflow-x: hidden;

1
src/scss/partials/pages/_pages.scss

@ -33,6 +33,7 @@ @@ -33,6 +33,7 @@
> .scrollable {
display: flex;
flex-direction: column;
position: relative;
&:before, &:after {
content: " ";

Loading…
Cancel
Save