Browse Source

Reactions menu fixes

master
Eduard Kuzmenko 2 years ago
parent
commit
7f35705e37
  1. 47
      src/components/chat/contextMenu.ts
  2. 2
      src/components/chat/input.ts
  3. 9
      src/index.ts
  4. 3
      src/scss/components/_global.scss
  5. 5
      src/scss/partials/_avatar.scss
  6. 50
      src/scss/partials/_button.scss
  7. 20
      src/scss/partials/_chat.scss
  8. 8
      src/scss/partials/_scrollable.scss
  9. 5
      src/scss/style.scss

47
src/components/chat/contextMenu.ts

@ -176,24 +176,26 @@ export default class ChatContextMenu {
const initResult = this.init(); const initResult = this.init();
element = initResult.element; element = initResult.element;
const {cleanup, destroy, menuPadding, reactionsMenu} = initResult; const {cleanup, destroy, menuPadding, reactionsMenu, reactionsMenuPosition} = initResult;
let isReactionsMenuVisible = false; let isReactionsMenuVisible = false;
if(reactionsMenu) { if(reactionsMenu) {
const className = 'is-visible'; const className = 'is-visible';
isReactionsMenuVisible = reactionsMenu.container.classList.contains(className); isReactionsMenuVisible = reactionsMenu.container.classList.contains(className);
if(isReactionsMenuVisible) reactionsMenu.container.classList.remove(className); if(isReactionsMenuVisible) reactionsMenu.container.classList.remove(className);
const offsetWidth = element.offsetWidth; if(reactionsMenuPosition === 'horizontal') {
// if(reactionsMenu.scrollable.container.scrollWidth > offsetWidth) { const offsetSize = element[/* reactionsMenuPosition === 'vertical' ? 'offsetHeight' : */'offsetWidth'];
const INNER_CONTAINER_PADDING = 8; // if(reactionsMenu.scrollable.container.scrollWidth > offsetWidth) {
const visibleLength = (offsetWidth - INNER_CONTAINER_PADDING) / REACTION_CONTAINER_SIZE; const INNER_CONTAINER_PADDING = 8;
const nextVisiblePart = visibleLength % 1; const visibleLength = (offsetSize - INNER_CONTAINER_PADDING) / REACTION_CONTAINER_SIZE;
const MIN_NEXT_VISIBLE_PART = 0.65; const nextVisiblePart = visibleLength % 1;
if(nextVisiblePart < MIN_NEXT_VISIBLE_PART) { const MIN_NEXT_VISIBLE_PART = 0.65;
const minWidth = (offsetWidth + (MIN_NEXT_VISIBLE_PART - nextVisiblePart) * REACTION_CONTAINER_SIZE) | 0; if(nextVisiblePart < MIN_NEXT_VISIBLE_PART) {
element.style.minWidth = minWidth + 'px'; const minSize = (offsetSize + (MIN_NEXT_VISIBLE_PART - nextVisiblePart) * REACTION_CONTAINER_SIZE) | 0;
} element.style[/* reactionsMenuPosition === 'vertical' ? 'minHeight' : */'minWidth'] = minSize + 'px';
// } }
// }
}
} }
const side: 'left' | 'right' = bubble.classList.contains('is-in') ? 'left' : 'right'; const side: 'left' | 'right' = bubble.classList.contains('is-in') ? 'left' : 'right';
@ -204,7 +206,7 @@ export default class ChatContextMenu {
if(reactionsMenu) { if(reactionsMenu) {
reactionsMenu.widthContainer.style.top = element.style.top; reactionsMenu.widthContainer.style.top = element.style.top;
reactionsMenu.widthContainer.style.left = element.style.left; reactionsMenu.widthContainer.style.left = element.style.left;
reactionsMenu.widthContainer.style.setProperty('--menu-width', element.offsetWidth + 'px'); reactionsMenu.widthContainer.style.setProperty('--menu-width', element[reactionsMenuPosition === 'vertical' ? 'offsetHeight' : 'offsetWidth'] + 'px');
element.parentElement.append(reactionsMenu.widthContainer); element.parentElement.append(reactionsMenu.widthContainer);
if(isReactionsMenuVisible) void reactionsMenu.container.offsetLeft; // reflow if(isReactionsMenuVisible) void reactionsMenu.container.offsetLeft; // reflow
} }
@ -603,26 +605,28 @@ export default class ChatContextMenu {
let menuPadding: MenuPositionPadding; let menuPadding: MenuPositionPadding;
let reactionsMenu: ChatReactionsMenu; let reactionsMenu: ChatReactionsMenu;
let reactionsMenuPosition: 'horizontal' | 'vertical';
if(this.message._ === 'message' && !this.chat.selection.isSelecting && !this.message.pFlags.is_outgoing && !this.message.pFlags.is_scheduled) { if(this.message._ === 'message' && !this.chat.selection.isSelecting && !this.message.pFlags.is_outgoing && !this.message.pFlags.is_scheduled) {
const position: 'horizontal' | 'vertical' = (IS_APPLE || IS_TOUCH_SUPPORTED)/* && false */ ? 'horizontal' : 'vertical'; reactionsMenuPosition = (IS_APPLE || IS_TOUCH_SUPPORTED)/* && false */ ? 'horizontal' : 'vertical';
reactionsMenu = this.reactionsMenu = new ChatReactionsMenu(this.appReactionsManager, position, this.middleware); reactionsMenu = this.reactionsMenu = new ChatReactionsMenu(this.appReactionsManager, reactionsMenuPosition, this.middleware);
reactionsMenu.init(this.appMessagesManager.getGroupsFirstMessage(this.message)); reactionsMenu.init(this.appMessagesManager.getGroupsFirstMessage(this.message));
// element.prepend(reactionsMenu.widthContainer); // element.prepend(reactionsMenu.widthContainer);
const size = 42; const size = 36;
const margin = 8; const margin = 8;
const totalSize = size + margin; const totalSize = size + margin;
if(position === 'vertical') { const paddingLeft = 0, paddingRight = 0;
if(reactionsMenuPosition === 'vertical') {
menuPadding = { menuPadding = {
top: 24, top: paddingLeft,
// bottom: 36, // positionMenu will detect it itself somehow // bottom: 36, // positionMenu will detect it itself somehow
left: totalSize left: totalSize
}; };
} else { } else {
menuPadding = { menuPadding = {
top: totalSize, top: totalSize,
right: 36, right: paddingRight,
left: 24 left: paddingLeft
}; };
} }
} }
@ -640,7 +644,8 @@ export default class ChatContextMenu {
reactionsMenu.widthContainer.remove(); reactionsMenu.widthContainer.remove();
}, },
menuPadding, menuPadding,
reactionsMenu reactionsMenu,
reactionsMenuPosition
}; };
} }

