mirror of
https://github.com/oxen-io/session-desktop.git
synced 2023-12-14 02:12:57 +01:00
uniformized props for Message
This commit is contained in:
parent
ee4a0b9b1e
commit
f0fad6edfa
10 changed files with 59 additions and 69 deletions
|
@ -5,7 +5,7 @@ import { Emojify } from './Emojify';
|
|||
|
||||
type Props = {
|
||||
phoneNumber: string;
|
||||
name?: string;
|
||||
name?: string | null;
|
||||
profileName?: string;
|
||||
module?: string;
|
||||
boldProfileName?: Boolean;
|
||||
|
|
|
@ -29,7 +29,6 @@ import _ from 'lodash';
|
|||
import { animation, contextMenu, Item, Menu } from 'react-contexify';
|
||||
import uuid from 'uuid';
|
||||
import { InView } from 'react-intersection-observer';
|
||||
import { withTheme } from 'styled-components';
|
||||
import { MessageMetadata } from './message/MessageMetadata';
|
||||
import { PubKey } from '../../session/types';
|
||||
import { MessageRegularProps } from '../../models/messageType';
|
||||
|
@ -56,7 +55,7 @@ interface State {
|
|||
const EXPIRATION_CHECK_MINIMUM = 2000;
|
||||
const EXPIRED_DELAY = 600;
|
||||
|
||||
class MessageInner extends React.PureComponent<MessageRegularProps, State> {
|
||||
export class Message extends React.PureComponent<MessageRegularProps, State> {
|
||||
public expirationCheckInterval: any;
|
||||
public expiredTimeout: any;
|
||||
public ctxMenuID: string;
|
||||
|
@ -279,14 +278,7 @@ class MessageInner extends React.PureComponent<MessageRegularProps, State> {
|
|||
|
||||
// tslint:disable-next-line cyclomatic-complexity
|
||||
public renderPreview() {
|
||||
const {
|
||||
attachments,
|
||||
conversationType,
|
||||
direction,
|
||||
onClickLinkPreview,
|
||||
previews,
|
||||
quote,
|
||||
} = this.props;
|
||||
const { attachments, conversationType, direction, previews, quote } = this.props;
|
||||
|
||||
// Attachments take precedence over Link Previews
|
||||
if (attachments && attachments.length) {
|
||||
|
@ -316,11 +308,6 @@ class MessageInner extends React.PureComponent<MessageRegularProps, State> {
|
|||
'module-message__link-preview',
|
||||
withContentAbove ? 'module-message__link-preview--with-content-above' : null
|
||||
)}
|
||||
onClick={() => {
|
||||
if (onClickLinkPreview) {
|
||||
onClickLinkPreview(first.url);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{first.image && previewHasImage && isFullSizeImage ? (
|
||||
<ImageGrid
|
||||
|
@ -898,5 +885,3 @@ class MessageInner extends React.PureComponent<MessageRegularProps, State> {
|
|||
await removeSenderFromModerator(this.props.authorPhoneNumber, this.props.convoId);
|
||||
}
|
||||
}
|
||||
|
||||
export const Message = withTheme(MessageInner);
|
||||
|
|
|
@ -4,25 +4,24 @@ import { OutgoingMessageStatus } from './OutgoingMessageStatus';
|
|||
import { MetadataBadges } from './MetadataBadge';
|
||||
import { Timestamp } from '../Timestamp';
|
||||
import { ExpireTimer } from '../ExpireTimer';
|
||||
import styled, { DefaultTheme } from 'styled-components';
|
||||
import styled, { DefaultTheme, useTheme } from 'styled-components';
|
||||
import { MessageDeliveryStatus, MessageModelType } from '../../../models/messageType';
|
||||
|
||||
type Props = {
|
||||
disableMenu?: boolean;
|
||||
isAdmin?: boolean;
|
||||
isDeletable: boolean;
|
||||
text?: string;
|
||||
text?: string | null;
|
||||
id: string;
|
||||
collapseMetadata?: boolean;
|
||||
direction: MessageModelType;
|
||||
timestamp: number;
|
||||
serverTimestamp?: number;
|
||||
status?: MessageDeliveryStatus;
|
||||
status?: MessageDeliveryStatus | null;
|
||||
expirationLength?: number;
|
||||
expirationTimestamp?: number;
|
||||
isPublic?: boolean;
|
||||
isShowingImage: boolean;
|
||||
theme: DefaultTheme;
|
||||
};
|
||||
// for some reason, we have to extend a styled component as this:
|
||||
// props => <OpacityMetadataComponent {...props}/>
|
||||
|
@ -68,9 +67,10 @@ export const MessageMetadata = (props: Props) => {
|
|||
isShowingImage,
|
||||
isPublic,
|
||||
isAdmin,
|
||||
theme,
|
||||
} = props;
|
||||
|
||||
const theme = useTheme();
|
||||
|
||||
if (collapseMetadata) {
|
||||
return null;
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ export const MessageMetadata = (props: Props) => {
|
|||
const showError = status === 'error' && isOutgoing;
|
||||
|
||||
const showStatus = Boolean(status?.length && isOutgoing);
|
||||
const messageStatusColor = withImageNoCaption ? 'white' : props.theme.colors.sentMessageText;
|
||||
const messageStatusColor = withImageNoCaption ? 'white' : theme.colors.sentMessageText;
|
||||
return (
|
||||
<MetadatasContainer withImageNoCaption={withImageNoCaption} {...props}>
|
||||
{showError ? (
|
||||
|
|
|
@ -61,7 +61,7 @@ const MessageStatusError = () => {
|
|||
};
|
||||
|
||||
export const OutgoingMessageStatus = (props: {
|
||||
status?: MessageDeliveryStatus;
|
||||
status?: MessageDeliveryStatus | null;
|
||||
iconColor: string;
|
||||
isInMessageView?: boolean;
|
||||
}) => {
|
||||
|
|
|
@ -26,6 +26,7 @@ import {
|
|||
ReduxConversationType,
|
||||
PropsForMessage,
|
||||
SortedMessageModelProps,
|
||||
fetchMessagesForConversation,
|
||||
} from '../../../state/ducks/conversations';
|
||||
import { MessageView } from '../../MainViewController';
|
||||
import { pushUnblockToSend } from '../../../session/utils/Toast';
|
||||
|
@ -304,7 +305,7 @@ export class SessionConversation extends React.Component<Props, State> {
|
|||
Constants.CONVERSATION.DEFAULT_MESSAGE_FETCH_COUNT,
|
||||
unreadCount
|
||||
);
|
||||
window.inboxStore?.dispatch(
|
||||
(window.inboxStore?.dispatch as any)(
|
||||
fetchMessagesForConversation({
|
||||
conversationKey: selectedConversationKey,
|
||||
count: messagesToFetch,
|
||||
|
@ -991,6 +992,3 @@ export class SessionConversation extends React.Component<Props, State> {
|
|||
window.inboxStore?.dispatch(updateMentionsMembers(allMembers));
|
||||
}
|
||||
}
|
||||
function fetchMessagesForConversation(arg0: { conversationKey: string; count: number }): any {
|
||||
throw new Error('Function not implemented.');
|
||||
}
|
||||
|
|
|
@ -10,7 +10,11 @@ import { contextMenu } from 'react-contexify';
|
|||
import { AttachmentType } from '../../../types/Attachment';
|
||||
import { GroupNotification } from '../../conversation/GroupNotification';
|
||||
import { GroupInvitation } from '../../conversation/GroupInvitation';
|
||||
import { ReduxConversationType, SortedMessageModelProps } from '../../../state/ducks/conversations';
|
||||
import {
|
||||
fetchMessagesForConversation,
|
||||
ReduxConversationType,
|
||||
SortedMessageModelProps,
|
||||
} from '../../../state/ducks/conversations';
|
||||
import { SessionLastSeenIndicator } from './SessionLastSeenIndicator';
|
||||
import { ToastUtils } from '../../../session/utils';
|
||||
import { TypingBubble } from '../../conversation/TypingBubble';
|
||||
|
@ -303,20 +307,12 @@ export class SessionMessagesList extends React.Component<Props, State> {
|
|||
multiSelectMode: boolean,
|
||||
playableMessageIndex: number
|
||||
) {
|
||||
const regularProps: MessageRegularProps = { ...messageProps.propsForMessage };
|
||||
|
||||
const messageId = messageProps.propsForMessage.id;
|
||||
|
||||
const selected =
|
||||
!!messageProps?.propsForMessage.id && this.props.selectedMessages.includes(messageId);
|
||||
|
||||
regularProps.selected = selected;
|
||||
regularProps.firstMessageOfSeries = firstMessageOfSeries;
|
||||
|
||||
regularProps.multiSelectMode = multiSelectMode;
|
||||
regularProps.onSelectMessage = this.props.selectMessage;
|
||||
regularProps.onDeleteMessage = this.props.deleteMessage;
|
||||
regularProps.onReply = this.props.replyToMessage;
|
||||
regularProps.onShowDetail = async () => {
|
||||
const onShowDetail = async () => {
|
||||
const found = await getMessageById(messageId);
|
||||
if (found) {
|
||||
const messageDetailsProps = await found.getPropsForMessageDetail();
|
||||
|
@ -327,10 +323,16 @@ export class SessionMessagesList extends React.Component<Props, State> {
|
|||
}
|
||||
};
|
||||
|
||||
regularProps.onClickAttachment = (attachment: AttachmentType) => {
|
||||
const onClickAttachment = (attachment: AttachmentType) => {
|
||||
this.props.onClickAttachment(attachment, messageProps.propsForMessage);
|
||||
};
|
||||
regularProps.onDownload = (attachment: AttachmentType) => {
|
||||
|
||||
// tslint:disable-next-line: no-async-without-await
|
||||
const onQuoteClick = messageProps.propsForMessage.quote
|
||||
? this.scrollToQuoteMessage
|
||||
: async () => {};
|
||||
|
||||
const onDownload = (attachment: AttachmentType) => {
|
||||
const messageTimestamp =
|
||||
messageProps.propsForMessage.timestamp ||
|
||||
messageProps.propsForMessage.serverTimestamp ||
|
||||
|
@ -343,14 +345,23 @@ export class SessionMessagesList extends React.Component<Props, State> {
|
|||
});
|
||||
};
|
||||
|
||||
regularProps.isQuotedMessageToAnimate = messageId === this.state.animateQuotedMessageId;
|
||||
|
||||
// tslint:disable-next-line: no-async-without-await
|
||||
const onQuoteClick = regularProps.quote ? this.scrollToQuoteMessage : async () => {};
|
||||
|
||||
regularProps.nextMessageToPlay = this.state.nextMessageToPlay;
|
||||
regularProps.playableMessageIndex = playableMessageIndex;
|
||||
regularProps.playNextMessage = this.playNextMessage;
|
||||
const regularProps: MessageRegularProps = {
|
||||
...messageProps.propsForMessage,
|
||||
selected,
|
||||
firstMessageOfSeries,
|
||||
multiSelectMode,
|
||||
isQuotedMessageToAnimate: messageId === this.state.animateQuotedMessageId,
|
||||
nextMessageToPlay: this.state.nextMessageToPlay,
|
||||
playableMessageIndex,
|
||||
onSelectMessage: this.props.selectMessage,
|
||||
onDeleteMessage: this.props.deleteMessage,
|
||||
onReply: this.props.replyToMessage,
|
||||
onShowDetail,
|
||||
onClickAttachment,
|
||||
onDownload,
|
||||
playNextMessage: this.playNextMessage,
|
||||
onQuoteClick,
|
||||
};
|
||||
|
||||
return <Message {...regularProps} onQuoteClick={onQuoteClick} key={messageId} />;
|
||||
}
|
||||
|
@ -461,7 +472,7 @@ export class SessionMessagesList extends React.Component<Props, State> {
|
|||
const oldLen = messagesProps.length;
|
||||
const previousTopMessage = messagesProps[oldLen - 1]?.propsForMessage.id;
|
||||
|
||||
window.inboxStore?.dispatch(
|
||||
(window.inboxStore?.dispatch as any)(
|
||||
fetchMessagesForConversation({ conversationKey, count: numMessages })
|
||||
);
|
||||
if (previousTopMessage && oldLen !== messagesProps.length) {
|
||||
|
@ -623,6 +634,3 @@ export class SessionMessagesList extends React.Component<Props, State> {
|
|||
return scrollHeight - scrollTop - clientHeight;
|
||||
}
|
||||
}
|
||||
function fetchMessagesForConversation(arg0: { conversationKey: string; count: number }): any {
|
||||
throw new Error('Function not implemented.');
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ export function unbanUser(userToUnBan: string, conversationId: string) {
|
|||
);
|
||||
}
|
||||
|
||||
export function copyBodyToClipboard(body?: string) {
|
||||
export function copyBodyToClipboard(body?: string | null) {
|
||||
window.clipboard.writeText(body);
|
||||
|
||||
ToastUtils.pushCopiedToClipBoard();
|
||||
|
|
|
@ -548,7 +548,7 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
|
|||
text: this.createNonBreakingLastSeparator(this.get('body')),
|
||||
id: this.id as string,
|
||||
direction: (this.isIncoming() ? 'incoming' : 'outgoing') as MessageModelType,
|
||||
timestamp: this.get('sent_at'),
|
||||
timestamp: this.get('sent_at') || 0,
|
||||
receivedAt: this.get('received_at'),
|
||||
serverTimestamp: this.get('serverTimestamp'),
|
||||
serverId: this.get('serverId'),
|
||||
|
@ -574,6 +574,7 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
|
|||
weAreAdmin,
|
||||
isDeletable,
|
||||
isSenderAdmin,
|
||||
isExpired: this.isExpired(),
|
||||
};
|
||||
|
||||
return props;
|
||||
|
|
|
@ -51,7 +51,7 @@ export interface MessageAttributes {
|
|||
* timestamp is the sent_at timestamp, which is the envelope.timestamp
|
||||
*/
|
||||
timestamp?: number;
|
||||
status: MessageDeliveryStatus;
|
||||
status?: MessageDeliveryStatus;
|
||||
dataMessage: any;
|
||||
sent_to: any;
|
||||
sent: boolean;
|
||||
|
@ -202,20 +202,20 @@ export interface MessageRegularProps {
|
|||
isDeletable: boolean;
|
||||
isAdmin?: boolean;
|
||||
weAreAdmin?: boolean;
|
||||
text?: string;
|
||||
text: string | null;
|
||||
id: string;
|
||||
collapseMetadata?: boolean;
|
||||
direction: MessageModelType;
|
||||
timestamp: number;
|
||||
serverTimestamp?: number;
|
||||
status?: MessageDeliveryStatus;
|
||||
status?: MessageDeliveryStatus | null;
|
||||
// What if changed this over to a single contact like quote, and put the events on it?
|
||||
contact?: Contact & {
|
||||
onSendMessage?: () => void;
|
||||
onClick?: () => void;
|
||||
};
|
||||
authorName?: string;
|
||||
authorProfileName?: string;
|
||||
authorName?: string | null;
|
||||
authorProfileName?: string | null;
|
||||
/** Note: this should be formatted for display */
|
||||
authorPhoneNumber: string;
|
||||
conversationType: ConversationTypeEnum;
|
||||
|
@ -247,16 +247,13 @@ export interface MessageRegularProps {
|
|||
isQuotedMessageToAnimate?: boolean;
|
||||
isTrustedForAttachmentDownload: boolean;
|
||||
|
||||
onClickAttachment?: (attachment: AttachmentType) => void;
|
||||
onClickLinkPreview?: (url: string) => void;
|
||||
onClickAttachment: (attachment: AttachmentType) => void;
|
||||
onSelectMessage: (messageId: string) => void;
|
||||
onReply?: (messagId: number) => void;
|
||||
onDownload?: (attachment: AttachmentType) => void;
|
||||
onReply: (messagId: number) => void;
|
||||
onDownload: (attachment: AttachmentType) => void;
|
||||
onDeleteMessage: (messageId: string) => void;
|
||||
onShowDetail: () => void;
|
||||
markRead: (readAt: number) => Promise<void>;
|
||||
onQuoteClick: (options: QuoteClickOptions) => Promise<void>;
|
||||
theme: DefaultTheme;
|
||||
|
||||
playableMessageIndex?: number;
|
||||
nextMessageToPlay?: number;
|
||||
|
|
|
@ -137,7 +137,7 @@ export type PropsForMessage = {
|
|||
text: string | null;
|
||||
id: string;
|
||||
direction: MessageModelType;
|
||||
timestamp: number | undefined;
|
||||
timestamp: number;
|
||||
receivedAt: number | undefined;
|
||||
serverTimestamp: number | undefined;
|
||||
serverId: number | undefined;
|
||||
|
@ -161,6 +161,7 @@ export type PropsForMessage = {
|
|||
weAreAdmin: boolean;
|
||||
isSenderAdmin: boolean;
|
||||
isDeletable: boolean;
|
||||
isExpired: boolean;
|
||||
};
|
||||
|
||||
export type LastMessageType = {
|
||||
|
@ -287,7 +288,7 @@ type FetchedMessageResults = {
|
|||
messagesProps: Array<SortedMessageModelProps>;
|
||||
};
|
||||
|
||||
const fetchMessagesForConversation = createAsyncThunk(
|
||||
export const fetchMessagesForConversation = createAsyncThunk(
|
||||
'messages/fetchByConversationKey',
|
||||
async ({
|
||||
conversationKey,
|
||||
|
|
Loading…
Reference in a new issue