add first step to enable back MessageDetails.
Still not much the react way to do it for now
This commit is contained in:
parent
71e1f1e143
commit
5c55a9411f
|
@ -55,6 +55,9 @@ export interface MessageModel extends Backbone.Model<MessageAttributes> {
|
|||
sendSyncMessageOnly: (message: any) => void;
|
||||
isUnread: () => boolean;
|
||||
commit: () => Promise<number>;
|
||||
getPropsForMessageDetail: (
|
||||
onSendAnyway: any /*, onShowSafetyNumber: any*/
|
||||
) => any; // FIXME enable this back. Be sure to handle case where it comes from a medium group
|
||||
|
||||
propsForMessage?: any;
|
||||
propsForTimerNotification?: any;
|
||||
|
|
|
@ -617,7 +617,6 @@
|
|||
onCopyPubKey: () => this.copyPubKey(),
|
||||
onBanUser: () => this.banUser(),
|
||||
onRetrySend: () => this.retrySend(),
|
||||
onShowDetail: () => this.trigger('show-message-detail', this),
|
||||
markRead: readAt => this.markRead(readAt),
|
||||
|
||||
onShowUserDetails: pubkey =>
|
||||
|
@ -804,7 +803,7 @@
|
|||
|
||||
return Boolean(lookup[contactId]);
|
||||
},
|
||||
async getPropsForMessageDetail() {
|
||||
async getPropsForMessageDetail(onSendAnyway, onShowSafetyNumber) {
|
||||
const newIdentity = i18n('newIdentity');
|
||||
const OUTGOING_KEY_ERROR = 'OutgoingIdentityKeyError';
|
||||
|
||||
|
@ -867,13 +866,15 @@
|
|||
isUnidentifiedDelivery,
|
||||
isPrimaryDevice,
|
||||
profileName,
|
||||
onSendAnyway: () =>
|
||||
this.trigger('force-send', {
|
||||
onSendAnyway: () => {
|
||||
onSendAnyway({
|
||||
contact: this.findContact(id),
|
||||
message: this,
|
||||
}),
|
||||
onShowSafetyNumber: () =>
|
||||
this.trigger('show-identity', this.findContact(id)),
|
||||
});
|
||||
},
|
||||
onShowSafetyNumber: () => {
|
||||
onShowSafetyNumber(this.findContact(id));
|
||||
},
|
||||
};
|
||||
})
|
||||
);
|
||||
|
@ -890,7 +891,7 @@
|
|||
sentAt: this.get('sent_at'),
|
||||
receivedAt: this.get('received_at'),
|
||||
message: {
|
||||
...this.getPropsForMessage({ noClick: true }),
|
||||
...this.propsForMessage,
|
||||
disableMenu: true,
|
||||
// To ensure that group avatar doesn't show up
|
||||
conversationType: 'direct',
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
height: calc(100% - 48px);
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.message-container {
|
||||
|
|
|
@ -1203,6 +1203,7 @@
|
|||
.module-message-detail__contact__text {
|
||||
margin-inline-start: 10px;
|
||||
flex-grow: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.module-message-detail__contact__error {
|
||||
|
|
|
@ -145,54 +145,56 @@ export class MessageDetail extends React.Component<Props> {
|
|||
const { errors, message, receivedAt, sentAt } = this.props;
|
||||
|
||||
return (
|
||||
<div className="module-message-detail">
|
||||
<div className="module-message-detail__message-container">
|
||||
<Message {...message} />
|
||||
</div>
|
||||
<table className="module-message-detail__info">
|
||||
<tbody>
|
||||
{(errors || []).map((error, index) => (
|
||||
<tr key={index}>
|
||||
<td className="module-message-detail__label">
|
||||
{i18n('error')}
|
||||
</td>
|
||||
<td>
|
||||
{' '}
|
||||
<span className="error-message">{error.message}</span>{' '}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
<tr>
|
||||
<td className="module-message-detail__label">{i18n('sent')}</td>
|
||||
<td>
|
||||
{moment(sentAt).format('LLLL')}{' '}
|
||||
<span className="module-message-detail__unix-timestamp">
|
||||
({sentAt})
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
{receivedAt ? (
|
||||
<div className="message-detail-wrapper">
|
||||
<div className="module-message-detail">
|
||||
<div className="module-message-detail__message-container">
|
||||
<Message {...message} />
|
||||
</div>
|
||||
<table className="module-message-detail__info">
|
||||
<tbody>
|
||||
{(errors || []).map((error, index) => (
|
||||
<tr key={index}>
|
||||
<td className="module-message-detail__label">
|
||||
{i18n('error')}
|
||||
</td>
|
||||
<td>
|
||||
{' '}
|
||||
<span className="error-message">{error.message}</span>{' '}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
<tr>
|
||||
<td className="module-message-detail__label">
|
||||
{i18n('received')}
|
||||
</td>
|
||||
<td className="module-message-detail__label">{i18n('sent')}</td>
|
||||
<td>
|
||||
{moment(receivedAt).format('LLLL')}{' '}
|
||||
{moment(sentAt).format('LLLL')}{' '}
|
||||
<span className="module-message-detail__unix-timestamp">
|
||||
({receivedAt})
|
||||
({sentAt})
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
) : null}
|
||||
<tr>
|
||||
<td className="module-message-detail__label">
|
||||
{message.direction === 'incoming' ? i18n('from') : i18n('to')}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{this.renderContacts()}
|
||||
{this.renderDeleteButton()}
|
||||
{receivedAt ? (
|
||||
<tr>
|
||||
<td className="module-message-detail__label">
|
||||
{i18n('received')}
|
||||
</td>
|
||||
<td>
|
||||
{moment(receivedAt).format('LLLL')}{' '}
|
||||
<span className="module-message-detail__unix-timestamp">
|
||||
({receivedAt})
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
) : null}
|
||||
<tr>
|
||||
<td className="module-message-detail__label">
|
||||
{message.direction === 'incoming' ? i18n('from') : i18n('to')}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{this.renderContacts()}
|
||||
{this.renderDeleteButton()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import { ConversationType } from '../../../state/ducks/conversations';
|
|||
import { MessageView } from '../../MainViewController';
|
||||
import { getMessageById, removeMessage } from '../../../../js/modules/data';
|
||||
import { pushUnblockToSend } from '../../../session/utils/Toast';
|
||||
import { MessageDetail } from '../../conversation/MessageDetail';
|
||||
|
||||
interface State {
|
||||
// Message sending progress
|
||||
|
@ -50,8 +51,11 @@ interface State {
|
|||
showRecordingView: boolean;
|
||||
showOptionsPane: boolean;
|
||||
|
||||
// For displaying `More Info` on messages, and `Safety Number`, etc.
|
||||
infoViewState?: 'safetyNumber' | 'messageDetails';
|
||||
// For displaying `Safety Number`, etc.
|
||||
infoViewState?: 'safetyNumber';
|
||||
|
||||
// if set, the `More Info` of a message screen is shown on top of the conversation.
|
||||
messageDetailShowProps?: any; // FIXME set the type for this
|
||||
|
||||
stagedAttachments: Array<StagedAttachmentType>;
|
||||
isDraggingFile: boolean;
|
||||
|
@ -127,6 +131,7 @@ export class SessionConversation extends React.Component<Props, State> {
|
|||
this.deleteSelectedMessages = this.deleteSelectedMessages.bind(this);
|
||||
|
||||
this.replyToMessage = this.replyToMessage.bind(this);
|
||||
this.showMessageDetails = this.showMessageDetails.bind(this);
|
||||
this.deleteMessage = this.deleteMessage.bind(this);
|
||||
this.onClickAttachment = this.onClickAttachment.bind(this);
|
||||
this.downloadAttachment = this.downloadAttachment.bind(this);
|
||||
|
@ -210,6 +215,7 @@ export class SessionConversation extends React.Component<Props, State> {
|
|||
infoViewState: undefined,
|
||||
stagedAttachments: [],
|
||||
isDraggingFile: false,
|
||||
messageDetailShowProps: undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -239,6 +245,8 @@ export class SessionConversation extends React.Component<Props, State> {
|
|||
selectedMessages,
|
||||
isDraggingFile,
|
||||
stagedAttachments,
|
||||
infoViewState,
|
||||
messageDetailShowProps,
|
||||
} = this.state;
|
||||
const selectionMode = !!selectedMessages.length;
|
||||
|
||||
|
@ -273,7 +281,7 @@ export class SessionConversation extends React.Component<Props, State> {
|
|||
);
|
||||
if (this.messageContainerRef.current) {
|
||||
// force scrolling to bottom on message sent
|
||||
// this will mark all messages as read
|
||||
// this will mark all messages as read, and reset the conversation unreadCount
|
||||
(this.messageContainerRef
|
||||
.current as any).scrollTop = this.messageContainerRef.current?.scrollHeight;
|
||||
}
|
||||
|
@ -281,8 +289,8 @@ export class SessionConversation extends React.Component<Props, State> {
|
|||
|
||||
const shouldRenderRightPanel = !conversationModel.isRss();
|
||||
|
||||
const showSafetyNumber = this.state.infoViewState === 'safetyNumber';
|
||||
const showMessageDetails = this.state.infoViewState === 'messageDetails';
|
||||
const showSafetyNumber = infoViewState === 'safetyNumber';
|
||||
const showMessageDetails = !!messageDetailShowProps;
|
||||
|
||||
return (
|
||||
<SessionTheme theme={this.props.theme}>
|
||||
|
@ -308,13 +316,15 @@ export class SessionConversation extends React.Component<Props, State> {
|
|||
<div
|
||||
className={classNames(
|
||||
'conversation-info-panel',
|
||||
this.state.infoViewState && 'show'
|
||||
(infoViewState || showMessageDetails) && 'show'
|
||||
)}
|
||||
>
|
||||
{showSafetyNumber && (
|
||||
<SessionKeyVerification conversation={conversationModel} />
|
||||
)}
|
||||
{showMessageDetails && <> </>}
|
||||
{showMessageDetails && (
|
||||
<MessageDetail {...messageDetailShowProps} />
|
||||
)}
|
||||
</div>
|
||||
|
||||
{lightBoxOptions?.media && this.renderLightBox(lightBoxOptions)}
|
||||
|
@ -400,7 +410,11 @@ export class SessionConversation extends React.Component<Props, State> {
|
|||
|
||||
public getHeaderProps() {
|
||||
const { conversationKey } = this.props;
|
||||
const { selectedMessages, infoViewState } = this.state;
|
||||
const {
|
||||
selectedMessages,
|
||||
infoViewState,
|
||||
messageDetailShowProps,
|
||||
} = this.state;
|
||||
const conversation = window.ConversationController.getOrThrow(
|
||||
conversationKey
|
||||
);
|
||||
|
@ -433,7 +447,7 @@ export class SessionConversation extends React.Component<Props, State> {
|
|||
subscriberCount: conversation.get('subscriberCount'),
|
||||
isKickedFromGroup: conversation.get('isKickedFromGroup'),
|
||||
expirationSettingName,
|
||||
showBackButton: Boolean(infoViewState),
|
||||
showBackButton: Boolean(infoViewState || messageDetailShowProps),
|
||||
timerOptions: window.Whisper.ExpirationTimerOptions.map((item: any) => ({
|
||||
name: item.getName(),
|
||||
value: item.get('seconds'),
|
||||
|
@ -458,7 +472,10 @@ export class SessionConversation extends React.Component<Props, State> {
|
|||
},
|
||||
|
||||
onGoBack: () => {
|
||||
this.setState({ infoViewState: undefined });
|
||||
this.setState({
|
||||
infoViewState: undefined,
|
||||
messageDetailShowProps: undefined,
|
||||
});
|
||||
},
|
||||
|
||||
onUpdateGroupName: () => {
|
||||
|
@ -514,6 +531,7 @@ export class SessionConversation extends React.Component<Props, State> {
|
|||
deleteMessage: this.deleteMessage,
|
||||
fetchMessagesForConversation: actions.fetchMessagesForConversation,
|
||||
replyToMessage: this.replyToMessage,
|
||||
showMessageDetails: this.showMessageDetails,
|
||||
onClickAttachment: this.onClickAttachment,
|
||||
onDownloadAttachment: this.downloadAttachment,
|
||||
messageContainerRef: this.messageContainerRef,
|
||||
|
@ -812,6 +830,13 @@ export class SessionConversation extends React.Component<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
private async showMessageDetails(messageProps: any) {
|
||||
messageProps.onDeleteMessage = (id: string) => {
|
||||
this.deleteMessage(id);
|
||||
};
|
||||
this.setState({ messageDetailShowProps: messageProps });
|
||||
}
|
||||
|
||||
private onClickAttachment(attachment: any, message: any) {
|
||||
const lightBoxOptions = {
|
||||
media: [
|
||||
|
|
|
@ -37,6 +37,7 @@ interface Props {
|
|||
count: number;
|
||||
}) => void;
|
||||
replyToMessage: (messageId: number) => Promise<void>;
|
||||
showMessageDetails: (messageProps: any) => Promise<void>;
|
||||
onClickAttachment: (attachment: any, message: any) => void;
|
||||
onDownloadAttachment: ({ attachment }: { attachment: any }) => void;
|
||||
onDeleteSelectedMessages: () => Promise<void>;
|
||||
|
@ -61,6 +62,8 @@ export class SessionMessagesList extends React.Component<Props, State> {
|
|||
this.getScrollOffsetBottomPx = this.getScrollOffsetBottomPx.bind(this);
|
||||
this.displayUnreadBannerIndex = this.displayUnreadBannerIndex.bind(this);
|
||||
|
||||
this.onSendAnyway = this.onSendAnyway.bind(this);
|
||||
|
||||
this.messageContainerRef = this.props.messageContainerRef;
|
||||
this.ignoreScrollEvents = true;
|
||||
}
|
||||
|
@ -272,7 +275,8 @@ export class SessionMessagesList extends React.Component<Props, State> {
|
|||
{this.renderMessage(
|
||||
messageProps,
|
||||
message.firstMessageOfSeries,
|
||||
multiSelectMode
|
||||
multiSelectMode,
|
||||
message
|
||||
)}
|
||||
{unreadIndicator}
|
||||
</>
|
||||
|
@ -285,7 +289,8 @@ export class SessionMessagesList extends React.Component<Props, State> {
|
|||
private renderMessage(
|
||||
messageProps: any,
|
||||
firstMessageOfSeries: boolean,
|
||||
multiSelectMode: boolean
|
||||
multiSelectMode: boolean,
|
||||
message: MessageModel
|
||||
) {
|
||||
const selected =
|
||||
!!messageProps?.id &&
|
||||
|
@ -298,6 +303,13 @@ export class SessionMessagesList extends React.Component<Props, State> {
|
|||
messageProps.onSelectMessage = this.props.selectMessage;
|
||||
messageProps.onDeleteMessage = this.props.deleteMessage;
|
||||
messageProps.onReply = this.props.replyToMessage;
|
||||
messageProps.onShowDetail = async () => {
|
||||
void this.props.showMessageDetails(
|
||||
await message.getPropsForMessageDetail(
|
||||
this.onSendAnyway /*, this.props.onShowSafetyNumber*/
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
messageProps.onClickAttachment = (attachment: any) => {
|
||||
this.props.onClickAttachment(attachment, messageProps);
|
||||
|
@ -534,4 +546,30 @@ export class SessionMessagesList extends React.Component<Props, State> {
|
|||
const clientHeight = messageContainer.clientHeight;
|
||||
return scrollHeight - scrollTop - clientHeight;
|
||||
}
|
||||
|
||||
private async onSendAnyway({ contact, message }: any) {
|
||||
const { i18n } = window;
|
||||
window.confirmationDialog({
|
||||
message: i18n('identityKeyErrorOnSend', [
|
||||
contact.getTitle(),
|
||||
contact.getTitle(),
|
||||
]),
|
||||
messageSub: i18n('youMayWishToVerifyContact'),
|
||||
okText: i18n('sendAnyway'),
|
||||
resolve: async () => {
|
||||
await contact.updateVerified();
|
||||
|
||||
if (contact.isUnverified()) {
|
||||
await contact.setVerifiedDefault();
|
||||
}
|
||||
|
||||
const untrusted = await contact.isUntrusted();
|
||||
if (untrusted) {
|
||||
await contact.setApproved();
|
||||
}
|
||||
|
||||
message.resend(contact.id);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ export type MessageType = {
|
|||
isSelected?: boolean;
|
||||
};
|
||||
|
||||
export type MessageTypeInConvo = {
|
||||
type MessageTypeInConvo = {
|
||||
id: string;
|
||||
conversationId: string;
|
||||
attributes: any;
|
||||
|
@ -46,6 +46,7 @@ export type MessageTypeInConvo = {
|
|||
propsForGroupNotification: Object;
|
||||
firstMessageOfSeries: boolean;
|
||||
receivedAt: number;
|
||||
getPropsForMessageDetail(): Promise<any>;
|
||||
};
|
||||
|
||||
export type ConversationType = {
|
||||
|
@ -397,6 +398,15 @@ const toPickFromMessageModel = [
|
|||
'propsForVerificationNotification',
|
||||
'propsForResetSessionNotification',
|
||||
'propsForGroupNotification',
|
||||
// FIXME below are what is needed to fetch on the fly messageDetails. This is not the react way
|
||||
'getPropsForMessageDetail',
|
||||
'get',
|
||||
'getConversation',
|
||||
'isIncoming',
|
||||
'findAndFormatContact',
|
||||
'findContact',
|
||||
'isUnidentifiedDelivery',
|
||||
'getStatus',
|
||||
];
|
||||
|
||||
function getEmptyState(): ConversationsStateType {
|
||||
|
|
Loading…
Reference in New Issue