Merge branch 'feat/ui-0.7.0' of git.backyard.segmentfault.com:opensource/answer into feat/ui-0.7.0

This commit is contained in:
haitao(lj) 2022-12-16 17:06:03 +08:00
commit 96a7b47923
11 changed files with 1214 additions and 93 deletions

View File

@ -552,7 +552,7 @@ ui:
placeholder: Search placeholder: Search
footer: footer:
build_on: >- build_on: >-
Built on <1> Answer </1>- the open-source software that power Q&A Built on <1> Answer </1>- the open-source software that powers Q&A
communities.<br />Made with love © {{cc}}. communities.<br />Made with love © {{cc}}.
upload_img: upload_img:
name: Change name: Change
@ -732,6 +732,7 @@ ui:
write_answer: write_answer:
title: Your Answer title: Your Answer
btn_name: Post your answer btn_name: Post your answer
add_another_answer: Add another answer
confirm_title: Continue to answer confirm_title: Continue to answer
continue: Continue continue: Continue
confirm_info: >- confirm_info: >-

View File

@ -505,7 +505,7 @@ ui:
placeholder: 搜索 placeholder: 搜索
footer: footer:
build_on: >- build_on: >-
Built on <1> Answer </1>- the open-source software that power Q&A Built on <1> Answer </1>- the open-source software that powers Q&A
communities<br />Made with love © 2022 Answer communities<br />Made with love © 2022 Answer
upload_img: upload_img:
name: 更改图片 name: 更改图片

View File

