From cc8b18ccbe7312185094df8c220423f0ad3d4f5d Mon Sep 17 00:00:00 2001 From: morethanwords Date: Wed, 12 Jan 2022 22:17:34 +0400 Subject: [PATCH] Chat input control button --- src/components/chat/bubbles.ts | 15 +- src/components/chat/chat.ts | 6 +- src/components/chat/contextMenu.ts | 2 +- src/components/chat/input.ts | 161 +++++++++++++++---- src/components/chat/selection.ts | 55 +++---- src/lib/appManagers/appImManager.ts | 5 +- src/scss/partials/_chat.scss | 229 +++++++++++++++++++++------- 7 files changed, 339 insertions(+), 134 deletions(-) diff --git a/src/components/chat/bubbles.ts b/src/components/chat/bubbles.ts index 6a737c34..e7fc7e5f 100644 --- a/src/components/chat/bubbles.ts +++ b/src/components/chat/bubbles.ts @@ -479,7 +479,7 @@ export default class ChatBubbles { handleHorizontalSwipe({ element: this.bubblesContainer, verifyTouchTarget: (e) => { - if(this.chat.selection.isSelecting || !this.appMessagesManager.canSendToPeer(this.peerId, this.chat.threadId)) { + if(this.chat.selection.isSelecting || !this.chat.canSend()) { return false; } @@ -551,7 +551,7 @@ export default class ChatBubbles { if(!IS_MOBILE && this.chat.type !== 'pinned') { this.listenerSetter.add(this.bubblesContainer)('dblclick', (e) => { if(this.chat.selection.isSelecting || - !this.appMessagesManager.canSendToPeer(this.peerId, this.chat.threadId)) { + !this.chat.canSend()) { return; } @@ -645,11 +645,11 @@ export default class ChatBubbles { this.listenerSetter.add(rootScope)('chat_update', (chatId) => { if(this.peerId === chatId.toPeerId(true)) { const hadRights = this.chatInner.classList.contains('has-rights'); - const hasRights = this.appMessagesManager.canSendToPeer(this.peerId, this.chat.threadId); + const hasRights = this.chat.canSend(); if(hadRights !== hasRights) { this.finishPeerChange(); - this.chat.input.updateMessageInput(); + this.chat.input.finishPeerChange(); } } }); @@ -2258,9 +2258,8 @@ export default class ChatBubbles { } public finishPeerChange() { - const peerId = this.peerId; - const isChannel = this.appPeersManager.isChannel(peerId); - const canWrite = this.appMessagesManager.canSendToPeer(peerId, this.chat.threadId); + const isChannel = this.appPeersManager.isChannel(this.peerId); + const canWrite = this.chat.canSend(); this.chatInner.classList.toggle('has-rights', canWrite); this.bubblesContainer.classList.toggle('is-chat-input-hidden', !canWrite); @@ -3886,7 +3885,7 @@ export default class ChatBubbles { this.renderEmptyPlaceholder('noScheduledMessages', bubble, message, elements); } else if(rootScope.myId === this.peerId) { this.renderEmptyPlaceholder('saved', bubble, message, elements); - } else if(this.appPeersManager.isUser(this.peerId) && !isBot && this.appMessagesManager.canSendToPeer(this.peerId) && this.chat.type === 'chat') { + } else if(this.appPeersManager.isUser(this.peerId) && !isBot && this.chat.canSend() && this.chat.type === 'chat') { this.renderEmptyPlaceholder('greeting', bubble, message, elements); } else { this.renderEmptyPlaceholder('noMessages', bubble, message, elements); diff --git a/src/components/chat/chat.ts b/src/components/chat/chat.ts index 1ad73a4a..969b55ad 100644 --- a/src/components/chat/chat.ts +++ b/src/components/chat/chat.ts @@ -5,7 +5,7 @@ */ import type { AppNotificationsManager } from "../../lib/appManagers/appNotificationsManager"; -import type { AppChatsManager } from "../../lib/appManagers/appChatsManager"; +import type { AppChatsManager, ChatRights } from "../../lib/appManagers/appChatsManager"; import type { AppDocsManager } from "../../lib/appManagers/appDocsManager"; import type { AppImManager } from "../../lib/appManagers/appImManager"; import type { AppInlineBotsManager } from "../../lib/appManagers/appInlineBotsManager"; @@ -416,4 +416,8 @@ export default class Chat extends EventListenerBase<{ tab.open(this.peerId, this.threadId, this.bubbles.onDatePick, query); } } + + public canSend(action?: ChatRights) { + return this.appMessagesManager.canSendToPeer(this.peerId, this.threadId, action); + } } diff --git a/src/components/chat/contextMenu.ts b/src/components/chat/contextMenu.ts index af49a0c3..7c760db1 100644 --- a/src/components/chat/contextMenu.ts +++ b/src/components/chat/contextMenu.ts @@ -193,7 +193,7 @@ export default class ChatContextMenu { icon: 'reply', text: 'Reply', onClick: this.onReplyClick, - verify: () => this.appMessagesManager.canSendToPeer(this.peerId, this.chat.threadId) && + verify: () => this.chat.canSend() && !this.message.pFlags.is_outgoing && !!this.chat.input.messageInput && this.chat.type !== 'scheduled'/* , diff --git a/src/components/chat/input.ts b/src/components/chat/input.ts index 9abf95cd..5336defc 100644 --- a/src/components/chat/input.ts +++ b/src/components/chat/input.ts @@ -105,7 +105,7 @@ export default class ChatInput { private lastTimeType = 0; public chatInput: HTMLElement; - private inputContainer: HTMLElement; + public inputContainer: HTMLElement; public rowsWrapper: HTMLDivElement; private newMessageWrapper: HTMLDivElement; private btnToggleEmoticons: HTMLButtonElement; @@ -146,6 +146,7 @@ export default class ChatInput { private noWebPage: true; public scheduleDate: number; public sendSilent: true; + public startParam: string; private recorder: any; public recording = false; @@ -198,8 +199,17 @@ export default class ChatInput { private previousQuery: string; private releaseMediaPlayback: () => void; - botStartBtn: HTMLButtonElement; - fakeBotStartBtn: HTMLElement; + + private botStartBtn: HTMLButtonElement; + omgContainer: HTMLDivElement; + private fakeBotStartBtn: HTMLElement; + private rowsWrapperWrapper: HTMLDivElement; + private botStartContainer: HTMLElement; + fakeSelectionWrapper: HTMLDivElement; + + private fakeWrapperTo: HTMLElement; + + // private activeContainer: HTMLElement; constructor(private chat: Chat, private appMessagesManager: AppMessagesManager, @@ -227,19 +237,24 @@ export default class ChatInput { this.inputContainer = document.createElement('div'); this.inputContainer.classList.add('chat-input-container'); + this.rowsWrapperWrapper = document.createElement('div'); + this.rowsWrapperWrapper.classList.add('rows-wrapper-wrapper'); + this.rowsWrapper = document.createElement('div'); this.rowsWrapper.classList.add('rows-wrapper', 'chat-input-wrapper'); + this.rowsWrapperWrapper.append(this.rowsWrapper); + const tail = generateTail(); this.rowsWrapper.append(tail); const fakeRowsWrapper = this.fakeRowsWrapper = document.createElement('div'); fakeRowsWrapper.classList.add('fake-wrapper', 'fake-rows-wrapper'); - const fakeSelectionWrapper = document.createElement('div'); + const fakeSelectionWrapper = this.fakeSelectionWrapper = document.createElement('div'); fakeSelectionWrapper.classList.add('fake-wrapper', 'fake-selection-wrapper'); - this.inputContainer.append(this.rowsWrapper, fakeRowsWrapper, fakeSelectionWrapper); + this.inputContainer.append(this.rowsWrapperWrapper, fakeRowsWrapper, fakeSelectionWrapper); this.chatInput.append(this.inputContainer); this.goDownBtn = ButtonCorner({icon: 'arrow_down', className: 'bubbles-corner-button bubbles-go-down hide'}); @@ -510,7 +525,7 @@ export default class ChatInput { this.willAttachType = 'media'; this.fileInput.click(); }, - verify: (peerId, threadId) => this.appMessagesManager.canSendToPeer(peerId, threadId, 'send_media') + verify: () => this.chat.canSend('send_media') }, { icon: 'document', text: 'Chat.Input.Attach.Document', @@ -520,14 +535,14 @@ export default class ChatInput { this.willAttachType = 'document'; this.fileInput.click(); }, - verify: (peerId, threadId) => this.appMessagesManager.canSendToPeer(peerId, threadId, 'send_media') + verify: () => this.chat.canSend('send_media') }, { icon: 'poll', text: 'Poll', onClick: () => { new PopupCreatePoll(this.chat).show(); }, - verify: (peerId, threadId) => peerId.isAnyChat() && this.appMessagesManager.canSendToPeer(peerId, threadId, 'send_polls') + verify: (peerId) => peerId.isAnyChat() && this.chat.canSend('send_polls') }]; this.attachMenu = ButtonMenuToggle({noRipple: true, listenerSetter: this.listenerSetter}, 'top-left', this.attachMenuButtons); @@ -776,35 +791,26 @@ export default class ChatInput { this.saveDraftDebounced = debounce(() => this.saveDraft(), 2500, false, true); - /* this.constructCenteredContainer((container, fakeContainer) => { - this.botStartBtn = Button('btn-primary btn-transparent text-bold'); - container.append(this.botStartBtn); + this.botStartBtn = Button('btn-primary btn-transparent text-bold chat-input-control-button'); + this.botStartBtn.append(i18n('BotStart')); - this.fakeBotStartBtn = this.botStartBtn.cloneNode(true) as HTMLElement; - fakeContainer.append(this.fakeBotStartBtn); + const c = this.botStartContainer = document.createElement('div'); + c.classList.add('chat-input-control', 'chat-input-wrapper'); + c.append(this.botStartBtn); + this.inputContainer.append(c); - this.botStartBtn.append(i18n('BotStart')); - this.fakeBotStartBtn.append(i18n('BotStart')); - }); */ + // this.botStartContainer.classList.add('hide'); + // this.startParam = '123'; } - private constructCenteredContainer(fill: (container: HTMLElement, fakeContainer: HTMLElement) => void) { + private constructPinnedContainer() { const container = document.createElement('div'); - container.classList.add('input-centered-container', 'rows-wrapper', 'is-centered', 'chat-input-wrapper'); - - const fakeContainer = container.cloneNode(true) as HTMLElement; - fakeContainer.classList.add('fake-wrapper', 'fake-input-centered-container'); - - fill(container, fakeContainer); - - this.inputContainer.append(container, fakeContainer); - + container.classList.add('pinned-container'); return container; } public constructPinnedHelpers() { - const container = document.createElement('div'); - container.classList.add('pinned-container'); + const container = this.constructPinnedContainer(); this.pinnedControlBtn = Button('btn-primary btn-transparent text-bold pinned-container-button', {icon: 'unpin'}); container.append(this.pinnedControlBtn); @@ -833,6 +839,95 @@ export default class ChatInput { this.rowsWrapper.classList.add('is-centered'); } + public center() { + const neededFakeContainer = this.getNeededFakeContainer(); + if(!neededFakeContainer && !this.inputContainer.classList.contains('is-centering')) { + return; + } + + /* if(neededFakeContainer === this.botStartContainer && this.fakeWrapperTo === this.fakeSelectionWrapper) { + this.inputContainer.classList.remove('is-centering'); + void this.rowsWrapper.offsetLeft; // reflow + // this.inputContainer.classList.add('is-centering'); + // void this.rowsWrapper.offsetLeft; // reflow + } */ + + const fakeSelectionWrapper = neededFakeContainer || this.fakeWrapperTo; + const forwards = !!neededFakeContainer; + const oldFakeWrapperTo = this.fakeWrapperTo; + let transform = '', borderRadius = '', needTranslateX: number; + // if(forwards) {] + const fakeSelectionRect = fakeSelectionWrapper.getBoundingClientRect(); + const fakeRowsRect = this.fakeRowsWrapper.getBoundingClientRect(); + const widthFrom = fakeRowsRect.width; + const widthTo = fakeSelectionRect.width; + + if(widthFrom !== widthTo) { + const scale = (widthTo/* - 8 */) / widthFrom; + const initTranslateX = (widthFrom - widthTo) / 2; + needTranslateX = fakeSelectionRect.left - fakeRowsRect.left - initTranslateX; + + if(forwards) { + transform = `translateX(${needTranslateX}px) scaleX(${scale})`; + // transform = `translateX(0px) scaleX(${scale})`; + + if(scale < 1) { + const br = 12; + borderRadius = '' + (br + br * (1 - scale)) + 'px'; + } + } + //scale = widthTo / widthFrom; + } + // } + + this.fakeWrapperTo = neededFakeContainer; + + const duration = 200; + SetTransition(this.inputContainer, 'is-centering', forwards, duration); + SetTransition(this.rowsWrapperWrapper, 'is-centering-to-control', !!(forwards && neededFakeContainer && neededFakeContainer.classList.contains('chat-input-control')), duration); + this.rowsWrapper.style.transform = transform; + this.rowsWrapper.style.borderRadius = borderRadius; + + return { + transform, + borderRadius, + needTranslateX: oldFakeWrapperTo && ( + ( + neededFakeContainer && + neededFakeContainer.classList.contains('chat-input-control') && + oldFakeWrapperTo === this.fakeSelectionWrapper + ) || oldFakeWrapperTo.classList.contains('chat-input-control') + ) ? needTranslateX * -.5 : needTranslateX, + widthFrom, + widthTo + }; + } + + public getNeededFakeContainer() { + if(this.chat.selection.isSelecting) { + return this.fakeSelectionWrapper; + } else if(this.startParam || !this.chat.canSend()) { + return this.botStartContainer; + } + } + + // public getActiveContainer() { + // if(this.chat.selection.isSelecting) { + // return this.chat + // } + // return this.startParam !== undefined ? this.botStartContainer : this.rowsWrapper; + // } + + // public setActiveContainer() { + // const container = this.activeContainer; + // const newContainer = this.getActiveContainer(); + // if(newContainer === container) { + // return; + // } + + + // } + private onCancelRecordClick = (e?: Event) => { if(e) { cancelEvent(e); @@ -1030,6 +1125,8 @@ export default class ChatInput { sendMenu.setPeerId(peerId); } + this.center(); + if(this.messageInput) { this.updateMessageInput(); } else if(this.pinnedControlBtn) { @@ -1046,7 +1143,7 @@ export default class ChatInput { public updateMessageInput() { const {chatInput, attachMenu, messageInput} = this; const {peerId, threadId} = this.chat; - const canWrite = this.appMessagesManager.canSendToPeer(peerId, threadId); + const canWrite = this.chat.canSend(); chatInput.classList.add('no-transition'); chatInput.classList.toggle('is-hidden', !canWrite); void chatInput.offsetLeft; // reflow @@ -1589,7 +1686,7 @@ export default class ChatInput { if(this.stickersHelper && rootScope.settings.stickers.suggest && - this.appMessagesManager.canSendToPeer(this.chat.peerId, this.chat.threadId, 'send_stickers') && + this.chat.canSend('send_stickers') && entity?._ === 'messageEntityEmoji' && entity.length === value.length && !entity.offset) { foundHelper = this.stickersHelper; this.stickersHelper.checkEmoticon(value); @@ -1675,7 +1772,7 @@ export default class ChatInput { this.sendMessage(); } } else { - if(this.chat.peerId.isAnyChat() && !this.appMessagesManager.canSendToPeer(this.chat.peerId, this.chat.threadId, 'send_media')) { + if(this.chat.peerId.isAnyChat() && !this.chat.canSend('send_media')) { toast(POSTING_MEDIA_NOT_ALLOWED); return; } @@ -2031,7 +2128,7 @@ export default class ChatInput { document = this.appDocsManager.getDoc(document); const flag = document.type === 'sticker' ? 'send_stickers' : (document.type === 'gif' ? 'send_gifs' : 'send_media'); - if(this.chat.peerId.isAnyChat() && !this.appMessagesManager.canSendToPeer(this.chat.peerId, this.chat.threadId, flag)) { + if(this.chat.peerId.isAnyChat() && !this.chat.canSend(flag)) { toast(POSTING_MEDIA_NOT_ALLOWED); return false; } diff --git a/src/components/chat/selection.ts b/src/components/chat/selection.ts index 84c2831e..c8386c25 100644 --- a/src/components/chat/selection.ts +++ b/src/components/chat/selection.ts @@ -819,36 +819,8 @@ export default class ChatSelection extends AppSelection { } protected onToggleSelection = (forwards: boolean) => { - let transform = '', borderRadius = '', needTranslateX: number; - // if(forwards) { - const p = this.input.rowsWrapper.parentElement; - const fakeSelectionWrapper = p.querySelector('.fake-selection-wrapper'); - const fakeRowsWrapper = p.querySelector('.fake-rows-wrapper'); - const fakeSelectionRect = fakeSelectionWrapper.getBoundingClientRect(); - const fakeRowsRect = fakeRowsWrapper.getBoundingClientRect(); - const widthFrom = fakeRowsRect.width; - const widthTo = fakeSelectionRect.width; - - if(widthFrom !== widthTo) { - const scale = (widthTo/* - 8 */) / widthFrom; - const initTranslateX = (widthFrom - widthTo) / 2; - needTranslateX = fakeSelectionRect.left - fakeRowsRect.left - initTranslateX; - - if(forwards) { - transform = `translateX(${needTranslateX}px) scaleX(${scale})`; - - if(scale < 1) { - const br = 12; - borderRadius = '' + (br + br * (1 - scale)) + 'px'; - } - } - //scale = widthTo / widthFrom; - } - // } + const {needTranslateX, widthFrom, widthTo} = this.chat.input.center(); - SetTransition(this.input.rowsWrapper, 'is-centering', forwards, 200); - this.input.rowsWrapper.style.transform = transform; - this.input.rowsWrapper.style.borderRadius = borderRadius; SetTransition(this.listenElement, 'is-selecting', forwards, 200, () => { if(!this.isSelecting) { this.selectionInputWrapper.remove(); @@ -870,11 +842,15 @@ export default class ChatSelection extends AppSelection { //const chatInput = this.appImManager.chatInput; + const translateButtonsX = widthFrom < widthTo ? undefined : needTranslateX * 2; if(this.isSelecting) { if(!this.selectionContainer) { this.selectionInputWrapper = document.createElement('div'); this.selectionInputWrapper.classList.add('chat-input-wrapper', 'selection-wrapper'); + // const background = document.createElement('div'); + // background.classList.add('chat-input-wrapper-background'); + this.selectionContainer = document.createElement('div'); this.selectionContainer.classList.add('selection-container'); @@ -928,22 +904,27 @@ export default class ChatSelection extends AppSelection { this.selectionDeleteBtn ].filter(Boolean)) - left.style.transform = `translateX(-${needTranslateX * 2}px)`; - right.style.transform = `translateX(${needTranslateX * 2}px)`; + if(translateButtonsX !== undefined) { + left.style.transform = `translateX(${-translateButtonsX}px)`; + right.style.transform = `translateX(${translateButtonsX}px)`; + } + this.selectionContainer.append(left, right); + // background.style.opacity = '0'; this.selectionInputWrapper.style.opacity = '0'; - this.selectionInputWrapper.append(this.selectionContainer); - this.input.rowsWrapper.parentElement.append(this.selectionInputWrapper); - + this.selectionInputWrapper.append(/* background, */this.selectionContainer); + this.input.inputContainer.append(this.selectionInputWrapper); + void this.selectionInputWrapper.offsetLeft; // reflow + // background.style.opacity = ''; this.selectionInputWrapper.style.opacity = ''; left.style.transform = ''; right.style.transform = ''; } - } else if(this.selectionLeft) { - this.selectionLeft.style.transform = `translateX(-${needTranslateX * 2}px)`; - this.selectionRight.style.transform = `translateX(${needTranslateX * 2}px)`; + } else if(this.selectionLeft && translateButtonsX !== undefined) { + this.selectionLeft.style.transform = `translateX(-${translateButtonsX}px)`; + this.selectionRight.style.transform = `translateX(${translateButtonsX}px)`; } }; diff --git a/src/lib/appManagers/appImManager.ts b/src/lib/appManagers/appImManager.ts index 75ad6b68..56aa12a1 100644 --- a/src/lib/appManagers/appImManager.ts +++ b/src/lib/appManagers/appImManager.ts @@ -1199,8 +1199,9 @@ export class AppImManager { } private canDrag() { - const peerId = this.chat?.peerId; - return !(!peerId || rootScope.isOverlayActive || !appMessagesManager.canSendToPeer(peerId, this.chat.threadId, 'send_media')); + const chat = this.chat; + const peerId = chat?.peerId; + return !(!peerId || rootScope.isOverlayActive || !chat.canSend('send_media')); } private onDocumentPaste = (e: ClipboardEvent | DragEvent, attachType?: 'media' | 'document') => { diff --git a/src/scss/partials/_chat.scss b/src/scss/partials/_chat.scss index 24e921aa..b60fcfac 100644 --- a/src/scss/partials/_chat.scss +++ b/src/scss/partials/_chat.scss @@ -7,6 +7,11 @@ $btn-send-margin: .5rem; $chat-helper-size: 36px; +$input-transition-time: .2s; +$input-half-transition-time: #{$input-transition-time / 2}; +$background-transition-time: 0.05s; +$background-transition-total-time: #{$input-transition-time - $background-transition-time}; + /* #bubble-contextmenu > div { padding: 0 5.25 0 1rem; @@ -79,7 +84,8 @@ $chat-helper-size: 36px; --padding-horizontal: var(--chat-input-padding); display: flex; align-items: flex-end; - justify-content: space-between; + justify-content: center; + // justify-content: space-between; max-width: var(--messages-container-width); margin: 0 auto; width: 100%; @@ -92,6 +98,40 @@ $chat-helper-size: 36px; width: var(--chat-input-size); height: var(--chat-input-size); } + + &.is-centering { + .new-message-wrapper { + pointer-events: none; + } + } + + &.is-centering:not(.backwards) { + .new-message-wrapper, .pinned-container { + opacity: 0; + } + + .rows-wrapper { + max-height: var(--chat-input-size); + // opacity: 0; + // transition: transform .2s, width .2s, max-height .2s, border-radius .1s, opacity 0s .2s; + //box-shadow: none; + + &:before { + opacity: 0; + transition: opacity $background-transition-time $background-transition-total-time; + } + } + + .reply-wrapper { + height: 0 !important; + opacity: 0; + pointer-events: none; + } + + .btn-send { + transform: scale(0); + } + } } /* @include respond-to(handhelds) { @@ -136,7 +176,7 @@ $chat-helper-size: 36px; } @include animation-level(2) { - transition: height .1s; + transition: height $input-half-transition-time; } @media only screen and (max-height: 30rem) { @@ -171,7 +211,7 @@ $chat-helper-size: 36px; .btn-record-cancel { visibility: hidden; opacity: 0; - transition: visibility 0s .1s, opacity .1s 0s; + transition: visibility 0s $input-half-transition-time, opacity $input-half-transition-time 0s; padding: 0; z-index: 3; position: absolute; @@ -346,10 +386,10 @@ $chat-helper-size: 36px; position: absolute; top: -94px; left: -94px; - transition: transform .03s ease-in-out, visibility .1s; + transition: transform .03s ease-in-out, visibility $input-half-transition-time; visibility: hidden; - body.animation-level-0 & { + @include animation-level(0) { transition: none !important; } @@ -377,7 +417,7 @@ $chat-helper-size: 36px; .btn-record-cancel { opacity: 1; visibility: visible; - transition: visibility 0s .1s, opacity .1s .1s; + transition: visibility 0s $input-half-transition-time, opacity $input-half-transition-time $input-half-transition-time; } // unlock @@ -387,6 +427,7 @@ $chat-helper-size: 36px; .rows-wrapper { width: calc(100% - (var(--chat-input-size) * 2 + #{$btn-send-margin * 2})); + // transform: translateX(calc((var(--chat-input-size) + 0.5rem) / -1)) scaleX(1); } .attach-file { @@ -414,7 +455,7 @@ $chat-helper-size: 36px; opacity: 1; @include animation-level(2) { - transition: opacity .1s 0s; + transition: opacity $input-half-transition-time 0s; } } @@ -432,45 +473,40 @@ $chat-helper-size: 36px; } } - .bubbles.is-selecting ~ & { - .new-message-wrapper { - pointer-events: none; - } - } - - .bubbles.is-selecting:not(.backwards) ~ & { - .new-message-wrapper, .pinned-container { - opacity: 0; - } + .bubbles.is-selecting:not(.backwards) ~ & { + .selection-wrapper { + opacity: 1; - .selection-wrapper { - opacity: 1; - } - - .rows-wrapper { - max-height: var(--chat-input-size); - //box-shadow: none; - } + .chat-input-wrapper-background { + // visibility: visible; + // transition: visibility 0s 3s; + opacity: 1; + transition: opacity $background-transition-time $background-transition-total-time; + } + } - .reply-wrapper { - height: 0 !important; - opacity: 0; - pointer-events: none; - } + .rows-wrapper { + &:before { + opacity: 1; + transition: opacity 0s 0s; + } + } + } - .btn-send { - transform: scale(0); - } - } + /* .bubbles.is-selecting:not(.backwards):not(.animating) ~ & { + .selection-wrapper:before { + visibility: visible; + } + } */ .bubbles.is-selecting.backwards ~ & { @include animation-level(2) { .new-message-wrapper, .pinned-container { - transition: opacity .1s .1s; + transition: opacity $input-half-transition-time $input-half-transition-time; } .selection-wrapper { - transition: opacity .1s 0s; + transition: opacity $input-half-transition-time 0s; } } } @@ -715,27 +751,63 @@ $chat-helper-size: 36px; width: calc(100% - (var(--chat-input-size) + #{$btn-send-margin})); max-width: calc(100% - (var(--chat-input-size) + #{$btn-send-margin})); justify-content: center; - background-color: var(--surface-color); + // background-color: var(--surface-color); border-radius: 12px; border-bottom-right-radius: 0; //box-shadow: 0 1px 2px 0 rgba(16, 35, 47, .07); - box-shadow: 0px 1px 8px 1px rgba(0, 0, 0, .18); + // box-shadow: 0px 1px 8px 1px rgba(0, 0, 0, .18); min-height: var(--chat-input-size); max-height: 30rem; flex: 0 0 auto; position: relative; z-index: 3; - transition: width .1s; + transition: width $input-half-transition-time; + + &:before, + .chat-input-wrapper-background { + content: " "; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: inherit; + box-shadow: 0px 1px 8px 1px rgb(0 0 0 / 18%); + background-color: #fff; + background-color: var(--surface-color); + opacity: 1; + transition: opacity $background-transition-time 0s; + + @include animation-level(0) { + transition: none !important; + } + } - body.animation-level-0 & { - transition: none; - } + @include animation-level(0) { + transition: none !important; + } } -.input-centered-container { +.chat-input-control { + --padding-vertical: .3125rem; + --padding-horizontal: var(--chat-input-inner-padding); + --padding: var(--padding-vertical) var(--padding-horizontal); position: absolute; margin: 0 auto; width: auto; + height: var(--chat-input-size); + padding: var(--padding); + background-color: var(--surface-color); + border-radius: $border-radius-big; + z-index: 3; + + &:before { + opacity: 0; + } +} + +.chat-input-control-button { + height: 100%; } .selection-wrapper, .fake-selection-wrapper { @@ -747,12 +819,32 @@ $chat-helper-size: 36px; max-width: calc(100% - (var(--chat-input-padding) * 2)); } +.selection-wrapper, +.chat-input-control { + transition: opacity $input-half-transition-time .075s; + opacity: 0; + + @include animation-level(0) { + transition: none !important; + } +} + .selection-wrapper { border-radius: $border-radius-big; - //z-index: 2; - box-shadow: none; - transition: opacity .1s .075s; - opacity: 0; + // z-index: 2; + // box-shadow: none; + background-color: var(--surface-color); + + &:before { + content: none; + } + + // .chat-input-wrapper-background { + // transition: visibility 0s 3s; + // opacity: 0; + // transition: opacity 0s 3s; + // box-shadow: 0px 1px 8px 1px rgb(0 0 0); + // } .selection-container { display: flex; @@ -775,7 +867,7 @@ $chat-helper-size: 36px; @include animation-level(2) { transform: translateX(0); - transition: transform .2s; + transition: transform $input-transition-time; } } @@ -868,12 +960,40 @@ $chat-helper-size: 36px; } } +.rows-wrapper-wrapper { + width: 100%; + display: flex; + + &.is-centering-to-control:not(.backwards) ~ .chat-input-control { + opacity: 1; + + &:before { + opacity: 1; + transition: opacity $background-transition-time $background-transition-total-time; + } + } + + &.is-centering-to-control.backwards ~ .chat-input-control { + transition: opacity $input-half-transition-time 0s; + } +} + .rows-wrapper { - transform: scaleX(1); - transition: transform .2s, width .2s, max-height .2s, border-radius .1s; + transform: scaleX(1); + // transform: translateX(calc((var(--chat-input-size) + 0.5rem) / -2)) scaleX(1); + transition: transform $input-transition-time, width $input-transition-time, max-height $input-transition-time, border-radius $input-half-transition-time/* , opacity 0s 0s */; + // background-color: transparent; + // opacity: 1; + // box-shadow: none; + + @include animation-level(0) { + transition: none !important; + } &.is-centered { margin: 0 auto; + // width: 100%; + // max-width: 100%; & ~ .fake-rows-wrapper { left: 50%; @@ -882,18 +1002,21 @@ $chat-helper-size: 36px; } .bubble-tail { - transition: transform .1s; + opacity: 1; + transition: transform $input-half-transition-time, opacity .025s 0s; @include animation-level(0) { - transition: none; + transition: none !important; } } - &.is-centering:not(.backwards), &.is-centered { + .chat-input-container.is-centering:not(.backwards) &, &.is-centered { border-bottom-right-radius: 12px; .bubble-tail { + transition: transform $input-half-transition-time, opacity .025s .075s; transform: scaleX(-1) translateX(#{.5625rem * 2}); + opacity: 0; } }