Fun picker improvements
This commit is contained in:
@@ -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}
|
||||
/>
|
||||
|
Reference in New Issue
Block a user