From ef884b5b8c2071d45163405aac68c2a5853974f3 Mon Sep 17 00:00:00 2001 From: morethanwords Date: Sun, 3 Jan 2021 19:59:13 +0400 Subject: [PATCH] Animations toggle --- src/components/appMediaViewer.ts | 4 +- src/components/appSearchSuper..ts | 2 +- src/components/appSelectPeers.ts | 11 ++- src/components/chat/bubbles.ts | 32 ++++---- src/components/chat/input.ts | 8 +- .../emoticonsDropdown/tabs/emoji.ts | 5 +- src/components/horizontalMenu.ts | 5 ++ src/components/inputField.ts | 7 ++ src/components/ripple.ts | 8 ++ src/components/scrollable.ts | 6 ++ src/components/sidebarRight/index.ts | 3 +- src/components/singleTransition.ts | 22 ++++-- src/components/transition.ts | 9 ++- src/helpers/dom.ts | 11 +-- src/lib/appManagers/appImManager.ts | 22 +++--- src/lib/richtextprocessor.ts | 3 + src/scss/partials/_button.scss | 12 +++ src/scss/partials/_chat.scss | 77 +++++++++++++++---- src/scss/partials/_chatBubble.scss | 57 ++++++++++---- src/scss/partials/_chatMarkupTooltip.scss | 12 +++ src/scss/partials/_chatPinned.scss | 23 +++++- src/scss/partials/_checkbox.scss | 28 +++++-- src/scss/partials/_emojiDropdown.scss | 4 + src/scss/partials/_input.scss | 36 +++++++-- src/scss/partials/_leftSidebar.scss | 12 +++ src/scss/partials/_mediaViewer.scss | 39 +++++----- src/scss/partials/_selector.scss | 26 +++++-- src/scss/partials/_slider.scss | 49 +++++------- src/scss/partials/popups/_createPoll.scss | 6 +- src/scss/partials/popups/_popup.scss | 22 +++++- src/scss/style.scss | 5 ++ 31 files changed, 415 insertions(+), 151 deletions(-) diff --git a/src/components/appMediaViewer.ts b/src/components/appMediaViewer.ts index 5365ae25..767dddde 100644 --- a/src/components/appMediaViewer.ts +++ b/src/components/appMediaViewer.ts @@ -324,7 +324,7 @@ class AppMediaViewerBase { const diff = Date.now() - start; - let progress = diff / delay; + let progress = delay ? diff / delay : 1; if(progress > 1) progress = 1; if(upscale) progress = 1 - progress; diff --git a/src/components/appSearchSuper..ts b/src/components/appSearchSuper..ts index fb6fc3ae..57ab141e 100644 --- a/src/components/appSearchSuper..ts +++ b/src/components/appSearchSuper..ts @@ -417,7 +417,7 @@ export default class AppSearchSuper { div.append(thumb); } - const needBlur = !isDownloaded || !willHaveThumb; + const needBlur = (!isDownloaded || !willHaveThumb) && rootScope.settings.animationsEnabled; const img = new Image(); img.dataset.mid = '' + message.mid; img.classList.add('grid-item-media'); diff --git a/src/components/appSelectPeers.ts b/src/components/appSelectPeers.ts index 28a75049..8ca6a7fa 100644 --- a/src/components/appSelectPeers.ts +++ b/src/components/appSelectPeers.ts @@ -393,11 +393,18 @@ export default class AppSelectPeers { div.classList.remove('scale-in'); void div.offsetWidth; div.classList.add('scale-out'); - div.addEventListener('animationend', () => { + + const onAnimationEnd = () => { this.selected.delete(key); div.remove(); this.onChange && this.onChange(this.selected.size); - }, {once: true}); + }; + + if(rootScope.settings.animationsEnabled) { + div.addEventListener('animationend', onAnimationEnd, {once: true}); + } else { + onAnimationEnd(); + } } public getSelected() { diff --git a/src/components/chat/bubbles.ts b/src/components/chat/bubbles.ts index 22f533f3..641401ae 100644 --- a/src/components/chat/bubbles.ts +++ b/src/components/chat/bubbles.ts @@ -2512,22 +2512,24 @@ export default class ChatBubbles { if(isFirstMessageRender) { waitPromise.then(() => { - const mids = getObjectKeysAndSort(this.bubbles, 'desc').filter(mid => !additionMsgIds.includes(mid)); - mids.forEach((mid, idx) => { - const bubble = this.bubbles[mid]; + if(rootScope.settings.animationsEnabled) { + const mids = getObjectKeysAndSort(this.bubbles, 'desc').filter(mid => !additionMsgIds.includes(mid)); + mids.forEach((mid, idx) => { + const bubble = this.bubbles[mid]; + + //if(idx || isSafari) { + // ! 0.1 = 1ms задержка для Safari, без этого первое сообщение над самым нижним может появиться позже другого с animation-delay, LOL ! + bubble.style.animationDelay = ((idx || 0.1) * 10) + 'ms'; + //} - //if(idx || isSafari) { - // ! 0.1 = 1ms задержка для Safari, без этого первое сообщение над самым нижним может появиться позже другого с animation-delay, LOL ! - bubble.style.animationDelay = ((idx || 0.1) * 10) + 'ms'; - //} - - bubble.classList.add('zoom-fade'); - bubble.addEventListener('animationend', () => { - bubble.style.animationDelay = ''; - bubble.classList.remove('zoom-fade'); - }, {once: true}); - //this.log('supa', bubble); - }); + bubble.classList.add('zoom-fade'); + bubble.addEventListener('animationend', () => { + bubble.style.animationDelay = ''; + bubble.classList.remove('zoom-fade'); + }, {once: true}); + //this.log('supa', bubble); + }); + } setTimeout(() => { this.loadMoreHistory(true, true); diff --git a/src/components/chat/input.ts b/src/components/chat/input.ts index 0f2d6bfa..2ba9fc26 100644 --- a/src/components/chat/input.ts +++ b/src/components/chat/input.ts @@ -11,7 +11,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, serializeNodes } from "../../helpers/dom"; +import { attachClickEvent, blurActiveElement, cancelEvent, cancelSelection, findUpClassName, getRichValue, getSelectedNodes, isInputEmpty, markdownTags, MarkdownType, placeCaretAtEnd } from "../../helpers/dom"; import { ButtonMenuItemOptions } from '../buttonMenu'; import emoticonsDropdown from "../emoticonsDropdown"; import PopupCreatePoll from "../popups/createPoll"; @@ -393,7 +393,7 @@ export default class ChatInput { const container = document.createElement('div'); container.classList.add('pinned-container'); - this.pinnedControlBtn = Button('btn-primary btn-transparent pinned-container-button', {icon: 'unpin'}); + this.pinnedControlBtn = Button('btn-primary btn-transparent text-bold pinned-container-button', {icon: 'unpin'}); container.append(this.pinnedControlBtn); this.listenerSetter.add(this.pinnedControlBtn, 'click', () => { @@ -883,9 +883,7 @@ export default class ChatInput { } } - if(!richValue.trim() && !serializeNodes(Array.from(this.messageInput.childNodes)).trim()) { - this.messageInput.innerHTML = ''; - + if(this.isInputEmpty()) { this.appMessagesManager.setTyping(this.chat.peerId, 'sendMessageCancelAction'); } else { const time = Date.now(); diff --git a/src/components/emoticonsDropdown/tabs/emoji.ts b/src/components/emoticonsDropdown/tabs/emoji.ts index 9799c4ee..c1971f70 100644 --- a/src/components/emoticonsDropdown/tabs/emoji.ts +++ b/src/components/emoticonsDropdown/tabs/emoji.ts @@ -159,7 +159,7 @@ export default class EmojiTab implements EmoticonsTab { spanEmoji.append(first); } - if(spanEmoji.firstElementChild) { + if(spanEmoji.firstElementChild && !RichTextProcessor.emojiSupported) { (spanEmoji.firstElementChild as HTMLImageElement).setAttribute('loading', 'lazy'); } @@ -186,8 +186,7 @@ export default class EmojiTab implements EmoticonsTab { } else if(target.tagName == 'DIV') return; //console.log('contentEmoji div', target); - - appImManager.chat.input.messageInput.innerHTML += target.outerHTML; + appImManager.chat.input.messageInput.innerHTML += RichTextProcessor.emojiSupported ? target.innerHTML : target.outerHTML; // Recent const emoji = this.getEmojiFromElement(target); diff --git a/src/components/horizontalMenu.ts b/src/components/horizontalMenu.ts index 5f4af41b..ff79c115 100644 --- a/src/components/horizontalMenu.ts +++ b/src/components/horizontalMenu.ts @@ -1,6 +1,7 @@ import { findUpTag, whichChild } from "../helpers/dom"; import { TransitionSlider } from "./transition"; import { ScrollableX } from "./scrollable"; +import rootScope from "../lib/rootScope"; export function horizontalMenu(tabs: HTMLElement, content: HTMLElement, onClick?: (id: number, tabContent: HTMLDivElement) => void, onTransitionEnd?: () => void, transitionTime = 250, scrollableX?: ScrollableX) { const selectTab = TransitionSlider(content, tabs || content.dataset.slider == 'tabs' ? 'tabs' : 'navigation', transitionTime, onTransitionEnd); @@ -25,6 +26,10 @@ export function horizontalMenu(tabs: HTMLElement, content: HTMLElement, onClick? scrollableX.scrollIntoView(target.parentElement.children[id] as HTMLElement, true, transitionTime); } + if(!rootScope.settings.animationsEnabled) { + animate = false; + } + if(target.classList.contains('active') || id === selectTab.prevId) { return false; } diff --git a/src/components/inputField.ts b/src/components/inputField.ts index 8a4d9207..b2aed838 100644 --- a/src/components/inputField.ts +++ b/src/components/inputField.ts @@ -92,6 +92,13 @@ class InputField { processInput(); } }); + + // * because if delete all characters there will br left + input.addEventListener('input', () => { + if(!this.value.trim()) { + input.innerHTML = ''; + } + }); // ! childList for paste first symbol observer.observe(input, {characterData: true, childList: true, subtree: true}); diff --git a/src/components/ripple.ts b/src/components/ripple.ts index e414c33d..f82d50ef 100644 --- a/src/components/ripple.ts +++ b/src/components/ripple.ts @@ -1,5 +1,6 @@ import {isTouchSupported} from "../helpers/touchSupport"; import { findUpClassName } from "../helpers/dom"; +import rootScope from "../lib/rootScope"; let rippleClickId = 0; export function ripple(elem: HTMLElement, callback: (id: number) => Promise = () => Promise.resolve(), onEnd: (id: number) => void = null) { @@ -139,6 +140,10 @@ export function ripple(elem: HTMLElement, callback: (id: number) => Promise { + if(!rootScope.settings.animationsEnabled) { + return; + } + //console.log('ripple touchstart', e); if(e.touches.length > 1 || touchStartFired @@ -163,6 +168,9 @@ export function ripple(elem: HTMLElement, callback: (id: number) => Promise { + if(!rootScope.settings.animationsEnabled) { + return; + } //console.log('ripple mousedown', e, e.target, findUpClassName(e.target as HTMLElement, 'c-ripple') == r); if(elem.dataset.ripple == '0' || findUpClassName(e.target as HTMLElement, 'c-ripple') != r) { diff --git a/src/components/scrollable.ts b/src/components/scrollable.ts index f9461971..f6bdf888 100644 --- a/src/components/scrollable.ts +++ b/src/components/scrollable.ts @@ -2,6 +2,7 @@ import { CancellablePromise, deferredPromise } from "../helpers/cancellablePromi import { isTouchSupported } from "../helpers/touchSupport"; import { logger, LogLevels } from "../lib/logger"; import smoothscroll, { SCROLL_TIME, SmoothScrollToOptions } from '../vendor/smoothscroll'; +import rootScope from "../lib/rootScope"; (window as any).__forceSmoothScrollPolyfill__ = true; smoothscroll(); /* @@ -86,6 +87,11 @@ export class ScrollableBase { return; } + if(!rootScope.settings.animationsEnabled) { + smooth = false; + scrollTime = 0; + } + const wasLocked = !!this.scrollLocked; if(wasLocked) clearTimeout(this.scrollLocked); if(smooth) { diff --git a/src/components/sidebarRight/index.ts b/src/components/sidebarRight/index.ts index 0cf6467a..fd19c071 100644 --- a/src/components/sidebarRight/index.ts +++ b/src/components/sidebarRight/index.ts @@ -9,6 +9,7 @@ import AppSharedMediaTab from "./tabs/sharedMedia"; //import AppForwardTab from "./tabs/forward"; import { MOUNT_CLASS_TO } from "../../lib/mtproto/mtproto_config"; import { pause } from "../../helpers/schedulers"; +import rootScope from "../../lib/rootScope"; export const RIGHT_COLUMN_ACTIVE_CLASSNAME = 'is-right-column-shown'; @@ -112,7 +113,7 @@ export class AppSidebarRight extends SidebarSlider { //if(mediaSizes.isMobile) { //appImManager._selectTab(active ? 1 : 2); appImManager.selectTab(active ? 1 : 2); - return pause(mediaSizes.isMobile ? 250 : 200); // delay of slider animation + return pause(rootScope.settings.animationsEnabled ? mediaSizes.isMobile ? 250 : 200 : 0); // delay of slider animation //} return pause(200); // delay for third column open diff --git a/src/components/singleTransition.ts b/src/components/singleTransition.ts index ef88dea1..35e2f13f 100644 --- a/src/components/singleTransition.ts +++ b/src/components/singleTransition.ts @@ -1,17 +1,16 @@ +import rootScope from "../lib/rootScope"; + const SetTransition = (element: HTMLElement, className: string, forwards: boolean, duration: number, onTransitionEnd?: () => void) => { const timeout = element.dataset.timeout; if(timeout !== undefined) { clearTimeout(+timeout); } - if(forwards && className) { + if(forwards) { element.classList.add(className); } - element.classList.add('animating'); - - element.classList.toggle('backwards', !forwards); - element.dataset.timeout = '' + setTimeout(() => { + const afterTimeout = () => { delete element.dataset.timeout; if(!forwards) { element.classList.remove('backwards', className); @@ -20,7 +19,18 @@ const SetTransition = (element: HTMLElement, className: string, forwards: boolea element.classList.remove('animating'); onTransitionEnd && onTransitionEnd(); - }, duration); + }; + + if(!rootScope.settings.animationsEnabled) { + element.classList.remove('animating', 'backwards'); + afterTimeout(); + return; + } + + element.classList.add('animating'); + + element.classList.toggle('backwards', !forwards); + element.dataset.timeout = '' + setTimeout(afterTimeout, duration); }; export default SetTransition; \ No newline at end of file diff --git a/src/components/transition.ts b/src/components/transition.ts index a1f7ff10..2d0a9a76 100644 --- a/src/components/transition.ts +++ b/src/components/transition.ts @@ -1,4 +1,5 @@ import { whichChild } from "../helpers/dom"; +import rootScope from "../lib/rootScope"; function slideNavigation(tabContent: HTMLElement, prevTabContent: HTMLElement, toRight: boolean) { const width = prevTabContent.getBoundingClientRect().width; @@ -95,13 +96,19 @@ const Transition = (content: HTMLElement, animationFunction: TransitionFunction, const p = prevTabContent; const tabContent = content.children[id] as HTMLElement; + if(!rootScope.settings.animationsEnabled) { + animate = false; + } + // * means animation isn't needed if(/* content.dataset.slider == 'none' || */!animate) { if(p) { p.classList.remove('active'); } - tabContent.classList.add('active'); + if(tabContent) { + tabContent.classList.add('active'); + } self.prevId = id; prevTabContent = tabContent; diff --git a/src/helpers/dom.ts b/src/helpers/dom.ts index dbddfe59..30017f95 100644 --- a/src/helpers/dom.ts +++ b/src/helpers/dom.ts @@ -242,15 +242,16 @@ export function getRichElementValue(node: HTMLElement, lines: string[], line: st export function isInputEmpty(element: HTMLElement) { if(element.hasAttribute('contenteditable') || element.tagName != 'INPUT') { - const value = element.innerText; + /* const value = element.innerText; - return !value.trim() && !serializeNodes(Array.from(element.childNodes)).trim(); + return !value.trim() && !serializeNodes(Array.from(element.childNodes)).trim(); */ + return !getRichValue(element).trim(); } else { - return !(element as HTMLInputElement).value.trim().length; + return !(element as HTMLInputElement).value.trim(); } } -export function serializeNodes(nodes: Node[]): string { +/* export function serializeNodes(nodes: Node[]): string { return nodes.reduce((str, child: any) => { //console.log('childNode', str, child, typeof(child), typeof(child) === 'string', child.innerText); @@ -260,7 +261,7 @@ export function serializeNodes(nodes: Node[]): string { return str; }, ''); -} +} */ /* if (Config.Modes.animations && typeof window.requestAnimationFrame == 'function') { diff --git a/src/lib/appManagers/appImManager.ts b/src/lib/appManagers/appImManager.ts index 7df86636..827e7897 100644 --- a/src/lib/appManagers/appImManager.ts +++ b/src/lib/appManagers/appImManager.ts @@ -100,15 +100,6 @@ export class AppImManager { this.chatsContainer.classList.add('chats-container', 'tabs-container'); this.columnEl.append(this.chatsContainer); - - this.chatsSelectTabDebounced = debounce(() => { - const topbar = this.chat.topbar; - if(topbar.pinnedMessage) { // * буду молиться богам, чтобы это ничего не сломало, но это исправляет получение пиннеда после анимации - topbar.pinnedMessage.setCorrectIndex(0); - } - - apiManager.setQueueId(this.chat.bubbles.lazyLoadQueue.queueId); - }, 250, false, true); this.createNewChat(); this.chatsSelectTab(this.chat.container); @@ -152,6 +143,19 @@ export class AppImManager { private setSettings() { document.documentElement.style.setProperty('--messages-text-size', rootScope.settings.messagesTextSize + 'px'); + + document.body.classList.toggle('animation-level-0', !rootScope.settings.animationsEnabled); + document.body.classList.toggle('animation-level-1', false); + document.body.classList.toggle('animation-level-2', rootScope.settings.animationsEnabled); + + this.chatsSelectTabDebounced = debounce(() => { + const topbar = this.chat.topbar; + if(topbar.pinnedMessage) { // * буду молиться богам, чтобы это ничего не сломало, но это исправляет получение пиннеда после анимации + topbar.pinnedMessage.setCorrectIndex(0); + } + + apiManager.setQueueId(this.chat.bubbles.lazyLoadQueue.queueId); + }, rootScope.settings.animationsEnabled ? 250 : 0, false, true); } private chatsSelectTab(tab: HTMLElement) { diff --git a/src/lib/richtextprocessor.ts b/src/lib/richtextprocessor.ts index b2e4876a..29ae75e6 100644 --- a/src/lib/richtextprocessor.ts +++ b/src/lib/richtextprocessor.ts @@ -472,6 +472,9 @@ namespace RichTextProcessor { insertPart(entity, ``, ``); } } + /* if(!emojiSupported) { + insertPart(entity, ``, ``); + } */ break; } diff --git a/src/scss/partials/_button.scss b/src/scss/partials/_button.scss index da98dc3e..729eeb04 100644 --- a/src/scss/partials/_button.scss +++ b/src/scss/partials/_button.scss @@ -17,6 +17,10 @@ align-items: center; justify-content: center; + body.animation-level-0 & { + transition: none; + } + &.active { color: $color-blue; } @@ -85,6 +89,10 @@ transition-timing-function: cubic-bezier(.4, 0, .2, 1); font-size: 16px; + body.animation-level-0 & { + transition: none; + } + -webkit-user-select: none; /* disable selection/Copy of UIWebView */ -webkit-touch-callout: none; /* disable the IOS popup when long-press on a link */ @@ -222,6 +230,10 @@ transition: .2s background-color, .2s opacity; background: darken($color-blue, 8%); } + + body.animation-level-0 & { + transition: none; + } svg, use { height: calc(100% - 20px); diff --git a/src/scss/partials/_chat.scss b/src/scss/partials/_chat.scss index c5f60a2b..02e1b452 100644 --- a/src/scss/partials/_chat.scss +++ b/src/scss/partials/_chat.scss @@ -22,6 +22,10 @@ $chat-helper-size: 39px; transition: transform var(--layer-transition); transform: translateY(var(--translateY)); + body.animation-level-0 & { + transition: none; + } + //display: none !important; /* // * for no ESG top @@ -41,10 +45,6 @@ $chat-helper-size: 39px; body.is-right-column-shown & { transform: translate3d(calc(var(--right-column-width) / -2), var(--translateY), 0) !important; } - - body.animation-level-0 & { - transition: none; - } } &.is-hidden { @@ -121,6 +121,8 @@ $chat-helper-size: 39px; border: none; outline: none; white-space: pre-wrap; + font-size: var(--messages-text-size); + line-height: 1.3125; @media only screen and (max-height: 30rem) { max-height: unquote('max(39px, calc(100vh - 10rem))'); @@ -155,6 +157,10 @@ $chat-helper-size: 39px; right: 0; top: 0; + body.animation-level-0 & { + transition: none !important; + } + // here percents can be used since there are no other transforms transform: translateX(calc(-100% + var(--padding-horizontal) * -1 + #{-$btn-send-margin})); @@ -176,8 +182,16 @@ $chat-helper-size: 39px; > .tgico { position: absolute; - animation: hide-icon .4s forwards ease-in-out; height: 24px; + + body:not(.animation-level-0) & { + animation: hide-icon .4s forwards ease-in-out; + } + + body.animation-level-0 & { + visibility: hidden; + animation: none !important; + } } .tgico-send { @@ -207,12 +221,17 @@ $chat-helper-size: 39px; &.record .tgico-microphone2, &.edit .tgico-check, &.schedule .tgico-schedule { - animation: grow-icon .4s forwards ease-in-out; + animation: grow-icon .4s forwards ease-in-out !important; + visibility: visible !important; } } .btn-icon { transition: .2s color, background-color .2s, .2s opacity; + + body.animation-level-0 & { + transition: none; + } } .btn-record-cancel, .btn-send { @@ -250,6 +269,10 @@ $chat-helper-size: 39px; transition: transform .03s ease-in-out, visibility .1s; visibility: hidden; + body.animation-level-0 & { + transition: none !important; + } + @include respond-to(handhelds) { width: 300px; height: 300px; @@ -452,6 +475,10 @@ $chat-helper-size: 39px; flex-direction: column; //z-index: 1; + body.animation-level-0 & { + transition: none !important; + } + &:not(.active):not(:last-child) { filter: brightness(.8); } @@ -557,6 +584,10 @@ $chat-helper-size: 39px; z-index: 3; transition: width .1s; + body.animation-level-0 & { + transition: none; + } + .chat-input.type-pinned & { width: 17.125rem; } @@ -709,6 +740,10 @@ $chat-helper-size: 39px; z-index: 1; user-select: none; + body.animation-level-0 & { + transition: none; + } + @include respond-to(handhelds) { padding-top: .25rem; } @@ -738,6 +773,7 @@ $chat-helper-size: 39px; //padding: 4.5px 0; //padding-bottom: 4.5px; align-items: flex-end; + min-height: var(--chat-input-size); .btn-icon:before { vertical-align: bottom; @@ -750,6 +786,7 @@ $chat-helper-size: 39px; flex: 1 1 auto; position: relative; overflow: hidden; + align-self: center; > .scrollable { position: relative; @@ -842,7 +879,7 @@ $chat-helper-size: 39px; //margin-bottom: 1px; // ! EXPERIMENTAL - margin: 0 3px 4px; + margin: 0 3px 5px; padding: 0.25rem; width: 34px; height: 34px; @@ -883,6 +920,10 @@ $chat-helper-size: 39px; transform: translateY(var(--translateY)); transition: transform var(--layer-transition); + body.animation-level-0 & { + transition: none; + } + /* html.is-safari & > .scrollable { -webkit-mask-image: -webkit-radial-gradient(circle, white 100%, black 100%); // fix safari overflow } */ @@ -945,15 +986,9 @@ $chat-helper-size: 39px; // ! WARNING, НЕЛЬЗЯ СТАВИТЬ ТРАНСФОРМ КРОМЕ TRANSLATEZ(0) НА БЛОК С OVERFLOW, ОН БУДЕТ ПРЫГАТЬ ВВЕРХ ПРИ ВКЛЮЧЕННОМ ПРАВИЛЕ И ЭТО НЕ ИСПРАВИТЬ JS'ОМ! @include respond-to(medium-screens) { - //transition: transform var(--layer-transition); - body.is-right-column-shown & { transform: translate3d(calc(var(--right-column-width) / -2), var(--translateY), 0); } - - body.animation-level-0 & { - transition: none; - } } &.is-selecting { @@ -1032,6 +1067,10 @@ $chat-helper-size: 39px; /* transition: margin-top var(--layer-transition); transition-delay: .2s; */ + body.animation-level-0 & { + transition: none; + } + @include respond-to(medium-screens) { width: calc(100% - var(--right-column-width)); } @@ -1111,6 +1150,10 @@ $chat-helper-size: 39px; --translateY: calc(var(--chat-input-size) + 10px); //--translateY: calc(100% + 10px); + body.animation-level-0 & { + transition: none !important; + } + /* &.is-broadcast { --translateY: 99px !important; } */ @@ -1189,6 +1232,10 @@ $chat-helper-size: 39px; background-color: #fff; transition: .2s ease; + body.animation-level-0 & { + transition: none; + } + &.active { opacity: 1; visibility: visible; @@ -1212,6 +1259,10 @@ $chat-helper-size: 39px; transform: translate3d(0, calc(-100% - 10px), 0); transition: transform .2s ease; + body.animation-level-0 & { + transition: none; + } + &.active { transform: translate3d(0, 0, 0); } diff --git a/src/scss/partials/_chatBubble.scss b/src/scss/partials/_chatBubble.scss index 53d7a973..9d5580ac 100644 --- a/src/scss/partials/_chatBubble.scss +++ b/src/scss/partials/_chatBubble.scss @@ -99,7 +99,10 @@ $bubble-margin: .25rem; &.is-highlighted:after { background-color: rgba(0, 132, 255, .3); - animation: bubbleSelected 2s linear; + + body:not(.animation-level-0) & { + animation: bubbleSelected 2s linear; + } } &.is-first-unread { @@ -132,11 +135,16 @@ $bubble-margin: .25rem; &.is-selected { &:after { background-color: rgba(77, 142, 80, .4); - animation: fade-in-opacity .2s linear forwards; } - &.backwards:after { - animation: fade-in-backwards-opacity .2s linear forwards; + body:not(.animation-level-0) & { + &:after { + animation: fade-in-opacity .2s linear forwards; + } + + &.backwards:after { + animation: fade-in-backwards-opacity .2s linear forwards; + } } } @@ -173,6 +181,10 @@ $bubble-margin: .25rem; opacity: .99999; // for safari pointer-events: none; + body.animation-level-0 & { + transition: none; + } + &.is-sticky { opacity: .00001; // for safari @@ -258,6 +270,10 @@ $bubble-margin: .25rem; transition: .2s transform; user-select: none; + body.animation-level-0 & { + transition: none; + } + /* html.no-touch .bubbles:not(.is-selecting) &, html.is-touch .bubbles.is-selecting:not(.no-select) & { user-select: text; @@ -285,6 +301,10 @@ $bubble-margin: .25rem; transform: scale3d(1, 1, 1); transform-origin: bottom; transition: transform var(--layer-transition); + + body.animation-level-0 & { + transition: none; + } } .bubbles.is-selecting:not(.backwards) & { @@ -581,6 +601,10 @@ $bubble-margin: .25rem; cursor: pointer; opacity: 1; transition: opacity .3s ease; + + body.animation-level-0 & { + transition: none; + } } .download { @@ -1056,8 +1080,10 @@ $bubble-margin: .25rem; background-color: rgba(0, 132, 255, .3); } - .document-selection, .document-wrapper:before { - animation: bubbleSelected 2s linear; + body:not(.animation-level-0) & { + .document-selection, .document-wrapper:before { + animation: bubbleSelected 2s linear; + } } } @@ -1066,13 +1092,15 @@ $bubble-margin: .25rem; background-color: rgba(77, 142, 80, .4); } - .document-selection, .document-wrapper:before { - animation: fade-in-opacity .2s linear forwards; - } - - &.backwards { + body:not(.animation-level-0) & { .document-selection, .document-wrapper:before { - animation: fade-in-backwards-opacity .2s linear forwards; + animation: fade-in-opacity .2s linear forwards; + } + + &.backwards { + .document-selection, .document-wrapper:before { + animation: fade-in-backwards-opacity .2s linear forwards; + } } } } @@ -1113,7 +1141,6 @@ $bubble-margin: .25rem; .checkbox-caption { &:after { - box-shadow: none; } } @@ -2108,6 +2135,10 @@ poll-element { transform: scale(1); transition: transform .2s ease; + body.animation-level-0 & { + transition: none; + } + // @include respond-to(handhelds) { // right: 16px; // } diff --git a/src/scss/partials/_chatMarkupTooltip.scss b/src/scss/partials/_chatMarkupTooltip.scss index 6e4cecb0..04e69471 100644 --- a/src/scss/partials/_chatMarkupTooltip.scss +++ b/src/scss/partials/_chatMarkupTooltip.scss @@ -20,6 +20,10 @@ display: flex; justify-content: flex-start; + body.animation-level-0 & { + transition: none; + } + &-wrapper { position: absolute; left: 0; @@ -33,6 +37,10 @@ transform: translateX(0); transition: transform var(--layer-transition); max-width: 100%; + + body.animation-level-0 & { + transition: none; + } } &-tools { @@ -100,6 +108,10 @@ opacity: 0; transition: opacity var(--layer-transition); pointer-events: none; + + body.animation-level-0 & { + transition: none; + } } } diff --git a/src/scss/partials/_chatPinned.scss b/src/scss/partials/_chatPinned.scss index cedd749d..79ec06fd 100644 --- a/src/scss/partials/_chatPinned.scss +++ b/src/scss/partials/_chatPinned.scss @@ -22,8 +22,6 @@ color: $color-blue; background: #50a2e988; position: relative; - will-change: transform; - transition: transform 0.25s ease-in-out; } &-bars { @@ -40,8 +38,13 @@ width: 2px; background: currentColor; border-radius: 1px; - will-change: transform; - transition: transform 0.25s ease-in-out; + } + + body:not(.animation-level-0) & { + &-wrapper, &-mark { + will-change: transform; + transition: transform 0.25s ease-in-out; + } } } } @@ -256,6 +259,10 @@ height: 2rem; position: absolute; transition: transform var(--pm-transition)/* , opacity var(--pm-transition) */; + + body.animation-level-0 & { + transition: none; + } } /* &-media { @@ -309,6 +316,10 @@ height: 50%; overflow: visible; transition: transform var(--pm-transition); + + body.animation-level-0 & { + transition: none; + } } } @@ -325,6 +336,10 @@ .animated-counter { transition: transform var(--pm-transition), opacity var(--pm-transition); + body.animation-level-0 & { + transition: none; + } + &:before { content: "#"; } diff --git a/src/scss/partials/_checkbox.scss b/src/scss/partials/_checkbox.scss index a0e1d90f..c74cd6b1 100644 --- a/src/scss/partials/_checkbox.scss +++ b/src/scss/partials/_checkbox.scss @@ -19,14 +19,18 @@ &:before { color: #fff; - font-size: 16px; - line-height: 24px; - margin-left: 4px; + font-size: 1rem; + line-height: 1.5rem; + margin-left: .25rem; transition: opacity .2s ease-in-out; opacity: 0; position: absolute; font-weight: bold; z-index: 1; + + body.animation-level-0 & { + transition: none; + } } &:after { @@ -40,6 +44,10 @@ //left: 0; background-color: transparent; transition: background-color .2s ease-in-out; + + body.animation-level-0 & { + transition: none; + } } } @@ -60,8 +68,6 @@ margin: 1.25rem 0; line-height: 1.5rem; cursor: pointer; - display: flex; - align-items: center; &.hidden-widget { cursor: default; @@ -101,6 +107,10 @@ width: 1.25rem; height: 1.25rem; transform: translateY(-50%); + + body.animation-level-0 & { + transition: none; + } } &::before { @@ -157,11 +167,19 @@ user-select: none; transition: .2s opacity; + body.animation-level-0 & { + transition: none; + } + &:before, &:after { content: ''; left: 0; position: absolute; transition: border .25s, background-color .25s, width .20s .1s, height .20s .1s, top .20s .1s, left .20s .1s; + + body.animation-level-0 & { + transition: none; + } } &:before { diff --git a/src/scss/partials/_emojiDropdown.scss b/src/scss/partials/_emojiDropdown.scss index a852c28b..d5dbee2c 100644 --- a/src/scss/partials/_emojiDropdown.scss +++ b/src/scss/partials/_emojiDropdown.scss @@ -27,6 +27,10 @@ transition: transform .2s ease-in; transform: scale(1); } + + body.animation-level-0 & { + transition: none; + } } /* @include respond-to(handhelds) { diff --git a/src/scss/partials/_input.scss b/src/scss/partials/_input.scss index 3e6ac95f..3c62329a 100644 --- a/src/scss/partials/_input.scss +++ b/src/scss/partials/_input.scss @@ -42,9 +42,13 @@ height: 1.5rem; transform: translateY(-50%); background-color: #fff; - transition: .2s transform, .2s padding, .1s opacity; + transition: .2s transform, .2s padding, .1s opacity, .2s top, .2s left; transform-origin: left center; pointer-events: none; + + body.animation-level-0 & { + transition: none; + } } input, &-input { @@ -66,6 +70,10 @@ /* overflow: hidden; white-space: nowrap; */ + body.animation-level-0 & { + transition: none; + } + html.no-touch & { &:hover:not(:focus):not(.error):not(.valid) { border-color: var(--color-gray); @@ -73,7 +81,7 @@ } @include respond-to(handhelds) { - min-height: 50px; + --height: 50px; } /* font-weight: 500; */ @@ -125,9 +133,13 @@ } &:focus ~ label, &:valid ~ label, &:not(:empty) ~ label, &:disabled ~ label { - transform: translate(-.3125rem, -2.375rem) scale(0.75); + //transform: translate(-.3125rem, -2.375rem) scale(.75); + //transform: translate(-.3125rem, -50%) scale(.75); + transform: translateY(-50%) scale(.75); + top: 1px; padding: 0 6px; opacity: 1; + left: .75rem; } } } @@ -159,7 +171,13 @@ input:focus, button:focus { padding: 0; &.error { - animation: input-shake .2s ease-in-out forwards; + body.animation-level-0 & { + color: $color-error!important; + } + + body:not(.animation-level-0) & { + animation: input-shake .2s ease-in-out forwards; + } } } @@ -190,7 +208,7 @@ input:focus, button:focus { overflow: hidden; @include respond-to(handhelds) { - margin-left: 16px; + margin-left: 1rem; } &-input { @@ -205,6 +223,10 @@ input:focus, button:focus { transition: background-color .2s ease-in-out, border-color .2s ease-in-out; border-color: transparent; + body.animation-level-0 & { + transition: none; + } + &:hover { border-color: var(--color-gray); } @@ -240,6 +262,10 @@ input:focus, button:focus { opacity: .6; transition: all .2s ease-out; + body.animation-level-0 & { + transition: none; + } + &:before { vertical-align: middle; } diff --git a/src/scss/partials/_leftSidebar.scss b/src/scss/partials/_leftSidebar.scss index 9d756ea5..8f1f52b9 100644 --- a/src/scss/partials/_leftSidebar.scss +++ b/src/scss/partials/_leftSidebar.scss @@ -26,6 +26,10 @@ width: 26.5rem; transform: translate3d(-5rem, 0, 0); transition: transform var(--layer-transition); + + body.animation-level-0 & { + transition: none; + } body.is-left-column-shown & { transform: translateZ(0); @@ -204,6 +208,10 @@ transform: rotate(180deg); } + body.animation-level-0 &, body.animation-level-0 &:before { + transition: none; + } + & + * { margin-left: 0!important; } @@ -609,6 +617,10 @@ width: 52px; transition: width 0.2s; margin: 5px 0 0 0; + + body.animation-level-0 & { + transition: none; + } } } } diff --git a/src/scss/partials/_mediaViewer.scss b/src/scss/partials/_mediaViewer.scss index d5a22f1f..f7d9d434 100644 --- a/src/scss/partials/_mediaViewer.scss +++ b/src/scss/partials/_mediaViewer.scss @@ -1,8 +1,6 @@ -$open-duration: .2s; -//$open-duration: 10s; -$move-duration: .35s; - .media-viewer { + --open-duration: .2s; + --move-duration: .35s; position: fixed; top: 0; left: 0; @@ -14,6 +12,11 @@ $move-duration: .35s; align-items: center; justify-content: center; + body.animation-level-0 & { + --open-duration: 0; + --move-duration: 0; + } + @include respond-to(handhelds) { background: #000; } @@ -28,7 +31,7 @@ $move-duration: .35s; flex-direction: column; justify-content: center; color: #8b8b8b; - transition: $open-duration; + transition: var(--open-duration); cursor: pointer; html.no-touch &:hover { @@ -64,7 +67,7 @@ $move-duration: .35s; .btn-icon { margin: 0 .25rem; - transition: $open-duration; + transition: var(--open-duration); html.no-touch &:hover { color: #fff; @@ -123,7 +126,7 @@ $move-duration: .35s; background-color: rgba(0, 0, 0, .6); border-radius: 8px; opacity: 0; - transition: opacity $open-duration; + transition: opacity var(--open-duration); @include respond-to(handhelds) { border-radius: 0; @@ -189,7 +192,7 @@ $move-duration: .35s; top: 50%; transform: translateY(-50%) rotate(90deg); opacity: 0; - transition: $open-duration opacity; + transition: var(--open-duration) opacity; z-index: 5; /* box-shadow: 0 1px 2px 0 rgba(16, 35, 47, 0.07); */ @@ -262,7 +265,7 @@ $move-duration: .35s; opacity: 1; /* border-radius: inherit; - transition: $open-duration border-radius; */ + transition: var(--open-duration) border-radius; */ //&.thumbnail { position: absolute; @@ -278,11 +281,11 @@ $move-duration: .35s; } &.active { - transition: $open-duration transform, $open-duration border-radius; + transition: var(--open-duration) transform, var(--open-duration) border-radius; } &.moving { - transition: $move-duration transform ease; + transition: var(--move-duration) transform ease; } /* &.center { @@ -350,7 +353,7 @@ $move-duration: .35s; &.hiding { img, video { - transition: $open-duration opacity; + transition: var(--open-duration) opacity; opacity: 0; } } @@ -370,8 +373,8 @@ $move-duration: .35s; } &-mover.active &-aspecter { - transition: width $open-duration, height $open-duration, transform $open-duration, border-radius $open-duration; - //transition: $open-duration all; + transition: width var(--open-duration), height var(--open-duration), transform var(--open-duration), border-radius var(--open-duration); + //transition: var(--open-duration) all; } &-whole { @@ -383,7 +386,7 @@ $move-duration: .35s; display: block; z-index: 4; visibility: hidden; - transition: visibility 0s $open-duration; + transition: visibility 0s var(--open-duration); &.active { visibility: visible; @@ -392,7 +395,7 @@ $move-duration: .35s; .overlays, > .btn-icon { opacity: 1; visibility: visible; - transition: opacity $open-duration 0s, visibility 0s 0s; + transition: opacity var(--open-duration) 0s, visibility 0s 0s; } } @@ -406,7 +409,7 @@ $move-duration: .35s; position: fixed; z-index: 5; opacity: 0; - transition: opacity $open-duration 0s, visibility 0s $open-duration; + transition: opacity var(--open-duration) 0s, visibility 0s var(--open-duration); } .btn-menu-toggle { @@ -446,5 +449,5 @@ $move-duration: .35s; //display: none; opacity: 0; visibility: hidden; - transition: opacity $open-duration 0s, visibility 0s $open-duration; + transition: opacity var(--open-duration) 0s, visibility 0s var(--open-duration); } diff --git a/src/scss/partials/_selector.scss b/src/scss/partials/_selector.scss index 12f6815c..fcdd4096 100644 --- a/src/scss/partials/_selector.scss +++ b/src/scss/partials/_selector.scss @@ -60,7 +60,11 @@ border-radius: 24px; user-select: none; flex: 0 0 auto; - transition: .2s all; + transition: .2s opacity, .2s transform, .2s background-color; + + body.animation-level-0 & { + transition: none; + } html.no-touch &:hover { background-color: #fae2e3; @@ -71,14 +75,16 @@ transform: scaleX(-1) rotate(-90deg); } } - - &.scale-in { - animation: scaleIn .15s ease forwards; - } - &.scale-out { - animation: scaleIn .1s ease forwards; - animation-direction: reverse; + body:not(.animation-level-0) & { + &.scale-in { + animation: scaleIn .15s ease forwards; + } + + &.scale-out { + animation: scaleIn .1s ease forwards; + animation-direction: reverse; + } } &-avatar { @@ -104,6 +110,10 @@ opacity: 0; transition: .2s opacity, .2s transform; transform: scaleX(-1) rotate(0deg); + + body.animation-level-0 & { + transition: none; + } } } } diff --git a/src/scss/partials/_slider.scss b/src/scss/partials/_slider.scss index 1c51b821..7c3c4f94 100644 --- a/src/scss/partials/_slider.scss +++ b/src/scss/partials/_slider.scss @@ -1,5 +1,3 @@ -$slider-time: .25s; - .menu-horizontal-div { width: 100%; display: flex; @@ -31,12 +29,15 @@ $slider-time: .25s; html.no-touch & { background-color: transparent; - transition: background-color .15s ease-in-out; &:hover { background-color: var(--color-gray-hover); } } + + html.no-touch body:not(.animation-level-0) & { + transition: background-color .15s ease-in-out; + } > span { position: relative; @@ -71,7 +72,7 @@ $slider-time: .25s; z-index: 1; &.animate { - transition: transform $slider-time; + transition: transform var(--tabs-transition); } } } @@ -111,12 +112,14 @@ $slider-time: .25s; html.no-touch & { background-color: transparent; - transition: background-color .15s ease-in-out; - &:hover { background-color: var(--color-gray-hover); } } + + html.no-touch body:not(.animation-level-0) & { + transition: background-color .15s ease-in-out; + } > span { position: relative; @@ -134,26 +137,6 @@ $slider-time: .25s; } } - /* &__stripe { - position: absolute; - background: $color-blue; - left: 0; - //left: -2px; - transition: .3s transform, .3s width; - //transition: .3s transform; - bottom: -1px; - height: 4px; - width: 1px; // need if using transform - transform: scaleX(1) translateX(0px); - border-top-left-radius: 2px; - border-top-right-radius: 2px; - z-index: 1; - - @include respond-to(handhelds) { - display: none; - } - } */ - i { position: absolute; bottom: calc(-.625rem - 2.4px); @@ -171,7 +154,7 @@ $slider-time: .25s; z-index: 1; &.animate { - transition: transform $slider-time; + transition: transform var(--tabs-transition); } } } @@ -197,7 +180,7 @@ $slider-time: .25s; width: 100%; max-width: 100%; //transition: transform .42s, filter .42s; - transition: transform $slider-time, filter $slider-time; + transition: transform var(--tabs-transition), filter var(--tabs-transition); display: none; flex-direction: column; position: relative; @@ -205,6 +188,10 @@ $slider-time: .25s; grid-column-start: 1; background-color: #fff; //z-index: 1; + + body.animation-level-0 & { + transition: none; + } //@include respond-to(not-handhelds) { overflow: hidden; @@ -223,6 +210,10 @@ $slider-time: .25s; } &[data-slider="tabs"] { - transition: transform $slider-time; + transition: transform var(--tabs-transition); + + body.animation-level-0 & { + transition: none; + } } } \ No newline at end of file diff --git a/src/scss/partials/popups/_createPoll.scss b/src/scss/partials/popups/_createPoll.scss index b50e68e3..d42d6e88 100644 --- a/src/scss/partials/popups/_createPoll.scss +++ b/src/scss/partials/popups/_createPoll.scss @@ -30,12 +30,12 @@ } } - .poll-create-questions > label { + /* .poll-create-questions > label { margin-top: 25px; - } + } */ .input-field { - margin-top: 0; + //margin-top: 0; .btn-icon { position: absolute; diff --git a/src/scss/partials/popups/_popup.scss b/src/scss/partials/popups/_popup.scss index 6f1a7580..07504808 100644 --- a/src/scss/partials/popups/_popup.scss +++ b/src/scss/partials/popups/_popup.scss @@ -19,6 +19,10 @@ /* align-items: center; justify-content: center; */ + body.animation-level-0 & { + transition: none; + } + &.active { opacity: 1; visibility: visible; @@ -44,6 +48,10 @@ flex-direction: column; overflow: hidden; margin: auto; + + body.animation-level-0 & { + transition: none; + } } &-centerer { @@ -57,7 +65,11 @@ text-align: center; justify-self: center; line-height: 1; - transition: .2s; + transition: color .2s; + + body.animation-level-0 & { + transition: none; + } html.no-touch &:hover { color: #000; @@ -87,7 +99,7 @@ justify-content: flex-end; align-items: flex-end; - button { + .btn { background: none; outline: none; border: none; @@ -103,12 +115,16 @@ max-width: 100%; white-space: nowrap; text-overflow: ellipsis; + + body.animation-level-0 & { + transition: none; + } html.no-touch &:hover { background-color: var(--color-gray-hover); } - & + button { + & + .btn { margin-top: .5rem; text-overflow: ellipsis; white-space: nowrap; diff --git a/src/scss/style.scss b/src/scss/style.scss index 2a92cd58..f643a0e5 100644 --- a/src/scss/style.scss +++ b/src/scss/style.scss @@ -84,6 +84,7 @@ $chat-padding-handhelds: .5rem; --color-gray-hover: rgba(112, 117, 121, .08); --pm-transition: .2s ease-in-out; --layer-transition: .2s ease-in-out; + --tabs-transition: .25s; //--layer-transition: .3s cubic-bezier(.33, 1, .68, 1); //--layer-transition: none; --btn-corner-transition: .2s cubic-bezier(.34, 1.56, .64, 1); @@ -873,6 +874,10 @@ img.emoji { bottom: 0; transition: transform var(--pm-transition), opacity var(--pm-transition); + body.animation-level-0 & { + transition: none; + } + /* &:not(.is-hiding) { transform: none !important; } */