fix: drop shadow renders correctly

moved to individual text and image attachments, need to check the other attachment types
pull/3020/head
William Grant 3 months ago
parent b34bf1380a
commit 0ecdcd93a0

@ -134,7 +134,6 @@ textarea {
.module-message__container {
position: relative;
display: inline-block;
overflow: hidden;
min-width: 30px;
// To limit messages with things forcing them wider, like long attachment names.
width: 100%;

@ -24,6 +24,7 @@ type Props = {
playIconOverlay?: boolean;
softCorners: boolean;
forceSquare?: boolean;
dropShadow?: boolean;
attachmentIndex?: number;
onClick?: (attachment: AttachmentTypeWithPath | AttachmentType) => void;
@ -55,6 +56,7 @@ export const Image = (props: Props) => {
playIconOverlay,
softCorners,
forceSquare,
dropShadow,
attachmentIndex,
url,
width: _width,
@ -101,6 +103,7 @@ export const Image = (props: Props) => {
maxWidth: width,
minHeight: height,
minWidth: width,
boxShadow: dropShadow ? 'var(--drop-shadow)' : undefined,
}}
data-attachmentindex={attachmentIndex}
>

@ -10,14 +10,16 @@ import {
isVideoAttachment,
} from '../../types/Attachment';
import { useMessageSelected } from '../../state/selectors';
import { THUMBNAIL_SIDE } from '../../types/attachments/VisualAttachment';
import { Image } from './Image';
import { IsMessageVisibleContext } from './message/message-content/MessageContent';
import { THUMBNAIL_SIDE } from '../../types/attachments/VisualAttachment';
type Props = {
attachments: Array<AttachmentTypeWithPath>;
onError: () => void;
onClickAttachment?: (attachment: AttachmentTypeWithPath | AttachmentType) => void;
messageId?: string;
};
const StyledImageGrid = styled.div<{ flexDirection: 'row' | 'column' }>`
@ -28,7 +30,12 @@ const StyledImageGrid = styled.div<{ flexDirection: 'row' | 'column' }>`
`;
const Row = (
props: Props & { renderedSize: number; startIndex: number; totalAttachmentsCount: number }
props: Props & {
renderedSize: number;
startIndex: number;
totalAttachmentsCount: number;
selected: boolean;
}
) => {
const {
attachments,
@ -37,6 +44,7 @@ const Row = (
startIndex,
onClickAttachment,
totalAttachmentsCount,
selected,
} = props;
const isMessageVisible = useContext(IsMessageVisibleContext);
const moreMessagesOverlay = totalAttachmentsCount > 3;
@ -61,6 +69,7 @@ const Row = (
softCorners={true}
darkOverlay={showOverlay}
overlayText={showOverlay ? moreMessagesOverlayText : undefined}
dropShadow={selected}
/>
);
})}
@ -69,7 +78,9 @@ const Row = (
};
export const ImageGrid = (props: Props) => {
const { attachments, onError, onClickAttachment } = props;
const { attachments, onError, onClickAttachment, messageId } = props;
const selected = useMessageSelected(messageId);
if (!attachments || !attachments.length) {
return null;
@ -85,6 +96,7 @@ export const ImageGrid = (props: Props) => {
renderedSize={THUMBNAIL_SIDE}
startIndex={0}
totalAttachmentsCount={attachments.length}
selected={selected}
/>
</StyledImageGrid>
);
@ -101,6 +113,7 @@ export const ImageGrid = (props: Props) => {
renderedSize={THUMBNAIL_SIDE}
startIndex={0}
totalAttachmentsCount={attachments.length}
selected={selected}
/>
</StyledImageGrid>
);
@ -118,6 +131,7 @@ export const ImageGrid = (props: Props) => {
renderedSize={THUMBNAIL_SIDE}
startIndex={0}
totalAttachmentsCount={attachments.length}
selected={selected}
/>
<StyledImageGrid flexDirection={'column'}>
@ -128,6 +142,7 @@ export const ImageGrid = (props: Props) => {
renderedSize={columnImageSide}
startIndex={1}
totalAttachmentsCount={attachments.length}
selected={selected}
/>
</StyledImageGrid>
</StyledImageGrid>

@ -51,8 +51,7 @@ type Props = SessionMessageListProps & {
scrollToNow: () => Promise<void>;
};
// isGroup is used to align the ExpireTimer with the member avatars
const StyledMessagesContainer = styled.div<{ isGroup: boolean }>`
const StyledMessagesContainer = styled.div`
display: flex;
flex-grow: 1;
gap: var(--margins-sm);
@ -61,12 +60,8 @@ const StyledMessagesContainer = styled.div<{ isGroup: boolean }>`
overflow-x: hidden;
min-width: 370px;
scrollbar-width: 4px;
// TODO fixing spacing around messages when in multi-select mode
/* padding-top: var(--margins-sm);
padding-right: var(--margins-lg);
padding-top: var(--margins-sm);
padding-bottom: var(--margins-xl);
padding-left: ${props => (props.isGroup ? 'var(--margins-xs)' : 'var(--margins-lg)')}; */
.session-icon-button {
display: flex;
@ -127,7 +122,6 @@ class SessionMessagesListContainerInner extends React.Component<Props> {
<StyledMessagesContainer
className="messages-container"
id={messageContainerDomID}
isGroup={!conversation.isPrivate}
onScroll={this.handleScroll}
ref={this.props.messageContainerRef}
data-testid="messages-container"

@ -32,7 +32,7 @@ import { AudioPlayerWithEncryptedFile } from '../../H5AudioPlayer';
import { ImageGrid } from '../../ImageGrid';
import { LightBoxOptions } from '../../SessionConversation';
import { ClickToTrustSender } from './ClickToTrustSender';
import { StyledMessageHighlighter } from './MessageContent';
import { MessageHighlighter } from './MessageHighlighter';
export type MessageAttachmentSelectorProps = Pick<
MessageRenderingProps,
@ -138,21 +138,22 @@ export const MessageAttachment = (props: Props) => {
(isVideo(attachments) && hasVideoScreenshot(attachments)))
) {
return (
<StyledMessageHighlighter highlight={highlight}>
<MessageHighlighter highlight={highlight}>
<StyledAttachmentContainer messageDirection={direction}>
<ImageGrid
messageId={messageId}
attachments={attachments}
onError={handleImageError}
onClickAttachment={onClickOnImageGrid}
/>
</StyledAttachmentContainer>
</StyledMessageHighlighter>
</MessageHighlighter>
);
}
if (!firstAttachment.pending && !firstAttachment.error && isAudio(attachments)) {
return (
<StyledMessageHighlighter
<MessageHighlighter
highlight={highlight}
role="main"
onClick={(e: any) => {
@ -168,14 +169,14 @@ export const MessageAttachment = (props: Props) => {
contentType={firstAttachment.contentType}
messageId={messageId}
/>
</StyledMessageHighlighter>
</MessageHighlighter>
);
}
const { pending, fileName, fileSize, contentType } = firstAttachment;
const extension = getExtensionForDisplay({ contentType, fileName });
return (
<StyledMessageHighlighter highlight={highlight} className="module-message__generic-attachment">
<MessageHighlighter highlight={highlight} className="module-message__generic-attachment">
{pending ? (
<div className="module-message__generic-attachment__spinner-container">
<Spinner size="small" />
@ -211,7 +212,7 @@ export const MessageAttachment = (props: Props) => {
{fileSize}
</div>
</div>
</StyledMessageHighlighter>
</MessageHighlighter>
);
};

@ -4,10 +4,14 @@ import moment from 'moment';
import React, { createContext, useCallback, useContext, useLayoutEffect, useState } from 'react';
import { InView } from 'react-intersection-observer';
import { useSelector } from 'react-redux';
import styled, { css, keyframes } from 'styled-components';
import styled from 'styled-components';
import { MessageModelType, MessageRenderingProps } from '../../../../models/messageType';
import { StateType } from '../../../../state/reducer';
import { useHideAvatarInMsgList, useMessageIsDeleted } from '../../../../state/selectors';
import {
useHideAvatarInMsgList,
useMessageIsDeleted,
useMessageSelected,
} from '../../../../state/selectors';
import {
getMessageContentSelectorProps,
getQuotedMessageToAnimate,
@ -21,6 +25,7 @@ import { canDisplayImage } from '../../../../types/Attachment';
import { ScrollToLoadedMessageContext } from '../../SessionMessagesListContainer';
import { MessageAttachment } from './MessageAttachment';
import { MessageAvatar } from './MessageAvatar';
import { MessageHighlighter } from './MessageHighlighter';
import { MessageLinkPreview } from './MessageLinkPreview';
import { MessageQuote } from './MessageQuote';
import { MessageText } from './MessageText';
@ -58,37 +63,10 @@ const StyledMessageContent = styled.div<{ msgDirection: MessageModelType }>`
align-self: ${props => (props.msgDirection === 'incoming' ? 'flex-start' : 'flex-end')};
`;
const opacityAnimation = keyframes`
0% {
opacity: 1;
}
25% {
opacity: 0.2;
}
50% {
opacity: 1;
}
75% {
opacity: 0.2;
}
100% {
opacity: 1;
}
`;
export const StyledMessageHighlighter = styled.div<{
highlight: boolean;
}>`
${props =>
props.highlight &&
css`
animation: ${opacityAnimation} 1s linear;
`}
`;
const StyledMessageOpaqueContent = styled(StyledMessageHighlighter)<{
const StyledMessageOpaqueContent = styled(MessageHighlighter)<{
isIncoming: boolean;
highlight: boolean;
selected: boolean;
}>`
background: ${props =>
props.isIncoming
@ -98,6 +76,8 @@ const StyledMessageOpaqueContent = styled(StyledMessageHighlighter)<{
padding: var(--padding-message-content);
border-radius: var(--border-radius-message-box);
width: 100%;
${props => props.selected && `box-shadow: var(--drop-shadow);`}
`;
export const IsMessageVisibleContext = createContext(false);
@ -125,7 +105,7 @@ export const MessageContent = (props: Props) => {
const [imageBroken, setImageBroken] = useState(false);
const onVisible = (inView: boolean, _: IntersectionObserverEntry) => {
// TODO check if there is no issue with focus after simplifiying the check
// TODO[epic=ses-1409] check if there is no issue with focus after simplifiying the check
if (inView) {
if (isMessageVisible !== true) {
setMessageIsVisible(true);
@ -140,7 +120,7 @@ export const MessageContent = (props: Props) => {
const quotedMessageToAnimate = useSelector(getQuotedMessageToAnimate);
const shouldHighlightMessage = useSelector(getShouldHighlightMessage);
const isQuotedMessageToAnimate = quotedMessageToAnimate === props.messageId;
// const selected = useMessageSelected(props.messageId);
const selected = useMessageSelected(props.messageId);
useLayoutEffect(() => {
if (isQuotedMessageToAnimate) {
@ -222,7 +202,11 @@ export const MessageContent = (props: Props) => {
>
<IsMessageVisibleContext.Provider value={isMessageVisible}>
{hasContentBeforeAttachment && (
<StyledMessageOpaqueContent isIncoming={direction === 'incoming'} highlight={highlight}>
<StyledMessageOpaqueContent
isIncoming={direction === 'incoming'}
highlight={highlight}
selected={selected}
>
{!isDeleted && (
<>
<MessageQuote messageId={props.messageId} />

@ -0,0 +1,29 @@
import styled, { css, keyframes } from 'styled-components';
const opacityAnimation = keyframes`
0% {
opacity: 1;
}
25% {
opacity: 0.2;
}
50% {
opacity: 1;
}
75% {
opacity: 0.2;
}
100% {
opacity: 1;
}
`;
export const MessageHighlighter = styled.div<{
highlight: boolean;
}>`
${props =>
props.highlight &&
css`
animation: ${opacityAnimation} 1s linear;
`}
`;
Loading…
Cancel
Save