Support for receiving formatted messages

Co-authored-by: Alvaro Carrasco <alvaro@signal.org>
This commit is contained in:
Scott Nonnenberg 2023-04-10 09:31:45 -07:00 committed by GitHub
parent d34d187f1e
commit d9d820e72a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
72 changed files with 3421 additions and 858 deletions

View file

@ -11,7 +11,8 @@ import React, {
import classNames from 'classnames';
import { noop } from 'lodash';
import type { DraftBodyRangesType, LocalizerType } from '../types/Util';
import type { DraftBodyRangeMention } from '../types/BodyRange';
import type { LocalizerType } from '../types/Util';
import type { ConversationType } from '../state/ducks/conversations';
import type { EmojiPickDataType } from './emoji/EmojiPicker';
import type { InputApi } from './CompositionInput';
@ -94,7 +95,7 @@ export type PropsType = {
onReact: (emoji: string) => unknown;
onReply: (
message: string,
mentions: DraftBodyRangesType,
mentions: ReadonlyArray<DraftBodyRangeMention>,
timestamp: number
) => unknown;
onSetSkinTone: (tone: number) => unknown;
@ -147,6 +148,14 @@ export function StoryViewsNRepliesModal({
string | undefined
>(undefined);
// These states aren't in redux; they are meant to last only as long as this dialog.
const [revealedSpoilersById, setRevealedSpoilersById] = useState<
Record<string, boolean | undefined>
>({});
const [displayLimitById, setDisplayLimitById] = useState<
Record<string, number | undefined>
>({});
const containerElementRef = useRef<HTMLDivElement | null>(null);
const inputApiRef = useRef<InputApi | undefined>();
const shouldScrollToBottomRef = useRef(true);
@ -287,15 +296,31 @@ export function StoryViewsNRepliesModal({
deleteGroupStoryReplyForEveryone={() =>
setDeleteForEveryoneReplyId(reply.id)
}
displayLimit={displayLimitById[reply.id]}
getPreferredBadge={getPreferredBadge}
i18n={i18n}
platform={platform}
id={reply.id}
isInternalUser={isInternalUser}
isSpoilerExpanded={revealedSpoilersById[reply.id] || false}
messageExpanded={(messageId, displayLimit) => {
const update = {
...displayLimitById,
[messageId]: displayLimit,
};
setDisplayLimitById(update);
}}
reply={reply}
shouldCollapseAbove={shouldCollapse(reply, replies[index - 1])}
shouldCollapseBelow={shouldCollapse(reply, replies[index + 1])}
showContactModal={showContactModal}
showSpoiler={messageId => {
const update = {
...revealedSpoilersById,
[messageId]: true,
};
setRevealedSpoilersById(update);
}}
/>
);
})}
@ -465,31 +490,39 @@ type ReplyOrReactionMessageProps = {
containerElementRef: React.RefObject<HTMLElement>;
deleteGroupStoryReply: (replyId: string) => void;
deleteGroupStoryReplyForEveryone: (replyId: string) => void;
displayLimit: number | undefined;
getPreferredBadge: PreferredBadgeSelectorType;
i18n: LocalizerType;
platform: string;
id: string;
isInternalUser?: boolean;
isSpoilerExpanded: boolean;
onContextMenu?: (ev: React.MouseEvent) => void;
reply: ReplyType;
shouldCollapseAbove: boolean;
shouldCollapseBelow: boolean;
showContactModal: (contactId: string, conversationId?: string) => void;
messageExpanded: (messageId: string, displayLimit: number) => void;
showSpoiler: (messageId: string) => void;
};
function ReplyOrReactionMessage({
containerElementRef,
deleteGroupStoryReply,
deleteGroupStoryReplyForEveryone,
displayLimit,
getPreferredBadge,
i18n,
id,
isInternalUser,
reply,
deleteGroupStoryReply,
deleteGroupStoryReplyForEveryone,
containerElementRef,
getPreferredBadge,
isSpoilerExpanded,
messageExpanded,
platform,
reply,
shouldCollapseAbove,
shouldCollapseBelow,
showContactModal,
showSpoiler,
}: ReplyOrReactionMessageProps) {
const renderContent = (onContextMenu?: (ev: React.MouseEvent) => void) => {
if (reply.reactionEmoji && !reply.deletedForEveryone) {
@ -549,21 +582,25 @@ function ReplyOrReactionMessage({
conversationId={reply.conversationId}
conversationTitle={reply.author.title}
conversationType="group"
direction="incoming"
deletedForEveryone={reply.deletedForEveryone}
renderMenu={undefined}
onContextMenu={onContextMenu}
direction="incoming"
displayLimit={displayLimit}
getPreferredBadge={getPreferredBadge}
i18n={i18n}
platform={platform}
id={reply.id}
interactionMode="mouse"
isSpoilerExpanded={isSpoilerExpanded}
messageExpanded={messageExpanded}
onContextMenu={onContextMenu}
readStatus={reply.readStatus}
renderingContext="StoryViewsNRepliesModal"
renderMenu={undefined}
shouldCollapseAbove={shouldCollapseAbove}
shouldCollapseBelow={shouldCollapseBelow}
shouldHideMetadata={false}
showContactModal={showContactModal}
showSpoiler={showSpoiler}
text={reply.body}
textDirection={TextDirection.Default}
timestamp={reply.timestamp}