feat: chat stickers
This commit is contained in:
@@ -13,12 +13,13 @@
|
||||
*/
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { Paperclip, SendHorizonal, X } from "lucide-react";
|
||||
import { Paperclip, Smile, SendHorizonal, X } from "lucide-react";
|
||||
import { LinkPreviewCard } from "@/components/chat/link-preview-card";
|
||||
import {
|
||||
ComposerAttachments,
|
||||
type StagedAttachment,
|
||||
} from "@/components/chat/composer-attachments";
|
||||
import { StickerPicker } from "@/components/chat/sticker-picker";
|
||||
import { compressImage } from "@/lib/compress-image";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
@@ -53,6 +54,8 @@ export function ChatComposer({
|
||||
replyToId?: string,
|
||||
previewUrl?: string,
|
||||
attachments?: UploadedAttachment[],
|
||||
/** Reward artwork sent on its own. */
|
||||
stickerKey?: string,
|
||||
) => void;
|
||||
disabled?: boolean;
|
||||
placeholder?: string;
|
||||
@@ -67,6 +70,7 @@ export function ChatComposer({
|
||||
const [staged, setStaged] = useState<StagedAttachment[]>([]);
|
||||
const ref = useRef<HTMLTextAreaElement>(null);
|
||||
const fileRef = useRef<HTMLInputElement>(null);
|
||||
const [pickingSticker, setPickingSticker] = useState(false);
|
||||
const lookupSeq = useRef(0);
|
||||
|
||||
// Grow with the content, up to a cap.
|
||||
@@ -253,6 +257,15 @@ export function ChatComposer({
|
||||
>
|
||||
<Paperclip className="size-4" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setPickingSticker(true)}
|
||||
disabled={disabled}
|
||||
aria-label="Send a sticker"
|
||||
className="inline-flex size-9 shrink-0 items-center justify-center rounded-full text-muted-foreground hover:text-foreground disabled:opacity-40"
|
||||
>
|
||||
<Smile className="size-4" />
|
||||
</button>
|
||||
|
||||
<textarea
|
||||
ref={ref}
|
||||
@@ -303,6 +316,16 @@ export function ChatComposer({
|
||||
<SendHorizonal className="size-4" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{pickingSticker && (
|
||||
<StickerPicker
|
||||
// Sent on its own, with no text: a sticker IS the message.
|
||||
onPick={(sticker) =>
|
||||
onSend("", undefined, undefined, undefined, sticker.key)
|
||||
}
|
||||
onClose={() => setPickingSticker(false)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user