feat: text input for mobile
This commit is contained in:
@@ -17,13 +17,11 @@ import {
|
||||
MentionCombobox
|
||||
} from "@udecode/plate";
|
||||
import { createComboboxPlugin } from "@udecode/plate-combobox";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ReactEditor } from "slate-react";
|
||||
import useUploadFile from "../../hook/useUploadFile";
|
||||
import { CONFIG } from "./config";
|
||||
import User from "../User";
|
||||
import { useAppSelector } from "../../../app/store";
|
||||
import Button from "../styled/Button";
|
||||
import { isMobile } from "../../utils";
|
||||
export const TEXT_EDITOR_PREFIX = "_text_editor";
|
||||
|
||||
@@ -49,7 +47,7 @@ const Plugins: FC<Props> = ({
|
||||
sendMessages,
|
||||
members = []
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
// const { getMenuProps, getItemProps } = useComboboxControls();
|
||||
const [context, to] = id.split("_") as [ctx, number];
|
||||
const { addStageFile } = useUploadFile({ context, id: to });
|
||||
@@ -229,7 +227,6 @@ const Plugins: FC<Props> = ({
|
||||
/>
|
||||
) : null}
|
||||
</Plate>
|
||||
<Button onClick={handleSend} className="mini md:hidden absolute right-1.5 bottom-1.5">{t("action.send")}</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -17,6 +17,7 @@ import MixedInput, { useMixedEditor } from "../MixedInput";
|
||||
import useDraft from "../../hook/useDraft";
|
||||
import useUploadFile from "../../hook/useUploadFile";
|
||||
import { useAppDispatch, useAppSelector } from "../../../app/store";
|
||||
import TextInput from "../TextInput";
|
||||
|
||||
const Modes = {
|
||||
text: "text",
|
||||
@@ -138,45 +139,50 @@ const Send: FC<IProps> = ({
|
||||
context == "channel" ? (channelsData[id]?.is_public ? uids : channelsData[id]?.members) : [];
|
||||
const isMarkdownMode = mode == Modes.markdown;
|
||||
return (
|
||||
<div
|
||||
className={clsx(`send relative bg-gray-200 rounded-lg w-full dark:bg-gray-600 ${mode} ${markdownFullscreen ? "fullscreen" : ""} ${replying_mid ? "reply" : ""
|
||||
} ${context}`, isMarkdownMode && markdownFullscreen && '-mt-9')}
|
||||
>
|
||||
{replying_mid && <Replying context={context} mid={replying_mid} id={id} />}
|
||||
{mode == Modes.text && <UploadFileList context={context} id={id} />}
|
||||
<>
|
||||
{/* mobile input */}
|
||||
<TextInput sendMessage={handleSendMessage} placeholder={placeholder} />
|
||||
{/* PC input */}
|
||||
<div
|
||||
className={clsx(`send hidden md:block relative bg-gray-200 rounded-lg w-full dark:bg-gray-600 ${mode} ${markdownFullscreen ? "fullscreen" : ""} ${replying_mid ? "reply" : ""
|
||||
} ${context}`, isMarkdownMode && markdownFullscreen && '-mt-9')}
|
||||
>
|
||||
{replying_mid && <Replying context={context} mid={replying_mid} id={id} />}
|
||||
{mode == Modes.text && <UploadFileList context={context} id={id} />}
|
||||
|
||||
<div className={clsx(`flex justify-between items-center gap-4 px-2 md:px-4 py-1 md:py-3.5`, isMarkdownMode && `grid grid-cols-[1fr_1fr] grid-rows-[auto_auto] gap-0`)}>
|
||||
<EmojiPicker selectEmoji={insertEmoji} />
|
||||
{mode == Modes.text && (
|
||||
<MixedInput
|
||||
updateDraft={getUpdateDraft()}
|
||||
initialValue={getDraft()}
|
||||
members={members}
|
||||
id={`${context}_${id}`}
|
||||
placeholder={placeholder}
|
||||
sendMessages={handleSendMessage}
|
||||
<div className={clsx(`flex justify-between items-center gap-4 px-4 py-3.5`, isMarkdownMode && `grid grid-cols-[1fr_1fr] grid-rows-[auto_auto] gap-0`)}>
|
||||
<EmojiPicker selectEmoji={insertEmoji} />
|
||||
{mode == Modes.text && (
|
||||
<MixedInput
|
||||
updateDraft={getUpdateDraft()}
|
||||
initialValue={getDraft()}
|
||||
members={members}
|
||||
id={`${context}_${id}`}
|
||||
placeholder={placeholder}
|
||||
sendMessages={handleSendMessage}
|
||||
/>
|
||||
)}
|
||||
<Toolbar
|
||||
context={context}
|
||||
to={id}
|
||||
mode={mode}
|
||||
toggleMode={toggleMode}
|
||||
fullscreen={markdownFullscreen}
|
||||
toggleMarkdownFullscreen={toggleMarkdownFullscreen}
|
||||
/>
|
||||
)}
|
||||
<Toolbar
|
||||
context={context}
|
||||
to={id}
|
||||
mode={mode}
|
||||
toggleMode={toggleMode}
|
||||
fullscreen={markdownFullscreen}
|
||||
toggleMarkdownFullscreen={toggleMarkdownFullscreen}
|
||||
/>
|
||||
{mode == Modes.markdown && (
|
||||
<MarkdownEditor
|
||||
updateDraft={getUpdateDraft("markdown")}
|
||||
initialValue={getDraft("markdown")}
|
||||
height={markdownFullscreen ? `calc(100vh - 168px)` : `30vh`}
|
||||
placeholder={placeholder}
|
||||
setEditorInstance={setMarkdownEditor}
|
||||
sendMarkdown={sendMarkdown}
|
||||
/>
|
||||
)}
|
||||
{mode == Modes.markdown && (
|
||||
<MarkdownEditor
|
||||
updateDraft={getUpdateDraft("markdown")}
|
||||
initialValue={getDraft("markdown")}
|
||||
height={markdownFullscreen ? `calc(100vh - 168px)` : `30vh`}
|
||||
placeholder={placeholder}
|
||||
setEditorInstance={setMarkdownEditor}
|
||||
sendMarkdown={sendMarkdown}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import { ChangeEvent, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import TextareaAutoSize from "react-textarea-autosize";
|
||||
|
||||
import Button from "../styled/Button";
|
||||
|
||||
type Props = {
|
||||
placeholder: string,
|
||||
sendMessage: any
|
||||
}
|
||||
const TextInput = ({ sendMessage, placeholder }: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const [currMsg, setCurrMsg] = useState("");
|
||||
const handleMsgChange = (evt: ChangeEvent<HTMLTextAreaElement>) => {
|
||||
setCurrMsg(evt.target.value);
|
||||
};
|
||||
const handleSend = () => {
|
||||
if (!currMsg) return;
|
||||
// todo
|
||||
const msg = [{ type: "text", content: currMsg }];
|
||||
sendMessage(msg);
|
||||
setCurrMsg("");
|
||||
};
|
||||
return (
|
||||
<div className='md:hidden relative mb-1 p-1 flex items-center w-full text-gray-600 dark:text-white bg-gray-200 dark:bg-gray-600 rounded-lg'>
|
||||
<TextareaAutoSize
|
||||
autoFocus
|
||||
onFocus={(e) =>
|
||||
e.currentTarget.setSelectionRange(
|
||||
e.currentTarget.value.length,
|
||||
e.currentTarget.value.length
|
||||
)
|
||||
}
|
||||
// ref={inputRef}
|
||||
className="p-1 w-full min-h-[28px] resize-none bg-transparent text-gray-800 dark:text-white text-sm break-all"
|
||||
maxRows={8}
|
||||
minRows={1}
|
||||
// onKeyDown={handleInputKeydown}
|
||||
onChange={handleMsgChange}
|
||||
value={currMsg}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
<Button onClick={handleSend} className="mini absolute right-1.5 bottom-1.5">{t("action.send")}</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TextInput;
|
||||
@@ -2,7 +2,8 @@ import { forwardRef, TextareaHTMLAttributes } from "react";
|
||||
|
||||
type Props = TextareaHTMLAttributes<HTMLTextAreaElement>
|
||||
const StyledTextarea = forwardRef(({ className, ...rest }: Props, ref) => {
|
||||
return <textarea ref={ref} className={`rounded text-sm p-2 bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 resize-none w-full shadow-sm border border-gray-200 dark:border-gray-400
|
||||
return <textarea ref={ref} className={`rounded text-sm p-2 bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 resize-none w-full shadow-sm
|
||||
border border-solid border-gray-200 dark:border-gray-400
|
||||
disabled:bg-gray-100 dark:disabled:bg-gray-800/50
|
||||
disabled:text-gray-400 dark:disabled:text-gray-500
|
||||
disabled:pointer-events-none
|
||||
|
||||
Reference in New Issue
Block a user