2
src/components/chat/input.ts

@ -1418,7 +1418,7 @@ export default class ChatInput {
buttons.forEach((button, idx) => { buttons.forEach((button, idx) => {
const peerId = peerIds[idx]; const peerId = peerIds[idx];
const avatar = new AvatarElement(); const avatar = new AvatarElement();
avatar.classList.add('avatar-32', 'btn-menu-item-icon'); avatar.classList.add('avatar-26', 'btn-menu-item-icon');
avatar.updateWithOptions({peerId}); avatar.updateWithOptions({peerId});
if(!idx) { if(!idx) {

9
src/index.ts

@ -124,8 +124,15 @@ document.addEventListener('DOMContentLoaded', async() => {
} }
}); });
// restrict contextmenu on images (e.g. webp stickers)
document.addEventListener('contextmenu', (e) => {
if((e.target as HTMLElement).tagName === 'IMG' && !(window as any).appMediaViewer) {
cancelEvent(e);
}
});
if(IS_FIREFOX) { if(IS_FIREFOX) {
document.documentElement.classList.add('is-firefox'); document.documentElement.classList.add('is-firefox', 'no-backdrop');
} }
if(IS_MOBILE) { if(IS_MOBILE) {

3
src/scss/components/_global.scss

@ -25,7 +25,8 @@ a {
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
} }
img, video { img,
video {
-webkit-user-drag: none; -webkit-user-drag: none;
} }

5
src/scss/partials/_avatar.scss

@ -209,6 +209,11 @@ avatar-element {
--multiplier: 1.6875; --multiplier: 1.6875;
} }
&.avatar-26 {
--size: 26px;
--multiplier: 2.076923;
}
&.avatar-24 { &.avatar-24 {
--size: 24px; --size: 24px;
--multiplier: 2.25; --multiplier: 2.25;

50
src/scss/partials/_button.scss

@ -107,6 +107,31 @@
backdrop-filter: var(--menu-backdrop-filter); backdrop-filter: var(--menu-backdrop-filter);
min-width: 11.25rem; min-width: 11.25rem;
&-old {
padding: .5rem 0;
background-color: var(--surface-color);
backdrop-filter: none;
min-width: auto;
.btn-menu-item {
--padding-left: 1rem;
--padding-right: 2.5rem;
--icon-margin: 1.5rem;
--icon-size: 1.5rem;
height: 3rem;
line-height: var(--line-height-16);
font-size: var(--font-size-16);
border-radius: 0;
margin: 0;
font-weight: 400;
transform: none !important;
&:before {
color: var(--secondary-text-color);
}
}
}
&/* , &/* ,
&-reactions */ { &-reactions */ {
box-shadow: var(--menu-box-shadow); box-shadow: var(--menu-box-shadow);
@ -262,7 +287,7 @@
} }
&-header { &-header {
color: var(--primary-color); color: var(--secondary-text-color);
height: 2rem; height: 2rem;
font-weight: var(--font-weight-bold); font-weight: var(--font-weight-bold);
pointer-events: none !important; pointer-events: none !important;
@ -364,9 +389,10 @@
--height: 2.25rem; --height: 2.25rem;
--bubble-side-offset: 0rem; --bubble-side-offset: 0rem;
--other-side-offset: 0rem; --other-side-offset: 0rem;
--menu-offset: calc((var(--height) + .5rem) * -1);
--width: calc(var(--menu-width) + (var(--bubble-side-offset) + var(--other-side-offset)) * -1); --width: calc(var(--menu-width) + (var(--bubble-side-offset) + var(--other-side-offset)) * -1);
// position: absolute; // position: absolute;
margin-top: calc((var(--height) + .5rem) * -1); margin-top: var(--menu-offset);
width: var(--width); width: var(--width);
max-width: var(--width); max-width: var(--width);
margin-left: var(--other-side-offset); margin-left: var(--other-side-offset);
@ -378,14 +404,29 @@
position: fixed; position: fixed;
z-index: 4; z-index: 4;
.contextmenu.center-left + &,
.contextmenu.bottom-left + & {
.btn-menu-reactions {
transform-origin: bottom right !important;
}
}
.contextmenu.bottom-center + & {
.btn-menu-reactions {
transform-origin: bottom center !important;
}
}
&-vertical { &-vertical {
top: var(--other-side-offset); // top: var(--other-side-offset);
left: calc((var(--height) + .5rem) * -1); // left: calc((var(--height) + .5rem) * -1);
width: var(--height); width: var(--height);
height: var(--width); height: var(--width);
max-width: var(--height); max-width: var(--height);
max-height: var(--width); max-height: var(--width);
flex-direction: column; flex-direction: column;
margin-top: 0;
margin-left: var(--menu-offset);
.btn-menu-reactions { .btn-menu-reactions {
--inner-shadow-degree: 180deg; --inner-shadow-degree: 180deg;
@ -393,6 +434,7 @@
height: auto; height: auto;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
transform-origin: top right;
} }
.btn-menu-reactions-reaction { .btn-menu-reactions-reaction {

20
src/scss/partials/_chat.scss

@ -1314,24 +1314,40 @@ $background-transition-total-time: #{$input-transition-time - $background-transi
transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1);
&-item { &-item {
height: 2.25rem;
&-header {
height: 1.875rem;
}
&-icon { &-icon {
margin-right: calc(var(--icon-margin) - .5rem); margin-right: calc(var(--icon-margin) - .5rem);
&.active:before { &.active:before {
--offset: -.25rem; --offset: -.125rem;
content: " "; content: " ";
position: absolute; position: absolute;
top: var(--offset); top: var(--offset);
right: var(--offset); right: var(--offset);
bottom: var(--offset); bottom: var(--offset);
left: var(--offset); left: var(--offset);
border: .125rem solid var(--primary-color); border: .0625rem solid var(--primary-color);
border-radius: 50%; border-radius: 50%;
} }
} }
&-text { &-text {
@include text-overflow(); @include text-overflow();
// font-size: .875rem !important;
line-height: 1 !important;
display: flex;
flex-direction: column;
justify-content: center;
}
&-subtitle {
font-size: .8125rem;
font-weight: 400;
} }
} }
} }

8
src/scss/partials/_scrollable.scss

@ -31,6 +31,10 @@ html:not(.is-safari):not(.is-ios) {
::-webkit-scrollbar-corner { ::-webkit-scrollbar-corner {
background-color: transparent; background-color: transparent;
} }
.scrollable:hover {
scrollbar-color: var(--scrollbar-color) rgba(0, 0, 0, 0);
}
.scrollable:hover::-webkit-scrollbar { .scrollable:hover::-webkit-scrollbar {
opacity: 1; // for safari opacity: 1; // for safari
@ -81,7 +85,7 @@ html:not(.is-safari):not(.is-ios) {
&.scrollable-x { &.scrollable-x {
overflow-x: auto; overflow-x: auto;
scrollbar-width: thin; // Firefox only scrollbar-width: none; // Firefox only
-ms-overflow-style: none; -ms-overflow-style: none;
} }
@ -89,6 +93,8 @@ html:not(.is-safari):not(.is-ios) {
overflow-y: auto; overflow-y: auto;
overflow-y: overlay; overflow-y: overlay;
scrollbar-width: thin; // Firefox only scrollbar-width: thin; // Firefox only
scrollbar-color: rgba(0, 0, 0, 0) rgba(0, 0, 0, 0);
transition: scrollbar-color .3s ease;
-ms-overflow-style: none; -ms-overflow-style: none;
transform: translateZ(0); transform: translateZ(0);

5
src/scss/style.scss

@ -404,6 +404,11 @@ html.is-ios {
-webkit-touch-callout: none; -webkit-touch-callout: none;
} }
html.no-backdrop {
--menu-background-color: var(--surface-color);
--menu-backdrop-filter: none;
}
@supports(padding: unquote('max(0px)')) { @supports(padding: unquote('max(0px)')) {
html { html {
padding: 0 unquote('min(16px, env(safe-area-inset-right))') 0 unquote('min(16px, env(safe-area-inset-left))'); padding: 0 unquote('min(16px, env(safe-area-inset-right))') 0 unquote('min(16px, env(safe-area-inset-left))');

Loading…
Cancel
Save