Fun picker improvements

This commit is contained in:
Jamie Kyle
2025-03-26 12:35:32 -07:00
committed by GitHub
parent 427f91f903
commit b0653d06fe
142 changed files with 3581 additions and 1280 deletions

View File

@@ -84,10 +84,9 @@ import * as RemoteConfig from '../RemoteConfig';
import type { FunEmojiSelection } from './fun/panels/FunPanelEmojis';
import type { FunStickerSelection } from './fun/panels/FunPanelStickers';
import type { FunGifSelection } from './fun/panels/FunPanelGifs';
import { tenorDownload } from './fun/data/tenor';
import { SignalService as Proto } from '../protobuf';
import { SKIN_TONE_TO_NUMBER } from './fun/data/emojis';
import type { SmartDraftGifMessageSendModalProps } from '../state/smart/DraftGifMessageSendModal';
import { strictAssert } from '../util/assert';
import { ConfirmationDialog } from './ConfirmationDialog';
export type OwnProps = Readonly<{
acceptedMessageRequest: boolean | null;
@@ -205,6 +204,9 @@ export type OwnProps = Readonly<{
payload: ForwardMessagesPayload,
onForward: () => void
) => void;
toggleDraftGifMessageSendModal: (
props: SmartDraftGifMessageSendModalProps | null
) => void;
}>;
export type Props = Pick<
@@ -221,7 +223,10 @@ export type Props = Pick<
> &
Pick<
EmojiButtonProps,
'onPickEmoji' | 'onSetSkinTone' | 'recentEmojis' | 'skinTone'
| 'onPickEmoji'
| 'onEmojiSkinToneDefaultChange'
| 'recentEmojis'
| 'emojiSkinToneDefault'
> &
Pick<
StickerButtonProps,
@@ -304,9 +309,9 @@ export const CompositionArea = memo(function CompositionArea({
sortedGroupMembers,
// EmojiButton
onPickEmoji,
onSetSkinTone,
onEmojiSkinToneDefaultChange,
recentEmojis,
skinTone,
emojiSkinToneDefault,
// StickerButton
knownPacks,
receivedPacks,
@@ -358,6 +363,8 @@ export const CompositionArea = memo(function CompositionArea({
selectedMessageIds,
toggleSelectMode,
toggleForwardMessagesModal,
// DraftGifMessageSendModal
toggleDraftGifMessageSendModal,
}: Props): JSX.Element | null {
const [dirty, setDirty] = useState(false);
const [large, setLarge] = useState(false);
@@ -603,14 +610,9 @@ export const CompositionArea = memo(function CompositionArea({
const handleFunPickerSelectEmoji = useCallback(
(emojiSelection: FunEmojiSelection) => {
const skinToneNumber = SKIN_TONE_TO_NUMBER.get(emojiSelection.skinTone);
strictAssert(
skinToneNumber,
`Unexpected skin tone: ${emojiSelection.skinTone}`
);
insertEmoji({
shortName: emojiSelection.englishShortName,
skinTone: skinToneNumber,
skinTone: emojiSelection.skinTone,
});
},
[insertEmoji]
@@ -625,24 +627,53 @@ export const CompositionArea = memo(function CompositionArea({
[sendStickerMessage, conversationId]
);
const [confirmGifSelection, setConfirmGifSelection] =
useState<FunGifSelection | null>(null);
const handleFunPickerSelectGif = useCallback(
async (gifSelection: FunGifSelection) => {
const { url } = gifSelection.attachmentMedia;
const bytes = await tenorDownload(url);
const file = new File([bytes], 'gif.mp4', {
type: 'video/mp4',
});
processAttachments({
conversationId,
files: [file],
flags: Proto.AttachmentPointer.Flags.GIF,
});
if (draftAttachments.length > 0) {
setConfirmGifSelection(gifSelection);
} else {
toggleDraftGifMessageSendModal({
conversationId,
previousComposerDraftText: draftText ?? '',
previousComposerDraftBodyRanges: draftBodyRanges ?? [],
gifSelection,
});
}
},
[processAttachments, conversationId]
[
conversationId,
toggleDraftGifMessageSendModal,
draftText,
draftBodyRanges,
draftAttachments,
]
);
const handleConfirmGifSelection = useCallback(() => {
strictAssert(confirmGifSelection != null, 'Need selected gif to confirm');
onClearAttachments(conversationId);
toggleDraftGifMessageSendModal({
conversationId,
previousComposerDraftText: draftText ?? '',
previousComposerDraftBodyRanges: draftBodyRanges ?? [],
gifSelection: confirmGifSelection,
});
}, [
confirmGifSelection,
conversationId,
toggleDraftGifMessageSendModal,
draftText,
draftBodyRanges,
onClearAttachments,
]);
const handleCancelGifSelection = useCallback(() => {
setConfirmGifSelection(null);
}, []);
const handleFunPickerAddStickerPack = useCallback(() => {
pushPanelForConversation({
type: PanelType.StickerManager,
@@ -651,6 +682,27 @@ export const CompositionArea = memo(function CompositionArea({
const leftHandSideButtonsFragment = (
<>
{confirmGifSelection && (
<ConfirmationDialog
i18n={i18n}
dialogName="CompositionArea.ConfirmGifSelection"
hasXButton={false}
onClose={handleCancelGifSelection}
onCancel={handleCancelGifSelection}
title={i18n('icu:CompositionArea__ConfirmGifSelection__Title')}
actions={[
{
action: handleConfirmGifSelection,
style: 'affirmative',
text: i18n(
'icu:CompositionArea__ConfirmGifSelection__ReplaceButton'
),
},
]}
>
{i18n('icu:CompositionArea__ConfirmGifSelection__Body')}
</ConfirmationDialog>
)}
{isFunPickerEnabled && (
<div className="CompositionArea__button-cell">
<FunPicker
@@ -677,8 +729,8 @@ export const CompositionArea = memo(function CompositionArea({
onPickEmoji={insertEmoji}
onClose={() => setComposerFocus(conversationId)}
recentEmojis={recentEmojis}
skinTone={skinTone}
onSetSkinTone={onSetSkinTone}
emojiSkinToneDefault={emojiSkinToneDefault}
onEmojiSkinToneDefaultChange={onEmojiSkinToneDefaultChange}
/>
</div>
)}
@@ -1057,7 +1109,7 @@ export const CompositionArea = memo(function CompositionArea({
ourConversationId={ourConversationId}
platform={platform}
recentStickers={recentStickers}
skinTone={skinTone}
emojiSkinToneDefault={emojiSkinToneDefault}
sortedGroupMembers={sortedGroupMembers}
/>
)}
@@ -1155,7 +1207,7 @@ export const CompositionArea = memo(function CompositionArea({
quotedMessageId={quotedMessageId}
sendCounter={sendCounter}
shouldHidePopovers={shouldHidePopovers}
skinTone={skinTone ?? null}
emojiSkinToneDefault={emojiSkinToneDefault ?? null}
sortedGroupMembers={sortedGroupMembers}
theme={theme}
/>