88 lines
2.9 KiB
JavaScript
88 lines
2.9 KiB
JavaScript
import { useState, useRef, memo } from 'react';
|
||
import axios from "axios";
|
||
import { SERVER_BASE_URL } from './App';
|
||
import { EmojiPicker } from './EmojiPicker';
|
||
|
||
|
||
|
||
|
||
|
||
|
||
export var ChatInput = memo(function ChatInput({ sendMessage, user, setSettingsModalOpen, socket, setProgress }) {
|
||
var [content, setContent] = useState("");
|
||
var textinputref = useRef();
|
||
|
||
function appendToTextInput(str) {
|
||
setContent(content => `${content} ${str} `);
|
||
textinputref.current?.select();
|
||
}
|
||
global.appendToTextInput = appendToTextInput;
|
||
|
||
var [showEmojiPicker, setShowEmojiPicker] = useState(false);
|
||
function onSubmit(event) {
|
||
event.preventDefault();
|
||
content = content.trim();
|
||
if (!content) return;
|
||
sendMessage({ content });
|
||
setContent("");
|
||
}
|
||
async function uploadFiles(files) {
|
||
console.debug("uploadFiles", files);
|
||
var formdata = new FormData();
|
||
for (let file of files) formdata.append(file.name, file);
|
||
setProgress(0);
|
||
var res = await axios.post(SERVER_BASE_URL + "/upload", formdata, {
|
||
headers: {
|
||
"Content-Type": "multipart/form-data"
|
||
},
|
||
onUploadProgress: progressEvent => {
|
||
console.debug("progressEvent", progressEvent);
|
||
var progress = progressEvent.loaded / progressEvent.total;
|
||
console.debug("upload progress", `${progress * 100}%`);
|
||
setProgress(progress);
|
||
}
|
||
});
|
||
setProgress(null);
|
||
console.debug("upload res", res.data);
|
||
var codes = res.data.map(({ name, code, type }) => {
|
||
name = name.replaceAll(' ', '_');
|
||
var t = type.toLowerCase().split('/')[0];
|
||
t = t === "image" ? "img" : t === "video" ? "video" : t === "audio" ? "audio" : "file";
|
||
return `[${t}:${code}/${name}]`;
|
||
}).join(" ");
|
||
appendToTextInput(codes);
|
||
}
|
||
return <div className='ChatInput'>
|
||
<form className="flex flex-row" onSubmit={onSubmit}>
|
||
<input
|
||
ref={textinputref}
|
||
className="p-4 flex-1 dark:bg-black"
|
||
style={{ color: user.color }}
|
||
type="text"
|
||
onChange={event => {
|
||
setContent(event.target.value);
|
||
socket.emit("type");
|
||
}}
|
||
onPaste={event => {
|
||
var files = event.clipboardData.files;
|
||
if (files.length) {
|
||
event.preventDefault();
|
||
uploadFiles(files);
|
||
}
|
||
}}
|
||
value={content}
|
||
placeholder="type or paste files and press ENTER">
|
||
</input>
|
||
<input type="submit" className='w-14 h-14 cursor-pointer' value="➡️" />
|
||
<button type="button" className='w-14 h-14' onClick={() => setShowEmojiPicker(!showEmojiPicker)}>🤔</button>
|
||
<label htmlFor="file" className="w-14 h-14 text-center leading-[56px] cursor-pointer">📄</label>
|
||
<input type="file" id="file" className='hidden' onChange={event => {
|
||
uploadFiles(event.target.files);
|
||
event.target.value = null;
|
||
}} multiple></input>
|
||
<button type="button" className='w-14 h-14' onClick={e => setSettingsModalOpen(true)}>⚙️</button>
|
||
</form>
|
||
<EmojiPicker open={showEmojiPicker} setOpen={setShowEmojiPicker} appendToTextInput={appendToTextInput} />
|
||
</div>;
|
||
});
|