Fix chat input max height (#64)
This commit is contained in:
parent
19478f245c
commit
125fea98c0
|
@ -20,6 +20,7 @@ export function ChatInput({ theme, addMessage }: ChatInputProps) {
|
||||||
const [showEmoji, setShowEmoji] = useState(false);
|
const [showEmoji, setShowEmoji] = useState(false);
|
||||||
const [inputHeight, setInputHeight] = useState(40);
|
const [inputHeight, setInputHeight] = useState(40);
|
||||||
const [imageUint, setImageUint] = useState<undefined | Uint8Array>(undefined);
|
const [imageUint, setImageUint] = useState<undefined | Uint8Array>(undefined);
|
||||||
|
|
||||||
const image = useMemo(() => {
|
const image = useMemo(() => {
|
||||||
if (imageUint) {
|
if (imageUint) {
|
||||||
return uintToImgUrl(imageUint);
|
return uintToImgUrl(imageUint);
|
||||||
|
@ -27,6 +28,7 @@ export function ChatInput({ theme, addMessage }: ChatInputProps) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}, [imageUint]);
|
}, [imageUint]);
|
||||||
|
|
||||||
const addEmoji = (e: any) => {
|
const addEmoji = (e: any) => {
|
||||||
const sym = e.unified.split("-");
|
const sym = e.unified.split("-");
|
||||||
const codesArray: any[] = [];
|
const codesArray: any[] = [];
|
||||||
|
@ -35,8 +37,27 @@ export function ChatInput({ theme, addMessage }: ChatInputProps) {
|
||||||
setContent(content + emoji);
|
setContent(content + emoji);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||||
|
const target = e.target;
|
||||||
|
target.style.height = "40px";
|
||||||
|
target.style.height = `${Math.min(target.scrollHeight, 438)}px`;
|
||||||
|
setInputHeight(target.scrollHeight);
|
||||||
|
setContent(target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onInputKeyPress = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
||||||
|
if (e.key == "Enter" && !e.getModifierState("Shift")) {
|
||||||
|
e.preventDefault();
|
||||||
|
(e.target as HTMLTextAreaElement).style.height = "40px";
|
||||||
|
setInputHeight(40);
|
||||||
|
addMessage(content, imageUint);
|
||||||
|
setImageUint(undefined);
|
||||||
|
setContent("");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InputWrapper>
|
<View>
|
||||||
{showEmoji && (
|
{showEmoji && (
|
||||||
<div>
|
<div>
|
||||||
<Picker
|
<Picker
|
||||||
|
@ -58,7 +79,7 @@ export function ChatInput({ theme, addMessage }: ChatInputProps) {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<AddPictureBtn>
|
<AddPictureInputWrapper>
|
||||||
<PictureIcon />
|
<PictureIcon />
|
||||||
<AddPictureInput
|
<AddPictureInput
|
||||||
type="file"
|
type="file"
|
||||||
|
@ -75,56 +96,85 @@ export function ChatInput({ theme, addMessage }: ChatInputProps) {
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</AddPictureBtn>
|
</AddPictureInputWrapper>
|
||||||
<InputImageWrapper
|
<Row style={{ height: `${inputHeight + (image ? 73 : 0)}px` }}>
|
||||||
style={{ height: `${inputHeight + (image ? 73 : 0)}px` }}
|
|
||||||
>
|
|
||||||
{image && (
|
{image && (
|
||||||
<ImagePreview src={image} onClick={() => setImageUint(undefined)} />
|
<ImagePreviewWrapper>
|
||||||
|
<ImagePreviewOverlay />
|
||||||
|
<ImagePreview src={image} onClick={() => setImageUint(undefined)} />
|
||||||
|
</ImagePreviewWrapper>
|
||||||
)}
|
)}
|
||||||
<Input
|
<Input
|
||||||
placeholder={"Message"}
|
placeholder="Message"
|
||||||
value={content}
|
value={content}
|
||||||
onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
onChange={onInputChange}
|
||||||
const target = e.target;
|
onKeyPress={onInputKeyPress}
|
||||||
target.style.height = "40px";
|
|
||||||
target.style.height = `${Math.min(target.scrollHeight, 160)}px`;
|
|
||||||
setInputHeight(target.scrollHeight);
|
|
||||||
setContent(target.value);
|
|
||||||
}}
|
|
||||||
onKeyPress={(e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
|
||||||
if (e.key == "Enter" && !e.getModifierState("Shift")) {
|
|
||||||
e.preventDefault();
|
|
||||||
(e.target as HTMLTextAreaElement).style.height = "40px";
|
|
||||||
setInputHeight(40);
|
|
||||||
addMessage(content, imageUint);
|
|
||||||
setImageUint(undefined);
|
|
||||||
setContent("");
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</InputImageWrapper>
|
<InputButtons>
|
||||||
<AddEmojiBtn onClick={() => setShowEmoji(!showEmoji)}>
|
<ChatButton onClick={() => setShowEmoji(!showEmoji)}>
|
||||||
<EmojiIcon isActive={showEmoji} />
|
<EmojiIcon isActive={showEmoji} />
|
||||||
</AddEmojiBtn>
|
</ChatButton>
|
||||||
<AddStickerBtn>
|
<ChatButton>
|
||||||
<StickerIcon />
|
<StickerIcon />
|
||||||
</AddStickerBtn>
|
</ChatButton>
|
||||||
<AddGifBtn>
|
<ChatButton>
|
||||||
<GifIcon />
|
<GifIcon />
|
||||||
</AddGifBtn>
|
</ChatButton>
|
||||||
</InputWrapper>
|
</InputButtons>
|
||||||
|
</Row>
|
||||||
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputWrapper = styled.div`
|
const View = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: flex-end;
|
||||||
padding: 6px 8px 6px 10px;
|
padding: 6px 8px 6px 10px;
|
||||||
position: relative;
|
position: relative;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const Row = styled.div`
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
width: 100%;
|
||||||
|
max-height: 438px;
|
||||||
|
padding-right: 6px;
|
||||||
|
background: ${({ theme }) => theme.inputColor};
|
||||||
|
border-radius: 16px 16px 4px 16px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const InputButtons = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
button + button {
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const ImagePreviewWrapper = styled.div`
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 82px;
|
||||||
|
z-index: 1;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const ImagePreviewOverlay = styled.div`
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: #eef2f5;
|
||||||
|
border-radius: 16px 16px 4px 16px;
|
||||||
|
opacity: 0.9;
|
||||||
|
`;
|
||||||
|
|
||||||
const ImagePreview = styled.img`
|
const ImagePreview = styled.img`
|
||||||
|
position: relative;
|
||||||
width: 64px;
|
width: 64px;
|
||||||
height: 64px;
|
height: 64px;
|
||||||
border-radius: 16px 16px 4px 16px;
|
border-radius: 16px 16px 4px 16px;
|
||||||
|
@ -132,32 +182,17 @@ const ImagePreview = styled.img`
|
||||||
margin-top: 9px;
|
margin-top: 9px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const InputImageWrapper = styled.div`
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
background: ${({ theme }) => theme.inputColor};
|
|
||||||
border-radius: 36px 16px 4px 36px;
|
|
||||||
height: 40px;
|
|
||||||
margin-right: 8px;
|
|
||||||
margin-left: 10px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Input = styled.textarea`
|
const Input = styled.textarea`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
|
max-height: 438px;
|
||||||
|
padding: 8px 0 8px 12px;
|
||||||
background: ${({ theme }) => theme.inputColor};
|
background: ${({ theme }) => theme.inputColor};
|
||||||
border: 1px solid ${({ theme }) => theme.inputColor};
|
border: 1px solid ${({ theme }) => theme.inputColor};
|
||||||
color: ${({ theme }) => theme.primary};
|
color: ${({ theme }) => theme.primary};
|
||||||
border-radius: 36px 16px 4px 36px;
|
border-radius: 16px 16px 4px 16px;
|
||||||
outline: none;
|
outline: none;
|
||||||
resize: none;
|
resize: none;
|
||||||
|
|
||||||
padding-top: 9px;
|
|
||||||
padding-bottom: 9px;
|
|
||||||
padding-left: 12px;
|
|
||||||
padding-right: 112px;
|
|
||||||
|
|
||||||
font-family: Inter;
|
font-family: Inter;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
@ -174,36 +209,26 @@ const Input = styled.textarea`
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const AddPictureBtn = styled.label`
|
const AddPictureInputWrapper = styled.div`
|
||||||
cursor: pointer;
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
margin-right: 4px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const AddPictureInput = styled.input`
|
const AddPictureInput = styled.input`
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
position: absolute;
|
|
||||||
z-index: -1;
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const AddEmojiBtn = styled.label`
|
const ChatButton = styled.button`
|
||||||
cursor: pointer;
|
width: 32px;
|
||||||
position: absolute;
|
height: 32px;
|
||||||
bottom: 10px;
|
|
||||||
right: 94px;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
`;
|
|
||||||
|
|
||||||
const AddStickerBtn = styled.label`
|
|
||||||
cursor: pointer;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 10px;
|
|
||||||
right: 58px;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
`;
|
|
||||||
|
|
||||||
const AddGifBtn = styled.label`
|
|
||||||
cursor: pointer;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 10px;
|
|
||||||
right: 20px;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
`;
|
`;
|
||||||
|
|
Loading…
Reference in New Issue