Merge pull request #2612 from tomobre/fix/messages-avatar-bottom

fix: avatar at bottom, reacts with margin
pull/2658/head
Audric Ackermann 2 years ago committed by GitHub
commit 8584edf302
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

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

@ -25,7 +25,7 @@
position: relative; position: relative;
display: inline-flex; display: inline-flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: flex-end;
max-width: 95%; max-width: 95%;
@media (min-width: 1200px) { @media (min-width: 1200px) {

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

@ -11,7 +11,7 @@ import {
isMessageSelectionMode, isMessageSelectionMode,
} from '../../../../state/selectors/conversations'; } from '../../../../state/selectors/conversations';
import { Reactions } from '../../../../util/reactions'; import { Reactions } from '../../../../util/reactions';
import { MessageAvatar } from '../message-content/MessageAvatar';
import { MessageAuthorText } from './MessageAuthorText'; import { MessageAuthorText } from './MessageAuthorText';
import { MessageContent } from './MessageContent'; import { MessageContent } from './MessageContent';
import { MessageContextMenu } from './MessageContextMenu'; import { MessageContextMenu } from './MessageContextMenu';
@ -20,7 +20,7 @@ import { MessageStatus } from './MessageStatus';
export type MessageContentWithStatusSelectorProps = Pick< export type MessageContentWithStatusSelectorProps = Pick<
MessageRenderingProps, MessageRenderingProps,
'direction' | 'isDeleted' 'conversationType' | 'direction' | 'isDeleted'
>; >;
type Props = { type Props = {
@ -40,7 +40,7 @@ const StyledMessageContentContainer = styled.div<{ direction: 'left' | 'right' }
width: 100%; width: 100%;
${StyledMessageReactions} { ${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; const { messageId, ctxMenuID, isDetailView, dataTestId, enableReactions } = props;
if (!contentProps) { if (!contentProps) {
return null; return null;
} }
const { direction, isDeleted } = contentProps; const { conversationType, direction, isDeleted } = contentProps;
const isIncoming = direction === 'incoming'; const isIncoming = direction === 'incoming';
const noAvatar = conversationType !== 'group' || direction === 'outgoing';
const [popupReaction, setPopupReaction] = useState(''); const [popupReaction, setPopupReaction] = useState('');
@ -118,6 +120,7 @@ export const MessageContentWithStatuses = (props: Props) => {
onDoubleClickCapture={onDoubleClickReplyToMessage} onDoubleClickCapture={onDoubleClickReplyToMessage}
data-testid={dataTestId} data-testid={dataTestId}
> >
<MessageAvatar messageId={messageId} noAvatar={noAvatar} />
<MessageStatus <MessageStatus
dataTestId="msg-status-incoming" dataTestId="msg-status-incoming"
messageId={messageId} messageId={messageId}
@ -125,7 +128,6 @@ export const MessageContentWithStatuses = (props: Props) => {
/> />
<StyledMessageWithAuthor isIncoming={isIncoming}> <StyledMessageWithAuthor isIncoming={isIncoming}>
<MessageAuthorText messageId={messageId} /> <MessageAuthorText messageId={messageId} />
<MessageContent messageId={messageId} isDetailView={isDetailView} /> <MessageContent messageId={messageId} isDetailView={isDetailView} />
</StyledMessageWithAuthor> </StyledMessageWithAuthor>
<MessageStatus <MessageStatus
@ -148,6 +150,7 @@ export const MessageContentWithStatuses = (props: Props) => {
popupReaction={popupReaction} popupReaction={popupReaction}
setPopupReaction={setPopupReaction} setPopupReaction={setPopupReaction}
onPopupClick={handlePopupClick} onPopupClick={handlePopupClick}
noAvatar={noAvatar}
/> />
)} )}
</StyledMessageContentContainer> </StyledMessageContentContainer>

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

@ -16,7 +16,7 @@ import {
} from '../../../../state/selectors/conversations'; } from '../../../../state/selectors/conversations';
import { getIncrement } from '../../../../util/timer'; import { getIncrement } from '../../../../util/timer';
import { ExpireTimer } from '../../ExpireTimer'; import { ExpireTimer } from '../../ExpireTimer';
import { MessageAvatar } from '../message-content/MessageAvatar';
import { MessageContentWithStatuses } from '../message-content/MessageContentWithStatus'; import { MessageContentWithStatuses } from '../message-content/MessageContentWithStatus';
import { ReadableMessage } from './ReadableMessage'; import { ReadableMessage } from './ReadableMessage';
import styled, { keyframes } from 'styled-components'; import styled, { keyframes } from 'styled-components';
@ -238,7 +238,6 @@ export const GenericReadableMessage = (props: Props) => {
isUnread={!!isUnread} isUnread={!!isUnread}
key={`readable-message-${messageId}`} key={`readable-message-${messageId}`}
> >
<MessageAvatar messageId={messageId} />
{expirationLength && expirationTimestamp && ( {expirationLength && expirationTimestamp && (
<ExpireTimer <ExpireTimer
isCorrectSide={!isIncoming} isCorrectSide={!isIncoming}

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

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

Loading…
Cancel
Save