mirror of https://gitee.com/answerdev/answer.git
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:
commit
96a7b47923
|
@ -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: >-
|
||||||
|
|
|
@ -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: 更改图片
|
||||||
|
|
|
@ -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",
|
||||||
|
|
1190
ui/pnpm-lock.yaml
1190
ui/pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||||
|
|
|
@ -169,7 +169,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.content-wrap {
|
.content-wrap {
|
||||||
height: 270px;
|
height: 264px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CodeMirror {
|
.CodeMirror {
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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(() => {
|
||||||
|
|
Loading…
Reference in New Issue