fix: improved reaction alignment based on avatar visibility

This commit is contained in:
William Grant 2023-02-02 14:09:07 +11:00
parent 828f1923a0
commit a8b8692016
6 changed files with 33 additions and 27 deletions

View File

@ -129,13 +129,6 @@ textarea {
font-style: normal;
}
.module-message__author-avatar {
position: relative;
margin-inline-end: 20px;
padding-top: 5px;
padding-inline-end: 4px;
}
.module-message--incoming {
margin-inline-start: 0;
margin-inline-end: auto;

View File

@ -1,5 +1,6 @@
import React, { useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import styled from 'styled-components';
import { OpenGroupData } from '../../../../data/opengroups';
import { MessageRenderingProps } from '../../../../models/messageType';
import { findCachedBlindedMatchOrLookItUp } from '../../../../session/apis/open_group_api/sogsv3/knownBlindedkeys';
@ -16,6 +17,13 @@ import {
import { Avatar, AvatarSize, CrownIcon } from '../../../avatar/Avatar';
// tslint:disable: use-simple-attributes
const StyledAvatar = styled.div`
position: relative;
margin-inline-end: 20px;
padding-top: 5px;
padding-inline-end: 4px;
`;
export type MessageAvatarSelectorProps = Pick<
MessageRenderingProps,
| 'authorAvatarPath'
@ -23,16 +31,14 @@ export type MessageAvatarSelectorProps = Pick<
| 'sender'
| 'authorProfileName'
| 'isSenderAdmin'
| 'conversationType'
| 'direction'
| 'isPublic'
| 'lastMessageOfSeries'
>;
type Props = { messageId: string };
type Props = { messageId: string; noAvatar: boolean };
export const MessageAvatar = (props: Props) => {
const { messageId } = props;
const { messageId, noAvatar } = props;
const dispatch = useDispatch();
const avatarProps = useSelector(state => getMessageAvatarProps(state as any, messageId));
@ -43,21 +49,21 @@ export const MessageAvatar = (props: Props) => {
if (!avatarProps) {
return null;
}
const {
authorAvatarPath,
authorName,
sender,
authorProfileName,
conversationType,
direction,
isSenderAdmin,
lastMessageOfSeries,
isPublic,
} = avatarProps;
if (conversationType !== 'group' || direction === 'outgoing') {
if (noAvatar) {
return null;
}
const userName = authorName || authorProfileName || sender;
const onMessageAvatarClick = useCallback(async () => {
@ -122,9 +128,9 @@ export const MessageAvatar = (props: Props) => {
}
return (
<div className="module-message__author-avatar" key={`msg-avatar-${sender}`}>
<StyledAvatar key={`msg-avatar-${sender}`}>
<Avatar size={AvatarSize.S} onAvatarClick={onMessageAvatarClick} pubkey={sender} />
{isSenderAdmin && <CrownIcon />}
</div>
</StyledAvatar>
);
};

View File

@ -20,7 +20,7 @@ import { MessageStatus } from './MessageStatus';
export type MessageContentWithStatusSelectorProps = Pick<
MessageRenderingProps,
'direction' | 'isDeleted'
'conversationType' | 'direction' | 'isDeleted'
>;
type Props = {
@ -40,7 +40,7 @@ const StyledMessageContentContainer = styled.div<{ direction: 'left' | 'right' }
width: 100%;
${StyledMessageReactions} {
margin-right: var(--margins-sm);
margin-right: var(--margins-md);
}
`;
@ -88,11 +88,13 @@ export const MessageContentWithStatuses = (props: Props) => {
};
const { messageId, ctxMenuID, isDetailView, dataTestId, enableReactions } = props;
if (!contentProps) {
return null;
}
const { direction, isDeleted } = contentProps;
const { conversationType, direction, isDeleted } = contentProps;
const isIncoming = direction === 'incoming';
const noAvatar = conversationType !== 'group' || direction === 'outgoing';
const [popupReaction, setPopupReaction] = useState('');
@ -118,7 +120,7 @@ export const MessageContentWithStatuses = (props: Props) => {
onDoubleClickCapture={onDoubleClickReplyToMessage}
data-testid={dataTestId}
>
<MessageAvatar messageId={messageId} />
<MessageAvatar messageId={messageId} noAvatar={noAvatar} />
<MessageStatus
dataTestId="msg-status-incoming"
messageId={messageId}
@ -148,6 +150,7 @@ export const MessageContentWithStatuses = (props: Props) => {
popupReaction={popupReaction}
setPopupReaction={setPopupReaction}
onPopupClick={handlePopupClick}
noAvatar={noAvatar}
/>
)}
</StyledMessageContentContainer>

View File

@ -15,15 +15,15 @@ import { useSelector } from 'react-redux';
export const popupXDefault = -81;
export const popupYDefault = -90;
const StyledMessageReactionsContainer = styled(Flex)<{ x: number; y: number }>`
div:first-child {
margin-left: 1.7rem;
}
const StyledMessageReactionsContainer = styled(Flex)<{ x: number; y: number; noAvatar: boolean }>`
${StyledPopupContainer} {
position: absolute;
top: ${props => `${props.y}px;`};
left: ${props => `${props.x}px;`};
}
// MessageAvatar width + margin-inline-end
${props => !props.noAvatar && 'margin-inline-start: calc(36px + 20px);'}
`;
export const StyledMessageReactions = styled(Flex)<{ fullWidth: boolean }>`
@ -118,13 +118,13 @@ const CompressedReactions = (props: ExpandReactionsProps): ReactElement => {
const ExpandedReactions = (props: ExpandReactionsProps): ReactElement => {
const { handleExpand } = props;
return (
<>
<Flex container={true} flexDirection={'column'} alignItems={'center'} margin="4px 0 0">
<Reactions {...props} />
<StyledReadLess onClick={handleExpand}>
<SessionIcon iconType="chevron" iconSize="medium" iconRotation={180} />
{window.i18n('expandedReactionsText')}
</StyledReadLess>
</>
</Flex>
);
};
@ -142,6 +142,7 @@ type Props = {
onPopupClick?: () => void;
inModal?: boolean;
onSelected?: (emoji: string) => boolean;
noAvatar: boolean;
};
export const MessageReactions = (props: Props): ReactElement => {
@ -154,6 +155,7 @@ export const MessageReactions = (props: Props): ReactElement => {
onPopupClick,
inModal = false,
onSelected,
noAvatar,
} = props;
const [reactions, setReactions] = useState<SortedReactionList>([]);
@ -211,6 +213,7 @@ export const MessageReactions = (props: Props): ReactElement => {
alignItems={inModal ? 'flex-start' : 'center'}
x={popupX}
y={popupY}
noAvatar={noAvatar}
>
{sortedReacts &&
sortedReacts?.length !== 0 &&

View File

@ -329,6 +329,7 @@ export const ReactListModal = (props: Props): ReactElement => {
inModal={true}
onSelected={handleSelectedReaction}
onClick={handleReactionClick}
noAvatar={true}
/>
</StyledReactionsContainer>
{reactionsMap && currentReact && (

View File

@ -1129,7 +1129,7 @@ export const getMessageContentWithStatusesSelectorProps = createSelector(
}
const msgProps: MessageContentWithStatusSelectorProps = {
...pick(props.propsForMessage, ['direction', 'isDeleted']),
...pick(props.propsForMessage, ['conversationType', 'direction', 'isDeleted']),
};
return msgProps;