feat(chat): support pasting images directly into the chat box
This commit is contained in:
@@ -437,6 +437,58 @@ export function ChatArea() {
|
||||
return () => clearInterval(t);
|
||||
}, [slowmodeRemaining]);
|
||||
|
||||
const handlePaste = async (e: React.ClipboardEvent<HTMLInputElement>) => {
|
||||
const items = e.clipboardData.items;
|
||||
let imageFile: File | null = null;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].type.startsWith('image/')) {
|
||||
imageFile = items[i].getAsFile();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (imageFile) {
|
||||
e.preventDefault();
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('file', imageFile);
|
||||
|
||||
try {
|
||||
const res = await fetch('/api/v1/upload', {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
credentials: 'include'
|
||||
});
|
||||
|
||||
if (!res.ok) throw new Error('Upload failed');
|
||||
|
||||
const data = await res.json();
|
||||
const imageUrl = data.url;
|
||||
|
||||
// Insert into input
|
||||
const imgMarkdown = ``;
|
||||
|
||||
const inputEl = inputRef.current;
|
||||
if (inputEl) {
|
||||
const start = inputEl.selectionStart || 0;
|
||||
const end = inputEl.selectionEnd || 0;
|
||||
const newValue = input.slice(0, start) + imgMarkdown + input.slice(end);
|
||||
setInput(newValue);
|
||||
|
||||
setTimeout(() => {
|
||||
inputEl.focus();
|
||||
inputEl.setSelectionRange(start + imgMarkdown.length, start + imgMarkdown.length);
|
||||
}, 0);
|
||||
} else {
|
||||
setInput(prev => prev + (prev.length > 0 && !prev.endsWith(' ') ? ' ' : '') + imgMarkdown);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to upload image:', err);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = e.target.value;
|
||||
const cursor = e.target.selectionStart ?? value.length;
|
||||
@@ -851,6 +903,7 @@ export function ChatArea() {
|
||||
type="text"
|
||||
value={input}
|
||||
onChange={handleInputChange}
|
||||
onPaste={handlePaste}
|
||||
placeholder="type a message..."
|
||||
className="terminal-input w-full"
|
||||
disabled={!activeChannelId || slowmodeRemaining > 0}
|
||||
|
||||
Reference in New Issue
Block a user