@ -50,6 +50,7 @@
"@testing-library/jest-dom": "^4.2.4", "@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^13.3.0", "@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"@types/color": "^3.0.3",
"@types/jest": "^27.5.2", "@types/jest": "^27.5.2",
"@types/lodash": "^4.14.184", "@types/lodash": "^4.14.184",
"@types/marked": "^4.0.6", "@types/marked": "^4.0.6",

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@ const Editor = ({
onBlur, onBlur,
editorPlaceholder, editorPlaceholder,
getEditorInstance, getEditorInstance,
autoFocus,
}) => { }) => {
const elRef = useRef<HTMLDivElement>(null); const elRef = useRef<HTMLDivElement>(null);
const [editor, setEditor] = useState<CodeMirror.Editor | null>(null); const [editor, setEditor] = useState<CodeMirror.Editor | null>(null);
@ -38,6 +39,9 @@ const Editor = ({
lineWrapping: true, lineWrapping: true,
placeholder: editorPlaceholder, placeholder: editorPlaceholder,
}); });
if (autoFocus) {
cm.focus();
}
cm.on('change', (e) => { cm.on('change', (e) => {
const newValue = e.getValue(); const newValue = e.getValue();
eventRef.current?.onChange?.(newValue); eventRef.current?.onChange?.(newValue);

View File

@ -169,7 +169,7 @@
} }
} }
.content-wrap { .content-wrap {
height: 270px; height: 264px;
} }
.CodeMirror { .CodeMirror {

View File

@ -49,10 +49,19 @@ interface Props extends EventRef {
editorPlaceholder?; editorPlaceholder?;
className?; className?;
value; value;
autoFocus?: boolean;
} }
const MDEditor: ForwardRefRenderFunction<EditorRef, Props> = ( const MDEditor: ForwardRefRenderFunction<EditorRef, Props> = (
{ editorPlaceholder = '', className = '', value, onChange, onFocus, onBlur }, {
editorPlaceholder = '',
className = '',
value,
onChange,
onFocus,
onBlur,
autoFocus = false,
},
ref, ref,
) => { ) => {
const [markdown, setMarkdown] = useState<string>(value || ''); const [markdown, setMarkdown] = useState<string>(value || '');
@ -146,6 +155,7 @@ const MDEditor: ForwardRefRenderFunction<EditorRef, Props> = (
<div className="content-wrap"> <div className="content-wrap">
<Editor <Editor
value={markdown} value={markdown}
autoFocus={autoFocus}
onChange={handleChange} onChange={handleChange}
onFocus={handleFocus} onFocus={handleFocus}
onBlur={handleBlur} onBlur={handleBlur}

View File

@ -1,7 +1,9 @@
import { FC, useRef, useEffect, memo } from 'react'; import { FC, useRef, useEffect, memo } from 'react';
import { FormControl, FormControlProps } from 'react-bootstrap'; import { FormControl, FormControlProps } from 'react-bootstrap';
const TextArea: FC<FormControlProps> = ({ value, onChange, size }) => { const TextArea: FC<
FormControlProps & { rows?: number; autoFocus?: boolean }
> = ({ value, onChange, size, rows = 1, autoFocus = true, ...rest }) => {
const ref = useRef<HTMLTextAreaElement>(null); const ref = useRef<HTMLTextAreaElement>(null);
const autoGrow = () => { const autoGrow = () => {
@ -21,13 +23,14 @@ const TextArea: FC<FormControlProps> = ({ value, onChange, size }) => {
<FormControl <FormControl
as="textarea" as="textarea"
className="resize-none font-monospace" className="resize-none font-monospace"
rows={1} rows={rows}
size={size} size={size}
value={value} value={value}
onChange={onChange} onChange={onChange}
autoFocus autoFocus={autoFocus}
ref={ref} ref={ref}
onInput={autoGrow} onInput={autoGrow}
{...rest}
/> />
); );
}; };

View File

@ -10,15 +10,12 @@ const AnswerLinks = () => {
<h6 className="mb-3">{t('answer_links')}</h6> <h6 className="mb-3">{t('answer_links')}</h6>
<Row> <Row>
<Col xs={6}> <Col xs={6}>
<a href="https://answer.dev" target="_blank" rel="noreferrer"> <a href="https://answer.dev/docs" target="_blank" rel="noreferrer">
{t('documents')} {t('documents')}
</a> </a>
</Col> </Col>
<Col xs={6}> <Col xs={6}>
<a <a href="https://meta.answer.dev" target="_blank" rel="noreferrer">
href="https://github.com/answerdev/answer/issues"
target="_blank"
rel="noreferrer">
{t('feedback')} {t('feedback')}
</a> </a>
</Col> </Col>

View File

@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next';
import { marked } from 'marked'; import { marked } from 'marked';
import classNames from 'classnames'; import classNames from 'classnames';
import { Editor, Modal } from '@/components'; import { Editor, Modal, TextArea } from '@/components';
import { FormDataType } from '@/common/interface'; import { FormDataType } from '@/common/interface';
import { postAnswer } from '@/services'; import { postAnswer } from '@/services';
@ -81,10 +81,13 @@ const Index: FC<Props> = ({ visible = false, data, callback }) => {
handleSubmit(); handleSubmit();
}; };
const handleFocusForTextArea = () => {
setShowEditor(true);
};
return ( return (
<Form noValidate className="mt-4"> <Form noValidate className="mt-4">
{showEditor && ( {(!data.answered || showEditor) && (
<Form.Group className="mb-3"> <Form.Group className="mb-3">
<Form.Label> <Form.Label>
<h5>{t('title')}</h5> <h5>{t('title')}</h5>
@ -93,28 +96,41 @@ const Index: FC<Props> = ({ visible = false, data, callback }) => {
isInvalid={formData.content.isInvalid} isInvalid={formData.content.isInvalid}
className="d-none" className="d-none"
/> />
<Editor {!showEditor && !data.answered && (
className={classNames( <div className="d-flex">
'form-control p-0', <TextArea
focusType === 'answer' && 'focus', className="w-100"
)} rows={8}
value={formData.content.value} autoFocus={false}
onChange={(val) => { onFocus={handleFocusForTextArea}
setFormData({ />
content: { </div>
value: val, )}
isInvalid: false, {showEditor && (
errorMsg: '', <Editor
}, className={classNames(
}); 'form-control p-0',
}} focusType === 'answer' && 'focus',
onFocus={() => { )}
setForceType('answer'); value={formData.content.value}
}} autoFocus
onBlur={() => { onChange={(val) => {
setForceType(''); setFormData({
}} content: {
/> value: val,
isInvalid: false,
errorMsg: '',
},
});
}}
onFocus={() => {
setForceType('answer');
}}
onBlur={() => {
setForceType('');
}}
/>
)}
<Form.Control.Feedback type="invalid"> <Form.Control.Feedback type="invalid">
{formData.content.errorMsg} {formData.content.errorMsg}
@ -122,7 +138,11 @@ const Index: FC<Props> = ({ visible = false, data, callback }) => {
</Form.Group> </Form.Group>
)} )}
<Button onClick={clickBtn}>{t('btn_name')}</Button> {data.answered && !showEditor ? (
<Button onClick={clickBtn}>{t('add_another_answer')}</Button>
) : (
<Button onClick={clickBtn}>{t('btn_name')}</Button>
)}
</Form> </Form>
); );
}; };

View File

@ -128,6 +128,13 @@ const Index = () => {
count: answers.count + 1, count: answers.count + 1,
list: [...answers.list, obj], list: [...answers.list, obj],
}); });
if (question) {
setQuestion({
...question,
answered: true,
});
}
}; };
useEffect(() => { useEffect(() => {