From 364f2d9930bbbe87e27d939947f8896474934401 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Mon, 13 Sep 2021 20:02:30 +0300 Subject: [PATCH] Safe area for iPhone (#1403) --- src/components/main/Main.scss | 6 +++++ src/components/mediaViewer/MediaViewer.scss | 26 +++++++++++++++++++ src/components/mediaViewer/SenderInfo.scss | 2 +- src/components/middle/MessageList.scss | 18 +++++++++++++ .../middle/MessageSelectToolbar.scss | 4 +++ .../middle/MessageSelectToolbar.tsx | 2 +- src/components/middle/MiddleColumn.scss | 17 +++++++++++- src/components/middle/MiddleColumn.tsx | 22 ++++++++++++++++ src/components/middle/MiddleHeader.scss | 15 +++++++++++ src/components/middle/MobileSearch.scss | 15 +++++++++++ src/components/middle/ScrollDownButton.scss | 14 ++++++++++ src/components/middle/composer/Composer.scss | 4 +++ .../middle/composer/SymbolMenu.scss | 13 ++++++++++ src/components/right/RightColumn.scss | 4 +++ src/index.html | 2 +- 15 files changed, 160 insertions(+), 4 deletions(-) diff --git a/src/components/main/Main.scss b/src/components/main/Main.scss index cdb44b32e..cc5523867 100644 --- a/src/components/main/Main.scss +++ b/src/components/main/Main.scss @@ -95,6 +95,12 @@ width: 100vw; transform: translate3d(-20vw, 0, 0); } + + + @supports (left: env(safe-area-inset-left)) { + left: env(safe-area-inset-left) !important; + max-width: calc(26.5rem - env(safe-area-inset-left)) !important; + } } #RightColumn { diff --git a/src/components/mediaViewer/MediaViewer.scss b/src/components/mediaViewer/MediaViewer.scss index 16eba3277..e6bfc6f45 100644 --- a/src/components/mediaViewer/MediaViewer.scss +++ b/src/components/mediaViewer/MediaViewer.scss @@ -77,10 +77,18 @@ @media (max-width: 600px) { padding: 0 0.5rem; + @supports (padding: 0 env(safe-area-inset-left)) { + padding: 0 #{"max(0.5rem, env(safe-area-inset-left))"}; + } + .media-viewer-close { margin-right: 1.5rem; } } + + @supports (padding: 0 env(safe-area-inset-left)) { + padding: 0 #{"max(1.25rem, env(safe-area-inset-left))"}; + } } & > .Transition, @@ -185,10 +193,19 @@ background-image: url("../../assets/media_navigation_previous.svg"); background-position: 1.25rem calc(50% - 2rem); + @supports (left: env(safe-area-inset-left)) { + left: env(safe-area-inset-left); + } + &[dir=rtl] { left: auto; right: 0; transform: scaleX(-1); + + @supports (left: env(safe-area-inset-left)) { + left: auto; + right: env(safe-area-inset-right); + } } } @@ -197,10 +214,19 @@ background-image: url("../../assets/media_navigation_next.svg"); background-position: calc(100% - 1.25rem) calc(50% - 2rem); + @supports (left: env(safe-area-inset-left)) { + right: env(safe-area-inset-right); + } + &[dir=rtl]{ left: 0; right: auto; transform: scaleX(-1); + + @supports (left: env(safe-area-inset-left)) { + right: auto; + left: env(safe-area-inset-left); + } } } diff --git a/src/components/mediaViewer/SenderInfo.scss b/src/components/mediaViewer/SenderInfo.scss index 42ac4448f..24996b033 100644 --- a/src/components/mediaViewer/SenderInfo.scss +++ b/src/components/mediaViewer/SenderInfo.scss @@ -23,7 +23,7 @@ display: flex; flex-direction: column; justify-content: center; - max-width: 100%; + max-width: calc(100% - 3.75rem); } .title { diff --git a/src/components/middle/MessageList.scss b/src/components/middle/MessageList.scss index f02f711d4..84a274d53 100644 --- a/src/components/middle/MessageList.scss +++ b/src/components/middle/MessageList.scss @@ -11,6 +11,12 @@ overflow-y: auto; @include overflow-y-overlay(); + transition: transform var(--layer-transition); + + body.animation-level-0 & { + transition: none !important; + } + .mask-image-enabled & { mask-image: linear-gradient(to top, transparent 0, #000 0.5rem); } @@ -25,6 +31,12 @@ } } + @supports (padding-bottom: env(safe-area-inset-bottom)) { + body.keyboard-visible & { + transform: translateY(env(safe-area-inset-bottom)); + } + } + &.no-avatars .Message > .Avatar { display: none; } @@ -67,6 +79,12 @@ @media (max-width: 600px) { margin-bottom: 4.25rem; + + @supports (padding-bottom: env(safe-area-inset-bottom)) { + body:not(.keyboard-visible) & { + margin-bottom: calc(4.25rem + env(safe-area-inset-bottom)); + } + } } &.ActionMessage { diff --git a/src/components/middle/MessageSelectToolbar.scss b/src/components/middle/MessageSelectToolbar.scss index 4d3d094d2..695ddbe53 100644 --- a/src/components/middle/MessageSelectToolbar.scss +++ b/src/components/middle/MessageSelectToolbar.scss @@ -8,6 +8,10 @@ justify-content: center; margin: 0; + @supports (padding-bottom: env(safe-area-inset-bottom)) { + bottom: calc(.5rem + env(safe-area-inset-bottom)); + } + .mask-image-disabled &::before { left: auto !important; right: auto !important; diff --git a/src/components/middle/MessageSelectToolbar.tsx b/src/components/middle/MessageSelectToolbar.tsx index abe9dcb5a..89a30f749 100644 --- a/src/components/middle/MessageSelectToolbar.tsx +++ b/src/components/middle/MessageSelectToolbar.tsx @@ -70,7 +70,7 @@ const MessageSelectToolbar: FC = ({ const lang = useLang(); - const formattedMessagesCount = lang('VoiceOver.Chat.MessagesSelected', renderingSelectedMessagesCount); + const formattedMessagesCount = lang('VoiceOver.Chat.MessagesSelected', renderingSelectedMessagesCount, 'i'); const className = buildClassName( 'MessageSelectToolbar', diff --git a/src/components/middle/MiddleColumn.scss b/src/components/middle/MiddleColumn.scss index 90941e34b..fb1479faf 100644 --- a/src/components/middle/MiddleColumn.scss +++ b/src/components/middle/MiddleColumn.scss @@ -227,7 +227,7 @@ z-index: var(--z-middle-footer); transform: translate3d(0, 0, 0); - transition: transform var(--layer-transition); + transition: top 200ms, transform var(--layer-transition); body.animation-level-0 & { transition: none !important; @@ -249,6 +249,17 @@ } } + @supports (padding-bottom: env(safe-area-inset-bottom)) { + &:not(.no-composer) { + padding-bottom: env(safe-area-inset-bottom); + top: 0; + + body.keyboard-visible & { + top: env(safe-area-inset-bottom); + } + } + } + &::before { content: ""; position: absolute; @@ -347,6 +358,10 @@ @media (max-width: 600px) { padding-bottom: 0.75rem; + + @supports (padding-bottom: env(safe-area-inset-bottom)) { + padding-bottom: calc(.75rem + env(safe-area-inset-bottom)); + } } .mask-image-disabled &::before { diff --git a/src/components/middle/MiddleColumn.tsx b/src/components/middle/MiddleColumn.tsx index 8ebb2d952..bdec41245 100644 --- a/src/components/middle/MiddleColumn.tsx +++ b/src/components/middle/MiddleColumn.tsx @@ -175,6 +175,28 @@ const MiddleColumn: FC = ({ } }, [animationLevel]); + // Fix for mobile virtual keyboard + useEffect(() => { + const { visualViewport } = window as any; + if (!visualViewport) { + return undefined; + } + + const handleResize = () => { + if (window.visualViewport.height !== document.documentElement.clientHeight) { + document.body.classList.add('keyboard-visible'); + } else { + document.body.classList.remove('keyboard-visible'); + } + }; + + visualViewport.addEventListener('resize', handleResize); + + return () => { + visualViewport.removeEventListener('resize', handleResize); + }; + }, []); + const handleTransitionEnd = (e: React.TransitionEvent) => { if (e.propertyName === 'transform' && e.target === e.currentTarget) { setIsReady(Boolean(chatId)); diff --git a/src/components/middle/MiddleHeader.scss b/src/components/middle/MiddleHeader.scss index b9613fc17..7dff068d5 100644 --- a/src/components/middle/MiddleHeader.scss +++ b/src/components/middle/MiddleHeader.scss @@ -32,6 +32,11 @@ max-width: unset; margin-top: -0.1875rem; } + + @supports (padding-left: env(safe-area-inset-left)) { + padding-left: #{"max(0.75rem, env(safe-area-inset-left))"}; + padding-right: #{"max(0.5rem, env(safe-area-inset-right))"}; + } } .AudioPlayer { @@ -80,12 +85,22 @@ position: relative; z-index: var(--z-middle-header); + @supports (padding-left: env(safe-area-inset-left)) { + padding-left: #{"max(1.5rem, env(safe-area-inset-left))"}; + padding-right: #{"max(.8125rem, env(safe-area-inset-right))"}; + } + @media (max-width: 600px) { padding: 0.5rem; position: relative; // Force rendering in the composite layer to fix the z-index rendering issue transform: translate3d(0, 0, 10px); transform-style: preserve-3d; + + @supports (padding-left: env(safe-area-inset-left)) { + padding-left: #{"max(.5rem, env(safe-area-inset-left))"}; + padding-right: #{"max(.5rem, env(safe-area-inset-right))"}; + } } .Transition { diff --git a/src/components/middle/MobileSearch.scss b/src/components/middle/MobileSearch.scss index 205fb09e4..059dddcda 100644 --- a/src/components/middle/MobileSearch.scss +++ b/src/components/middle/MobileSearch.scss @@ -10,6 +10,11 @@ align-items: center; padding: 0 0.5rem 0 0.25rem; + @supports (padding-left: env(safe-area-inset-left)) { + padding-left: #{"max(0.25rem, env(safe-area-inset-left))"}; + padding-right: #{"max(0.5rem, env(safe-area-inset-right))"}; + } + > .SearchInput { margin-left: 0.25rem; flex: 1; @@ -29,6 +34,16 @@ padding-left: 1rem; padding-right: 0.5rem; + @supports (padding-bottom: env(safe-area-inset-bottom)) { + padding-left: #{"max(1rem, env(safe-area-inset-left))"}; + padding-right: #{"max(0.5rem, env(safe-area-inset-right))"}; + + body:not(.keyboard-visible) & { + padding-bottom: env(safe-area-inset-bottom); + height: calc(3.5rem + env(safe-area-inset-bottom)); + } + } + > .counter { flex: 1; color: var(--color-text-secondary); diff --git a/src/components/middle/ScrollDownButton.scss b/src/components/middle/ScrollDownButton.scss index 18ec4f95e..cabf515b8 100644 --- a/src/components/middle/ScrollDownButton.scss +++ b/src/components/middle/ScrollDownButton.scss @@ -10,6 +10,10 @@ z-index: var(--z-scroll-down-button); pointer-events: none; + @supports (right: env(safe-area-inset-right)) { + right: #{"max(1rem, env(safe-area-inset-right))"}; + } + body.animation-level-0 & { transform: none !important; @@ -19,6 +23,12 @@ @media (max-width: 600px) { right: 0.5rem; bottom: 4.5rem; + + @supports (padding-bottom: env(safe-area-inset-bottom)) { + body:not(.keyboard-visible) & { + bottom: calc(4.5rem + env(safe-area-inset-bottom)); + } + } } &-inner { @@ -63,6 +73,10 @@ &.no-composer:not(.with-extra-shift) { transform: translateY(4rem); + + @supports (padding-bottom: env(safe-area-inset-bottom)) { + transform: translateY(calc(4rem - env(safe-area-inset-bottom))); + } } } diff --git a/src/components/middle/composer/Composer.scss b/src/components/middle/composer/Composer.scss index f76fa8563..d42a0e0b3 100644 --- a/src/components/middle/composer/Composer.scss +++ b/src/components/middle/composer/Composer.scss @@ -8,6 +8,10 @@ padding-right: 2rem; bottom: 0; + @supports (padding-bottom: env(safe-area-inset-bottom)) { + bottom: env(safe-area-inset-bottom); + } + @media (max-width: 600px) { padding-right: 1rem; } diff --git a/src/components/middle/composer/SymbolMenu.scss b/src/components/middle/composer/SymbolMenu.scss index 4ff91541d..a3ed3bfd3 100644 --- a/src/components/middle/composer/SymbolMenu.scss +++ b/src/components/middle/composer/SymbolMenu.scss @@ -11,6 +11,11 @@ z-index: 1; transition: transform var(--layer-transition); + @supports (padding-bottom: env(safe-area-inset-bottom)) { + padding-right: env(safe-area-inset-right); + padding-bottom: env(safe-area-inset-bottom); + padding-left: env(safe-area-inset-left); + } &.open { transform: translate3d(0, 0, 0); @@ -33,6 +38,9 @@ width: var(--symbol-menu-width); height: var(--symbol-menu-height); max-height: calc(100vh - var(--symbol-menu-footer-height)); + @supports (padding-bottom: env(safe-area-inset-bottom)) { + max-height: calc(100vh - var(--symbol-menu-footer-height) - env(safe-area-inset-bottom)); + } } &-footer { @@ -116,6 +124,11 @@ position: absolute; right: .25rem; top: .25rem; + + @supports (right: env(safe-area-inset-right)) { + right: #{"max(.25rem, env(safe-area-inset-right))"}; + top: #{"max(.25rem, env(safe-area-inset-top))"}; + } } @media (orientation: landscape) { diff --git a/src/components/right/RightColumn.scss b/src/components/right/RightColumn.scss index 359756df5..7f04a65f9 100644 --- a/src/components/right/RightColumn.scss +++ b/src/components/right/RightColumn.scss @@ -32,6 +32,10 @@ transform: translate3d(110vw, 0, 0); } + @supports (padding-right: env(safe-area-inset-right)) { + padding-right: env(safe-area-inset-right); + } + > .Transition { height: calc(100% - var(--header-height)); overflow: hidden; diff --git a/src/index.html b/src/index.html index 4ee5eedd9..b5b70fc3e 100644 --- a/src/index.html +++ b/src/index.html @@ -3,7 +3,7 @@ - +