Compact context menus on desktop (#1726)

This commit is contained in:
Alexander Zinchuk 2022-02-25 22:52:51 +02:00
parent 9c789cdcb8
commit c81ed0eb61
19 changed files with 130 additions and 22 deletions

View File

@ -11,17 +11,13 @@
background: #181f27;
}
.Menu .bubble {
--color-background: #232a34;
--color-chat-hover: #2f363e;
--color-item-active: #2f363e;
--color-text: #fff;
box-shadow: 0 0.25rem 0.5rem 0.125rem rgba(16, 16, 16, 0.3);
}
// Compact menu items
.MenuItem {
padding: 0.75rem 1rem !important;
.Menu {
--color-text: white;
--color-background-compact-menu: #212121DD;
--color-background-compact-menu-hover: #00000066;
.bubble {
box-shadow: 0 0.25rem 0.5rem 0.125rem rgba(16, 16, 16, 0.3);
}
}
&.single-column {

View File

@ -2,14 +2,18 @@
.participant-menu {
position: absolute;
--color-text: white;
--color-background-compact-menu: #212121DD;
--color-background-compact-menu-hover: #00000066;
.bubble {
background: none;
background: none !important;
border-radius: 0;
padding: 0;
border: none !important;
box-shadow: none !important;
overflow: visible;
color: #ffffff;
color: var(--color-text);
.group {
box-shadow: 0 0.25rem 0.5rem 0.125rem rgba(16, 16, 16, 0.3);
@ -20,6 +24,12 @@
}
}
&.compact {
.group {
background: var(--color-background-compact-menu);
}
}
.volume-control {
height: 3rem;

View File

@ -69,6 +69,16 @@
flex-shrink: 0;
}
.MenuItem.compact .archived-badge {
background: none;
padding: 0;
color: var(--color-text-secondary);
}
.MenuItem.compact .Switcher {
transform: scale(0.75);
}
[dir="rtl"] .archived-badge {
margin-left: 0;
margin-right: auto;

View File

@ -43,6 +43,7 @@ const BotCommandMenu: FC<OwnProps> = ({
onMouseEnter={!IS_TOUCH_ENV ? handleMouseEnter : undefined}
onMouseLeave={!IS_TOUCH_ENV ? handleMouseLeave : undefined}
noCloseOnBackdrop={!IS_TOUCH_ENV}
noCompact
>
{botCommands.map((botCommand) => (
<BotCommand

View File

@ -56,6 +56,7 @@ const BotKeyboardMenu: FC<OwnProps & StateProps> = ({
onCloseAnimationEnd={handleClose}
onMouseEnter={!IS_TOUCH_ENV ? handleMouseEnter : undefined}
onMouseLeave={!IS_TOUCH_ENV ? handleMouseLeave : undefined}
noCompact
>
<div className="content">
{message.keyboardButtons.map((row) => (

View File

@ -86,6 +86,7 @@ const SendAsMenu: FC<OwnProps> = ({
onMouseEnter={!IS_TOUCH_ENV ? handleMouseEnter : undefined}
onMouseLeave={!IS_TOUCH_ENV ? handleMouseLeave : undefined}
noCloseOnBackdrop={!IS_TOUCH_ENV}
noCompact
>
<div className="send-as-title" dir="auto">{lang('SendMessageAsTitle')}</div>
{usersById && chatsById && sendAsIds?.map((id, index) => {

View File

@ -232,6 +232,7 @@ const SymbolMenu: FC<OwnProps & StateProps> = ({
onMouseEnter={!IS_TOUCH_ENV ? handleMouseEnter : undefined}
onMouseLeave={!IS_TOUCH_ENV ? handleMouseLeave : undefined}
noCloseOnBackdrop={!IS_TOUCH_ENV}
noCompact
>
{content}
</Menu>

View File

@ -9,11 +9,15 @@
overscroll-behavior: contain;
}
&.compact .scrollable-content {
padding: 0.25rem 0;
}
.bubble {
transition: opacity 0.15s cubic-bezier(0.2, 0, 0.2, 1), transform 0.15s cubic-bezier(0.2, 0, 0.2, 1) !important;
transform: scale(0.7);
overflow: initial;
padding: 0;
padding: 0 !important;
}
&.with-reactions .bubble {

View File

@ -11,6 +11,7 @@
top: -3.5rem;
&__bubble-big {
border: 0.5rem solid var(--color-background);
position: absolute;
display: block;
content: "";
@ -18,8 +19,10 @@
bottom: -0.5rem;
width: 1rem;
height: 1rem;
border-radius: 50%;
background: var(--color-background);
border-top: 0;
border-left: 0;
border-right: 0;
border-radius: 0 0 50% 50%;
z-index: -1;
}
@ -64,4 +67,22 @@
align-items: center;
border-radius: 3rem;
}
&--compact {
background: var(--color-background-compact-menu-reactions);
height: 2rem;
top: -2.5rem;
}
&--compact &__items {
padding: 0 0.5rem;
}
&--compact &__bubble-big {
border-color: var(--color-background-compact-menu-reactions);
}
&--compact &__bubble-small {
background: var(--color-background-compact-menu-reactions);
}
}

View File

@ -8,6 +8,8 @@ import useHorizontalScroll from '../../../hooks/useHorizontalScroll';
import useFlag from '../../../hooks/useFlag';
import { getTouchY } from '../../../util/scrollLock';
import { createClassNameBuilder } from '../../../util/buildClassName';
import { IS_COMPACT_MENU } from '../../../util/environment';
import ReactionSelectorReaction from './ReactionSelectorReaction';
import './ReactionSelector.scss';
@ -50,7 +52,7 @@ const ReactionSelector: FC<OwnProps> = ({
if ((!isPrivate && !enabledReactions?.length) || !availableReactions) return undefined;
return (
<div className={cn('&')} onWheelCapture={handleWheel} onTouchMove={handleWheel}>
<div className={cn('&', IS_COMPACT_MENU && 'compact')} onWheelCapture={handleWheel} onTouchMove={handleWheel}>
<div className={cn('bubble-big')} />
<div className={cn('bubble-small')} />
<div className={cn('items-wrapper')}>

View File

@ -23,4 +23,9 @@
top: 0;
left: 0;
}
&--compact {
min-width: 1.5rem;
min-height: 1.5rem;
}
}

View File

@ -8,12 +8,13 @@ import useMedia from '../../../hooks/useMedia';
import useFlag from '../../../hooks/useFlag';
import useShowTransition from '../../../hooks/useShowTransition';
import { createClassNameBuilder } from '../../../util/buildClassName';
import { IS_COMPACT_MENU } from '../../../util/environment';
import AnimatedSticker from '../../common/AnimatedSticker';
import './ReactionSelectorReaction.scss';
const REACTION_SIZE = 32;
const REACTION_SIZE = IS_COMPACT_MENU ? 24 : 32;
type OwnProps = {
reaction: ApiAvailableReaction;
@ -48,7 +49,7 @@ const ReactionSelectorReaction: FC<OwnProps> = ({ reaction, previewIndex, onSend
return (
<div
className={cn('&')}
className={cn('&', IS_COMPACT_MENU && 'compact')}
onClick={handleClick}
ref={containerRef}
onMouseEnter={isReady ? activate : undefined}
@ -59,7 +60,7 @@ const ReactionSelectorReaction: FC<OwnProps> = ({ reaction, previewIndex, onSend
'static',
isReady ? [staticClassNames] : undefined,
)}
style={`background-position-x: ${previewIndex * -32}px;`}
style={`background-position-x: ${previewIndex * -REACTION_SIZE}px;`}
/>
)}
{shouldRenderAnimated && (

View File

@ -78,4 +78,16 @@
font-size: 0.8125rem;
text-align: center;
}
&.compact {
.bubble {
background: var(--color-background-compact-menu);
backdrop-filter: blur(10px);
padding: 0.25rem 0;
}
.footer {
background: none;
}
}
}

View File

@ -10,6 +10,7 @@ import buildClassName from '../../util/buildClassName';
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
import useHistoryBack from '../../hooks/useHistoryBack';
import { preventMessageInputBlurWithBubbling } from '../middle/helpers/preventMessageInputBlur';
import { IS_COMPACT_MENU } from '../../util/environment';
import './Menu.scss';
@ -28,6 +29,7 @@ type OwnProps = {
shouldSkipTransition?: boolean;
footer?: string;
noCloseOnBackdrop?: boolean;
noCompact?: boolean;
onKeyDown?: (e: React.KeyboardEvent<any>) => void;
onCloseAnimationEnd?: () => void;
onClose?: () => void;
@ -53,6 +55,7 @@ const Menu: FC<OwnProps> = ({
autoClose = false,
footer,
noCloseOnBackdrop = false,
noCompact,
onCloseAnimationEnd,
onClose,
onMouseEnter,
@ -110,7 +113,7 @@ const Menu: FC<OwnProps> = ({
return (
<div
className={buildClassName('Menu no-selection', className)}
className={buildClassName('Menu no-selection', !noCompact && IS_COMPACT_MENU && 'compact', className)}
onKeyDown={isOpen ? handleKeyDown : undefined}
onMouseEnter={onMouseEnter}
onMouseLeave={isOpen ? onMouseLeave : undefined}

View File

@ -64,7 +64,7 @@
}
}
&:not(.has-ripple):not(.disabled):active {
&:not(.has-ripple):not(.disabled):not(.compact):active {
background-color: var(--color-item-active);
transition: none !important;
}
@ -89,4 +89,35 @@
margin-right: auto;
}
}
&.compact {
align-items: center;
font-size: 0.875rem;
margin: 0.125rem 0.25rem;
padding: 0.25rem;
border-radius: 0.375rem;
width: auto;
font-weight: 500;
transform: scale(1);
transition: 0.15s ease-in-out transform;
i {
font-size: 1.25rem;
margin-left: 0.5rem;
margin-right: 1.25rem;
}
@media (hover: hover) {
&:hover,
&:focus,
&:active {
background: var(--color-background-compact-menu-hover);
text-decoration: none;
}
&:active {
transform: scale(0.98);
}
}
}
}

View File

@ -2,6 +2,7 @@ import React, { FC, useCallback } from '../../lib/teact/teact';
import buildClassName from '../../util/buildClassName';
import useLang from '../../hooks/useLang';
import { IS_COMPACT_MENU } from '../../util/environment';
import './MenuItem.scss';
@ -64,6 +65,7 @@ const MenuItem: FC<OwnProps> = (props) => {
className,
disabled && 'disabled',
destructive && 'destructive',
IS_COMPACT_MENU && 'compact',
);
const content = (

View File

@ -65,6 +65,9 @@ $color-message-reaction-own-hover: #b5e0a4;
:root {
--color-background: #{$color-white};
--color-background-compact-menu: #FFFFFFBB;
--color-background-compact-menu-reactions: #FFFFFFEB;
--color-background-compact-menu-hover: #000000B2;
--color-background-selected: #f4f4f5;
--color-background-secondary: #f4f4f5;
--color-background-secondary-accent: #e4e4e5;

View File

@ -3,6 +3,9 @@
"--color-primary-opacity": ["#50A2E980", "#8378DB80"],
"--color-primary-shade": ["#4a95d6", "#7b71c6"],
"--color-background": ["#FFFFFF", "#212121"],
"--color-background-compact-menu": ["#FFFFFFBB", "#212121DD"],
"--color-background-compact-menu-reactions": ["#FFFFFFEB", "#212121DD"],
"--color-background-compact-menu-hover": ["#00000011", "#00000066"],
"--color-background-secondary": ["#f4f4f5", "#0F0F0F"],
"--color-background-secondary-accent": ["#E4E4E5", "#100f10"],
"--color-background-own": ["#EEFFDE", "#8774E1"],

View File

@ -86,6 +86,7 @@ export const DPR = window.devicePixelRatio || 1;
export const MASK_IMAGE_DISABLED = true;
export const IS_COMPACT_MENU = !IS_TOUCH_ENV;
export const IS_SCROLL_PATCH_NEEDED = !IS_MAC_OS && !IS_IOS && !IS_ANDROID;
// Smaller area reduces scroll jumps caused by `patchChromiumScroll`