Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Implement new Read Receipt design #8389

Merged
merged 15 commits into from
Apr 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions res/css/_components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@
@import "./views/rooms/_NotificationBadge.scss";
@import "./views/rooms/_PinnedEventTile.scss";
@import "./views/rooms/_PresenceLabel.scss";
@import "./views/rooms/_ReadReceiptGroup.scss";
@import "./views/rooms/_RecentlyViewedButton.scss";
@import "./views/rooms/_ReplyPreview.scss";
@import "./views/rooms/_ReplyTile.scss";
Expand Down
4 changes: 2 additions & 2 deletions res/css/views/right_panel/_TimelineCard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ limitations under the License.
padding-left: 36px;
}

.mx_EventTile_readAvatars {
top: -10px;
.mx_ReadReceiptGroup {
top: -6px;
}

.mx_WhoIsTypingTile {
Expand Down
6 changes: 3 additions & 3 deletions res/css/views/rooms/_EventBubbleTile.scss
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ limitations under the License.
}
}

.mx_EventTile_readAvatars {
.mx_ReadReceiptGroup {
position: absolute;
right: -78px; // as close to right gutter without clipping as possible
bottom: 0;
Expand Down Expand Up @@ -585,8 +585,8 @@ limitations under the License.
right: 127px; // align with that of right-column bubbles
}

.mx_EventTile_readAvatars {
right: -18px; // match alignment to RRs of chat bubbles
.mx_ReadReceiptGroup {
right: -14px; // match alignment to RRs of chat bubbles
}

&::before {
Expand Down
44 changes: 6 additions & 38 deletions res/css/views/rooms/_EventTile.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,18 @@ $left-gutter: 64px;

.mx_EventTile_receiptSent,
.mx_EventTile_receiptSending {
// Give it some dimensions so the tooltip can position properly
position: relative;
display: inline-block;
width: 14px;
height: 14px;
// We don't use `position: relative` on the element because then it won't line
// up with the other read receipts
width: 16px;
height: 16px;

&::before {
background-color: $tertiary-content;
mask-repeat: no-repeat;
mask-position: center;
mask-size: 14px;
width: 14px;
height: 14px;
mask-size: 16px;
width: 16px;
height: 16px;
content: '';
position: absolute;
top: 0;
Expand Down Expand Up @@ -349,36 +347,6 @@ $left-gutter: 64px;
}
}

.mx_EventTile_readAvatars {
position: relative;
display: inline-block;
width: 14px;
height: 14px;
// This aligns the avatar with the last line of the
// message. We want to move it one line up - 2.2rem
top: -2.2rem;
user-select: none;
z-index: 1;
}

.mx_EventTile_readAvatars .mx_BaseAvatar {
position: absolute;
display: inline-block;
height: $font-14px;
width: $font-14px;

will-change: left, top;
transition:
left var(--transition-short) ease-out,
top var(--transition-standard) ease-out;
}

.mx_EventTile_readAvatarRemainder {
color: $event-timestamp-color;
font-size: $font-11px;
position: absolute;
}

.mx_EventTile_bigEmoji {
font-size: 48px;
line-height: 57px;
Expand Down
2 changes: 1 addition & 1 deletion res/css/views/rooms/_GroupLayout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ $left-gutter: 64px;
top: 3px;
}

.mx_EventTile_readAvatars {
.mx_ReadReceiptGroup {
// This aligns the avatar with the last line of the
// message. We want to move it one line up - 2rem
top: -2rem;
Expand Down
4 changes: 2 additions & 2 deletions res/css/views/rooms/_IRCLayout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ $irc-line-height: $font-18px;
order: 5;
flex-shrink: 0;

.mx_EventTile_readAvatars {
top: 0.2rem; // ($irc-line-height - avatar height) / 2
.mx_ReadReceiptGroup {
top: -0.3rem; // ($irc-line-height - avatar height) / 2
}
}

Expand Down
146 changes: 146 additions & 0 deletions res/css/views/rooms/_ReadReceiptGroup.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

.mx_ReadReceiptGroup {
justjanne marked this conversation as resolved.
Show resolved Hide resolved
position: relative;
display: inline-block;
// This aligns the avatar with the last line of the
// message. We want to move it one line up
// See .mx_GroupLayout .mx_EventTile .mx_EventTile_line in _GroupLayout.scss
top: calc(-$font-22px - 3px);
user-select: none;
z-index: 1;

.mx_ReadReceiptGroup_button {
display: inline-flex;
flex-direction: row;
height: 16px;
padding: 4px;
border-radius: 6px;

&.mx_AccessibleButton {
&:hover {
background: $event-selected-color;
}
}
}

.mx_ReadReceiptGroup_remainder {
color: $secondary-content;
font-size: $font-11px;
line-height: $font-16px;
margin-right: 4px;
}

.mx_ReadReceiptGroup_container {
position: relative;
display: block;
height: 100%;

.mx_BaseAvatar {
position: absolute;
display: inline-block;
height: 14px;
width: 14px;
border: 1px solid $background;
border-radius: 100%;

will-change: left, top;
transition:
left var(--transition-short) ease-out,
top var(--transition-standard) ease-out;
}
}
}

.mx_ReadReceiptGroup_popup {
max-height: 300px;
width: 220px;
border-radius: 8px;
display: flex;
flex-direction: column;
text-align: left;
font-size: 12px;
line-height: 15px;

right: 0;

&.mx_ContextualMenu_top {
top: 8px;
}

&.mx_ContextualMenu_bottom {
bottom: 8px;
}

.mx_ReadReceiptGroup_title {
font-size: 12px;
line-height: 15px;
margin: 16px 16px 8px;
font-weight: 600;
// shouldn’t be actually focusable
outline: none;
}

.mx_AutoHideScrollbar {
.mx_ReadReceiptGroup_person {
display: flex;
flex-direction: row;
padding: 4px;
margin: 0 12px;
border-radius: 8px;

&:hover {
background: $menu-selected-color;
}

&:last-child {
margin-bottom: 8px;
}

.mx_BaseAvatar {
margin: 6px 8px;
align-self: center;
justify-self: center;
}

.mx_ReadReceiptGroup_name {
display: flex;
flex-direction: column;
flex-grow: 1;
flex-shrink: 1;
overflow: hidden;

p {
margin: 2px 0;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}

.mx_ReadReceiptGroup_secondary {
color: $secondary-content;
}
}
}
}
}

.mx_ReadReceiptGroup_person--tooltip {
overflow-y: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
16 changes: 12 additions & 4 deletions src/accessibility/roving/RovingAccessibleButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,21 @@ import AccessibleButton from "../../components/views/elements/AccessibleButton";
import { useRovingTabIndex } from "../RovingTabIndex";
import { Ref } from "./types";

interface IProps extends Omit<React.ComponentProps<typeof AccessibleButton>, "onFocus" | "inputRef" | "tabIndex"> {
interface IProps extends Omit<React.ComponentProps<typeof AccessibleButton>, "inputRef" | "tabIndex"> {
inputRef?: Ref;
}

// Wrapper to allow use of useRovingTabIndex for simple AccessibleButtons outside of React Functional Components.
export const RovingAccessibleButton: React.FC<IProps> = ({ inputRef, ...props }) => {
const [onFocus, isActive, ref] = useRovingTabIndex(inputRef);
return <AccessibleButton {...props} onFocus={onFocus} inputRef={ref} tabIndex={isActive ? 0 : -1} />;
export const RovingAccessibleButton: React.FC<IProps> = ({ inputRef, onFocus, ...props }) => {
const [onFocusInternal, isActive, ref] = useRovingTabIndex(inputRef);
return <AccessibleButton
{...props}
onFocus={event => {
onFocusInternal();
onFocus?.(event);
}}
inputRef={ref}
tabIndex={isActive ? 0 : -1}
/>;
};

16 changes: 12 additions & 4 deletions src/accessibility/roving/RovingAccessibleTooltipButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,21 @@ import { useRovingTabIndex } from "../RovingTabIndex";
import { Ref } from "./types";

type ATBProps = React.ComponentProps<typeof AccessibleTooltipButton>;
interface IProps extends Omit<ATBProps, "onFocus" | "inputRef" | "tabIndex"> {
interface IProps extends Omit<ATBProps, "inputRef" | "tabIndex"> {
inputRef?: Ref;
}

// Wrapper to allow use of useRovingTabIndex for simple AccessibleTooltipButtons outside of React Functional Components.
export const RovingAccessibleTooltipButton: React.FC<IProps> = ({ inputRef, ...props }) => {
const [onFocus, isActive, ref] = useRovingTabIndex(inputRef);
return <AccessibleTooltipButton {...props} onFocus={onFocus} inputRef={ref} tabIndex={isActive ? 0 : -1} />;
export const RovingAccessibleTooltipButton: React.FC<IProps> = ({ inputRef, onFocus, ...props }) => {
const [onFocusInternal, isActive, ref] = useRovingTabIndex(inputRef);
return <AccessibleTooltipButton
{...props}
onFocus={event => {
onFocusInternal();
onFocus?.(event);
}}
inputRef={ref}
tabIndex={isActive ? 0 : -1}
/>;
};

3 changes: 2 additions & 1 deletion src/components/structures/ContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export interface IProps extends IPosition {
// whether this context menu should be focus managed. If false it must handle itself
managed?: boolean;
wrapperClassName?: string;
menuClassName?: string;

// If true, this context menu will be mounted as a child to the parent container. Otherwise
// it will be mounted to a container at the root of the DOM.
Expand Down Expand Up @@ -319,7 +320,7 @@ export default class ContextMenu extends React.PureComponent<IProps, IState> {
'mx_ContextualMenu_withChevron_bottom': chevronFace === ChevronFace.Bottom,
'mx_ContextualMenu_rightAligned': this.props.rightAligned === true,
'mx_ContextualMenu_bottomAligned': this.props.bottomAligned === true,
});
}, this.props.menuClassName);

const menuStyle: CSSProperties = {};
if (props.menuWidth) {
Expand Down
1 change: 1 addition & 0 deletions src/components/views/avatars/BaseAvatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ interface IProps {
onClick?: React.MouseEventHandler;
inputRef?: React.RefObject<HTMLImageElement & HTMLSpanElement>;
className?: string;
tabIndex?: number;
}

const calculateUrls = (url, urls, lowBandwidth) => {
Expand Down
3 changes: 2 additions & 1 deletion src/components/views/avatars/MemberAvatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ interface IProps extends Omit<React.ComponentProps<typeof BaseAvatar>, "name" |
title?: string;
style?: any;
forceHistorical?: boolean; // true to deny `feature_use_only_current_profiles` usage. Default false.
hideTitle?: boolean;
}

interface IState {
Expand Down Expand Up @@ -124,7 +125,7 @@ export default class MemberAvatar extends React.PureComponent<IProps, IState> {
<BaseAvatar
{...otherProps}
name={this.state.name}
title={this.state.title}
title={this.props.hideTitle ? undefined : this.state.title}
idName={userId}
url={this.state.imageUrl}
onClick={onClick}
Expand Down
12 changes: 12 additions & 0 deletions src/components/views/elements/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export enum Alignment {
Top, // Centered
Bottom, // Centered
InnerBottom, // Inside the target, at the bottom
TopRight, // On top of the target, right aligned
TopCenter, // On top of the target, center aligned
}

export interface ITooltipProps {
Expand Down Expand Up @@ -149,6 +151,16 @@ export default class Tooltip extends React.Component<ITooltipProps> {
style.top = baseTop + parentBox.height - 50;
style.left = horizontalCenter;
style.transform = "translate(-50%)";
break;
case Alignment.TopRight:
style.top = baseTop - 5;
style.right = width - parentBox.right - window.pageXOffset;
style.transform = "translate(5px, -100%)";
break;
case Alignment.TopCenter:
style.top = baseTop - 5;
style.left = horizontalCenter;
style.transform = "translate(-50%, -100%)";
}

return style;
Expand Down
Loading