Adds an edit message entry point in message details screen
This commit is contained in:
parent
008cb99ab9
commit
94cd764107
8 changed files with 168 additions and 122 deletions
|
@ -5150,6 +5150,10 @@
|
||||||
"messageformat": "Disappears in",
|
"messageformat": "Disappears in",
|
||||||
"description": "In the message details screen, shown as a label of how long it will be before the message disappears"
|
"description": "In the message details screen, shown as a label of how long it will be before the message disappears"
|
||||||
},
|
},
|
||||||
|
"icu:MessageDetail__view-edits": {
|
||||||
|
"messageformat": "View edit history",
|
||||||
|
"description": "Link to view a message's edit history"
|
||||||
|
},
|
||||||
"icu:ProfileEditor--about": {
|
"icu:ProfileEditor--about": {
|
||||||
"messageformat": "About",
|
"messageformat": "About",
|
||||||
"description": "Default text for about field"
|
"description": "Default text for about field"
|
||||||
|
|
|
@ -424,6 +424,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&__attachment img {
|
&__attachment img {
|
||||||
|
border-radius: 4px;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset-inline-end: 8px;
|
inset-inline-end: 8px;
|
||||||
|
|
|
@ -253,6 +253,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&--edit {
|
||||||
|
&::after {
|
||||||
|
@include details-icon('../images/icons/v3/edit/edit.svg');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&--down {
|
&--down {
|
||||||
border-radius: 18px;
|
border-radius: 18px;
|
||||||
@include light-theme {
|
@include light-theme {
|
||||||
|
|
|
@ -3,7 +3,16 @@
|
||||||
|
|
||||||
.EditHistoryMessagesModal {
|
.EditHistoryMessagesModal {
|
||||||
&__divider {
|
&__divider {
|
||||||
|
border-style: solid;
|
||||||
margin-block: 24px;
|
margin-block: 24px;
|
||||||
|
|
||||||
|
@include light-theme {
|
||||||
|
border-color: $color-gray-15;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include dark-theme {
|
||||||
|
border-color: $color-gray-75;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__title {
|
&__title {
|
||||||
|
|
|
@ -39,18 +39,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.module-message-detail__contact-container {
|
|
||||||
border-top: 1px solid $color-gray-15;
|
|
||||||
margin-top: 36px;
|
|
||||||
|
|
||||||
@include light-theme {
|
|
||||||
border-top-color: $color-gray-15;
|
|
||||||
}
|
|
||||||
@include dark-theme {
|
|
||||||
border-top-color: $color-gray-75;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.module-message-detail__contact-group__header {
|
.module-message-detail__contact-group__header {
|
||||||
@include font-body-1-bold;
|
@include font-body-1-bold;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
|
@ -27,6 +27,12 @@ import { formatDateTimeLong } from '../../util/timestamp';
|
||||||
import { DurationInSeconds } from '../../util/durations';
|
import { DurationInSeconds } from '../../util/durations';
|
||||||
import { format as formatRelativeTime } from '../../util/expirationTimer';
|
import { format as formatRelativeTime } from '../../util/expirationTimer';
|
||||||
import { missingCaseError } from '../../util/missingCaseError';
|
import { missingCaseError } from '../../util/missingCaseError';
|
||||||
|
import { PanelRow } from './conversation-details/PanelRow';
|
||||||
|
import { PanelSection } from './conversation-details/PanelSection';
|
||||||
|
import {
|
||||||
|
ConversationDetailsIcon,
|
||||||
|
IconType,
|
||||||
|
} from './conversation-details/ConversationDetailsIcon';
|
||||||
|
|
||||||
export type Contact = Pick<
|
export type Contact = Pick<
|
||||||
ConversationType,
|
ConversationType,
|
||||||
|
@ -88,6 +94,7 @@ export type PropsReduxActions = Pick<
|
||||||
| 'saveAttachment'
|
| 'saveAttachment'
|
||||||
| 'showContactModal'
|
| 'showContactModal'
|
||||||
| 'showConversation'
|
| 'showConversation'
|
||||||
|
| 'showEditHistoryModal'
|
||||||
| 'showExpiredIncomingTapToViewToast'
|
| 'showExpiredIncomingTapToViewToast'
|
||||||
| 'showExpiredOutgoingTapToViewToast'
|
| 'showExpiredOutgoingTapToViewToast'
|
||||||
| 'showLightbox'
|
| 'showLightbox'
|
||||||
|
@ -131,6 +138,7 @@ export function MessageDetail({
|
||||||
saveAttachment,
|
saveAttachment,
|
||||||
showContactModal,
|
showContactModal,
|
||||||
showConversation,
|
showConversation,
|
||||||
|
showEditHistoryModal,
|
||||||
showExpiredIncomingTapToViewToast,
|
showExpiredIncomingTapToViewToast,
|
||||||
showExpiredOutgoingTapToViewToast,
|
showExpiredOutgoingTapToViewToast,
|
||||||
showLightbox,
|
showLightbox,
|
||||||
|
@ -321,123 +329,150 @@ export function MessageDetail({
|
||||||
return (
|
return (
|
||||||
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
||||||
<div className="module-message-detail" tabIndex={0} ref={focusRef}>
|
<div className="module-message-detail" tabIndex={0} ref={focusRef}>
|
||||||
<div
|
<PanelSection>
|
||||||
className="module-message-detail__message-container"
|
<div
|
||||||
ref={messageContainerRef}
|
className="module-message-detail__message-container"
|
||||||
>
|
ref={messageContainerRef}
|
||||||
<Message
|
>
|
||||||
{...message}
|
<Message
|
||||||
renderingContext="conversation/MessageDetail"
|
{...message}
|
||||||
checkForAccount={checkForAccount}
|
renderingContext="conversation/MessageDetail"
|
||||||
clearTargetedMessage={clearTargetedMessage}
|
checkForAccount={checkForAccount}
|
||||||
contactNameColor={contactNameColor}
|
clearTargetedMessage={clearTargetedMessage}
|
||||||
containerElementRef={messageContainerRef}
|
contactNameColor={contactNameColor}
|
||||||
containerWidthBreakpoint={WidthBreakpoint.Wide}
|
containerElementRef={messageContainerRef}
|
||||||
renderMenu={undefined}
|
containerWidthBreakpoint={WidthBreakpoint.Wide}
|
||||||
disableScroll
|
renderMenu={undefined}
|
||||||
displayLimit={Number.MAX_SAFE_INTEGER}
|
disableScroll
|
||||||
showLightboxForViewOnceMedia={showLightboxForViewOnceMedia}
|
displayLimit={Number.MAX_SAFE_INTEGER}
|
||||||
doubleCheckMissingQuoteReference={doubleCheckMissingQuoteReference}
|
showLightboxForViewOnceMedia={showLightboxForViewOnceMedia}
|
||||||
getPreferredBadge={getPreferredBadge}
|
doubleCheckMissingQuoteReference={doubleCheckMissingQuoteReference}
|
||||||
i18n={i18n}
|
getPreferredBadge={getPreferredBadge}
|
||||||
interactionMode={interactionMode}
|
i18n={i18n}
|
||||||
kickOffAttachmentDownload={kickOffAttachmentDownload}
|
interactionMode={interactionMode}
|
||||||
markAttachmentAsCorrupted={markAttachmentAsCorrupted}
|
kickOffAttachmentDownload={kickOffAttachmentDownload}
|
||||||
messageExpanded={messageExpanded}
|
markAttachmentAsCorrupted={markAttachmentAsCorrupted}
|
||||||
openGiftBadge={openGiftBadge}
|
messageExpanded={messageExpanded}
|
||||||
platform={platform}
|
openGiftBadge={openGiftBadge}
|
||||||
pushPanelForConversation={pushPanelForConversation}
|
platform={platform}
|
||||||
retryMessageSend={retryMessageSend}
|
pushPanelForConversation={pushPanelForConversation}
|
||||||
renderAudioAttachment={renderAudioAttachment}
|
retryMessageSend={retryMessageSend}
|
||||||
saveAttachment={saveAttachment}
|
renderAudioAttachment={renderAudioAttachment}
|
||||||
shouldCollapseAbove={false}
|
saveAttachment={saveAttachment}
|
||||||
shouldCollapseBelow={false}
|
shouldCollapseAbove={false}
|
||||||
shouldHideMetadata={false}
|
shouldCollapseBelow={false}
|
||||||
showConversation={showConversation}
|
shouldHideMetadata={false}
|
||||||
showSpoiler={showSpoiler}
|
showConversation={showConversation}
|
||||||
scrollToQuotedMessage={() => {
|
showSpoiler={showSpoiler}
|
||||||
log.warn('MessageDetail: scrollToQuotedMessage called!');
|
scrollToQuotedMessage={() => {
|
||||||
}}
|
log.warn('MessageDetail: scrollToQuotedMessage called!');
|
||||||
showContactModal={showContactModal}
|
}}
|
||||||
showExpiredIncomingTapToViewToast={showExpiredIncomingTapToViewToast}
|
showContactModal={showContactModal}
|
||||||
showExpiredOutgoingTapToViewToast={showExpiredOutgoingTapToViewToast}
|
showExpiredIncomingTapToViewToast={
|
||||||
showLightbox={showLightbox}
|
showExpiredIncomingTapToViewToast
|
||||||
startConversation={startConversation}
|
}
|
||||||
theme={theme}
|
showExpiredOutgoingTapToViewToast={
|
||||||
viewStory={viewStory}
|
showExpiredOutgoingTapToViewToast
|
||||||
onToggleSelect={noop}
|
}
|
||||||
onReplyToMessage={noop}
|
showLightbox={showLightbox}
|
||||||
/>
|
startConversation={startConversation}
|
||||||
</div>
|
theme={theme}
|
||||||
<table className="module-message-detail__info">
|
viewStory={viewStory}
|
||||||
<tbody>
|
onToggleSelect={noop}
|
||||||
{(errors || []).map(error => (
|
onReplyToMessage={noop}
|
||||||
<tr key={_keyForError(error)}>
|
/>
|
||||||
|
</div>
|
||||||
|
<table className="module-message-detail__info">
|
||||||
|
<tbody>
|
||||||
|
{(errors || []).map(error => (
|
||||||
|
<tr key={_keyForError(error)}>
|
||||||
|
<td className="module-message-detail__label">
|
||||||
|
{i18n('icu:error')}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{' '}
|
||||||
|
<span className="error-message">{error.message}</span>{' '}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
<tr>
|
||||||
<td className="module-message-detail__label">
|
<td className="module-message-detail__label">
|
||||||
{i18n('icu:error')}
|
{i18n('icu:sent')}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{' '}
|
<ContextMenu
|
||||||
<span className="error-message">{error.message}</span>{' '}
|
i18n={i18n}
|
||||||
|
menuOptions={[
|
||||||
|
{
|
||||||
|
icon: 'StoryDetailsModal__copy-icon',
|
||||||
|
label: i18n('icu:StoryDetailsModal__copy-timestamp'),
|
||||||
|
onClick: () => {
|
||||||
|
void window.navigator.clipboard.writeText(
|
||||||
|
String(sentAt)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<>
|
||||||
|
<Time timestamp={sentAt}>
|
||||||
|
{formatDateTimeLong(i18n, sentAt)}
|
||||||
|
</Time>{' '}
|
||||||
|
<span className="module-message-detail__unix-timestamp">
|
||||||
|
({sentAt})
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
</ContextMenu>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
{receivedAt && message.direction === 'incoming' ? (
|
||||||
<tr>
|
<tr>
|
||||||
<td className="module-message-detail__label">{i18n('icu:sent')}</td>
|
<td className="module-message-detail__label">
|
||||||
<td>
|
{i18n('icu:received')}
|
||||||
<ContextMenu
|
</td>
|
||||||
i18n={i18n}
|
<td>
|
||||||
menuOptions={[
|
<Time timestamp={receivedAt}>
|
||||||
{
|
{formatDateTimeLong(i18n, receivedAt)}
|
||||||
icon: 'StoryDetailsModal__copy-icon',
|
|
||||||
label: i18n('icu:StoryDetailsModal__copy-timestamp'),
|
|
||||||
onClick: () => {
|
|
||||||
void window.navigator.clipboard.writeText(String(sentAt));
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<>
|
|
||||||
<Time timestamp={sentAt}>
|
|
||||||
{formatDateTimeLong(i18n, sentAt)}
|
|
||||||
</Time>{' '}
|
</Time>{' '}
|
||||||
<span className="module-message-detail__unix-timestamp">
|
<span className="module-message-detail__unix-timestamp">
|
||||||
({sentAt})
|
({receivedAt})
|
||||||
</span>
|
</span>
|
||||||
</>
|
</td>
|
||||||
</ContextMenu>
|
</tr>
|
||||||
</td>
|
) : null}
|
||||||
</tr>
|
{timeRemaining && timeRemaining > 0 && (
|
||||||
{receivedAt && message.direction === 'incoming' ? (
|
<tr>
|
||||||
<tr>
|
<td className="module-message-detail__label">
|
||||||
<td className="module-message-detail__label">
|
{i18n('icu:MessageDetail--disappears-in')}
|
||||||
{i18n('icu:received')}
|
</td>
|
||||||
</td>
|
<td>
|
||||||
<td>
|
{formatRelativeTime(i18n, timeRemaining, {
|
||||||
<Time timestamp={receivedAt}>
|
largest: 2,
|
||||||
{formatDateTimeLong(i18n, receivedAt)}
|
})}
|
||||||
</Time>{' '}
|
</td>
|
||||||
<span className="module-message-detail__unix-timestamp">
|
</tr>
|
||||||
({receivedAt})
|
)}
|
||||||
</span>
|
</tbody>
|
||||||
</td>
|
</table>
|
||||||
</tr>
|
</PanelSection>
|
||||||
) : null}
|
{message.isEditedMessage && (
|
||||||
{timeRemaining && timeRemaining > 0 && (
|
<PanelSection>
|
||||||
<tr>
|
<PanelRow
|
||||||
<td className="module-message-detail__label">
|
icon={
|
||||||
{i18n('icu:MessageDetail--disappears-in')}
|
<ConversationDetailsIcon
|
||||||
</td>
|
ariaLabel={i18n('icu:MessageDetail__view-edits')}
|
||||||
<td>
|
icon={IconType.edit}
|
||||||
{formatRelativeTime(i18n, timeRemaining, {
|
/>
|
||||||
largest: 2,
|
}
|
||||||
})}
|
label={i18n('icu:MessageDetail__view-edits')}
|
||||||
</td>
|
onClick={() => {
|
||||||
</tr>
|
showEditHistoryModal?.(message.id);
|
||||||
)}
|
}}
|
||||||
</tbody>
|
/>
|
||||||
</table>
|
</PanelSection>
|
||||||
{renderContacts()}
|
)}
|
||||||
|
|
||||||
|
<PanelSection>{renderContacts()}</PanelSection>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { bemGenerator } from './util';
|
||||||
|
|
||||||
export enum IconType {
|
export enum IconType {
|
||||||
'block' = 'block',
|
'block' = 'block',
|
||||||
|
'edit' = 'edit',
|
||||||
'unblock' = 'unblock',
|
'unblock' = 'unblock',
|
||||||
'color' = 'color',
|
'color' = 'color',
|
||||||
'down' = 'down',
|
'down' = 'down',
|
||||||
|
|
|
@ -54,7 +54,8 @@ export function SmartMessageDetail(): JSX.Element | null {
|
||||||
showSpoiler,
|
showSpoiler,
|
||||||
startConversation,
|
startConversation,
|
||||||
} = useConversationsActions();
|
} = useConversationsActions();
|
||||||
const { showContactModal, toggleSafetyNumberModal } = useGlobalModalActions();
|
const { showContactModal, showEditHistoryModal, toggleSafetyNumberModal } =
|
||||||
|
useGlobalModalActions();
|
||||||
const { showLightbox, showLightboxForViewOnceMedia } = useLightboxActions();
|
const { showLightbox, showLightboxForViewOnceMedia } = useLightboxActions();
|
||||||
const { viewStory } = useStoriesActions();
|
const { viewStory } = useStoriesActions();
|
||||||
|
|
||||||
|
@ -100,6 +101,7 @@ export function SmartMessageDetail(): JSX.Element | null {
|
||||||
sentAt={message.timestamp}
|
sentAt={message.timestamp}
|
||||||
showContactModal={showContactModal}
|
showContactModal={showContactModal}
|
||||||
showConversation={showConversation}
|
showConversation={showConversation}
|
||||||
|
showEditHistoryModal={showEditHistoryModal}
|
||||||
showExpiredIncomingTapToViewToast={showExpiredIncomingTapToViewToast}
|
showExpiredIncomingTapToViewToast={showExpiredIncomingTapToViewToast}
|
||||||
showExpiredOutgoingTapToViewToast={showExpiredOutgoingTapToViewToast}
|
showExpiredOutgoingTapToViewToast={showExpiredOutgoingTapToViewToast}
|
||||||
showLightbox={showLightbox}
|
showLightbox={showLightbox}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue