|
@@ -1,14 +1,16 @@
|
|
|
-import { Button, message, Modal } from 'antd';
|
|
|
-import React, { useEffect, useState } from 'react';
|
|
|
-import { PageHeaderWrapper } from '@ant-design/pro-layout';
|
|
|
-import { useSingleState } from 'nice-hooks';
|
|
|
+import {Button, Input, message, Modal} from 'antd';
|
|
|
+import React, {useEffect, useState} from 'react';
|
|
|
+import {PageHeaderWrapper} from '@ant-design/pro-layout';
|
|
|
+import {useSingleState} from 'nice-hooks';
|
|
|
import Quill from '@/pages/Memory/components/Quill';
|
|
|
import UpdateForm from '@/pages/Memory/components/UpdateForm';
|
|
|
-import { TableListItem } from '../MemoryList/data.d';
|
|
|
+import {TableListItem} from '../MemoryList/data.d';
|
|
|
import service from './service';
|
|
|
import styles from './index.less';
|
|
|
-import { DownOutlined, ExclamationCircleOutlined } from '@ant-design/icons/lib';
|
|
|
-import { getRandom, getTextFromHtml } from '@/utils/utils';
|
|
|
+import {DownOutlined, ExclamationCircleOutlined} from '@ant-design/icons/lib';
|
|
|
+import {getRandom, getTextFromHtml} from '@/utils/utils';
|
|
|
+
|
|
|
+const {TextArea} = Input;
|
|
|
|
|
|
enum Step {
|
|
|
MAIN = 0,
|
|
@@ -22,12 +24,16 @@ interface State {
|
|
|
showBack?: boolean;
|
|
|
}
|
|
|
|
|
|
+const practice = "practice";
|
|
|
+
|
|
|
const TableList: React.FC<{}> = () => {
|
|
|
const [btnDisable, setBtnDisable] = useState(false);
|
|
|
const [showMore, setShowMore] = useState(false);
|
|
|
+
|
|
|
+ const [backPractice, setBackPractice] = useState("");
|
|
|
let counting = false;
|
|
|
|
|
|
- const { confirm } = Modal;
|
|
|
+ const {confirm} = Modal;
|
|
|
|
|
|
const [state, setState] = useSingleState<State>({
|
|
|
remindCount: 0,
|
|
@@ -46,13 +52,18 @@ const TableList: React.FC<{}> = () => {
|
|
|
userId: 0,
|
|
|
});
|
|
|
|
|
|
+ const isPracticeFocus = () => {
|
|
|
+ // @ts-ignore
|
|
|
+ return document.activeElement.id === practice;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 查询用户待提醒数量
|
|
|
* @param fields
|
|
|
*/
|
|
|
const countRemind = async () => {
|
|
|
// 如果上一个查询还没有结束,则直接返回
|
|
|
- console.log(counting);
|
|
|
+ // console.log(counting);
|
|
|
if (counting) {
|
|
|
return;
|
|
|
}
|
|
@@ -62,7 +73,7 @@ const TableList: React.FC<{}> = () => {
|
|
|
const res = await service.countRemind({});
|
|
|
hide();
|
|
|
if (res.success) {
|
|
|
- setState({ remindCount: parseInt(res.data, 10) });
|
|
|
+ setState({remindCount: parseInt(res.data, 10)});
|
|
|
}
|
|
|
counting = false;
|
|
|
} catch (error) {
|
|
@@ -90,34 +101,51 @@ const TableList: React.FC<{}> = () => {
|
|
|
// 只要有返回值,就使按钮可见
|
|
|
setBtnDisable(false);
|
|
|
if (res.success) {
|
|
|
- setMemory({ ...memory, ...res.data });
|
|
|
+ setMemory({...memory, ...res.data});
|
|
|
} else {
|
|
|
- setState({ step: Step.MAIN });
|
|
|
+ setState({step: Step.MAIN});
|
|
|
}
|
|
|
};
|
|
|
|
|
|
const memorySuccess = async (factorInt: number) => {
|
|
|
setBtnDisable(true);
|
|
|
- memoryRes(await service.memorySuccess({ id: memory.id, factor: factorInt * getRandom() }));
|
|
|
+ memoryRes(await service.memorySuccess({id: memory.id, factor: factorInt * getRandom()}));
|
|
|
};
|
|
|
|
|
|
const findNextLine = async () => {
|
|
|
const res = await service.findNext({});
|
|
|
if (res.success) {
|
|
|
- setMemory({ ...memory, ...res.data });
|
|
|
+ setMemory({...memory, ...res.data});
|
|
|
} else {
|
|
|
- setState({ step: Step.MAIN });
|
|
|
+ setState({step: Step.MAIN});
|
|
|
}
|
|
|
};
|
|
|
|
|
|
// 绑定快捷键
|
|
|
const bindShortKey = () => {
|
|
|
document.onkeydown = (ev) => {
|
|
|
+
|
|
|
+ // 在input有焦点的时候
|
|
|
+ if (isPracticeFocus()) {
|
|
|
+ // 按esc
|
|
|
+ if (ev.key.toLowerCase() === 'escape') {
|
|
|
+ // @ts-ignore
|
|
|
+ document.getElementById(practice).blur();
|
|
|
+ }
|
|
|
+ // 其他情况
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ev.key === 'i' && state.step === Step.MEMORY && !isPracticeFocus()) {
|
|
|
+ ev.preventDefault();
|
|
|
+ // @ts-ignore
|
|
|
+ document.getElementById(practice).focus();
|
|
|
+ }
|
|
|
// 空格显示背面和默认选择
|
|
|
if (ev.key === ' ' && state.step === Step.MEMORY) {
|
|
|
ev.preventDefault(); // 关闭浏览器快捷键
|
|
|
if (state.showBack === false) {
|
|
|
- setState({ showBack: true });
|
|
|
+ setState({showBack: true});
|
|
|
} else {
|
|
|
memorySuccess(2);
|
|
|
}
|
|
@@ -125,20 +153,20 @@ const TableList: React.FC<{}> = () => {
|
|
|
// 空格刷新
|
|
|
// 如果待复习大于0,则直接进去
|
|
|
if (state.remindCount > 0) {
|
|
|
- setState({ step: Step.MEMORY });
|
|
|
+ setState({step: Step.MEMORY});
|
|
|
} else {
|
|
|
// 刷新一下,再判断是否应该去复习
|
|
|
countRemind();
|
|
|
if (state.remindCount > 0) {
|
|
|
- setState({ step: Step.MEMORY });
|
|
|
+ setState({step: Step.MEMORY});
|
|
|
}
|
|
|
}
|
|
|
} else if (ev.key.toLowerCase() === 'e') {
|
|
|
// 快捷 E,进入编辑、新建页面
|
|
|
- setState({ step: Step.ADD });
|
|
|
+ setState({step: Step.ADD});
|
|
|
} else if (ev.key.toLowerCase() === 'escape') {
|
|
|
// esc键回到主页
|
|
|
- setState({ step: Step.MAIN });
|
|
|
+ setState({step: Step.MAIN});
|
|
|
}
|
|
|
};
|
|
|
};
|
|
@@ -153,7 +181,7 @@ const TableList: React.FC<{}> = () => {
|
|
|
|
|
|
useEffect(() => {
|
|
|
// 关闭背面,清空 memory
|
|
|
- setState({ showBack: false });
|
|
|
+ setState({showBack: false});
|
|
|
clearMemory();
|
|
|
|
|
|
if (state.step === Step.MAIN) {
|
|
@@ -172,12 +200,13 @@ const TableList: React.FC<{}> = () => {
|
|
|
// 进入复习页面后
|
|
|
// 如果没有文字,并且也没有图片
|
|
|
if (getTextFromHtml(memory.back).length === 0 && memory.back.indexOf('img') < 0) {
|
|
|
- setState({ showBack: true });
|
|
|
+ setState({showBack: true});
|
|
|
} else {
|
|
|
- setState({ showBack: false });
|
|
|
+ setState({showBack: false});
|
|
|
}
|
|
|
// 隐藏更多按钮
|
|
|
setShowMore(false);
|
|
|
+ setBackPractice("")
|
|
|
}, [memory.front]);
|
|
|
|
|
|
return (
|
|
@@ -187,7 +216,7 @@ const TableList: React.FC<{}> = () => {
|
|
|
<div>
|
|
|
待复习:<b>{state.remindCount}</b>
|
|
|
</div>
|
|
|
- <p />
|
|
|
+ <p/>
|
|
|
<Button
|
|
|
type="primary"
|
|
|
size="large"
|
|
@@ -196,13 +225,13 @@ const TableList: React.FC<{}> = () => {
|
|
|
message.info('已经复习完了哟!');
|
|
|
return;
|
|
|
}
|
|
|
- setState({ step: Step.MEMORY });
|
|
|
+ setState({step: Step.MEMORY});
|
|
|
}}
|
|
|
>
|
|
|
复习
|
|
|
</Button>
|
|
|
- <p />
|
|
|
- <Button type="primary" size="large" onClick={() => setState({ step: Step.ADD })}>
|
|
|
+ <p/>
|
|
|
+ <Button type="primary" size="large" onClick={() => setState({step: Step.ADD})}>
|
|
|
添加
|
|
|
</Button>
|
|
|
</div>
|
|
@@ -211,15 +240,17 @@ const TableList: React.FC<{}> = () => {
|
|
|
{state.step === Step.MEMORY ? (
|
|
|
<div>
|
|
|
正面:
|
|
|
- <p />
|
|
|
- <Quill theme="bubble" readonly onChange={() => {}} value={memory.front} />
|
|
|
- <p />
|
|
|
+ <p/>
|
|
|
+ <Quill theme="bubble" readonly onChange={() => {
|
|
|
+ }} value={memory.front}/>
|
|
|
+ <p/>
|
|
|
{state.showBack ? (
|
|
|
<div>
|
|
|
反面:
|
|
|
- <p />
|
|
|
- <Quill theme="bubble" readonly onChange={() => {}} value={memory.back} />
|
|
|
- <p />
|
|
|
+ <p/>
|
|
|
+ <Quill theme="bubble" readonly onChange={() => {
|
|
|
+ }} value={memory.back}/>
|
|
|
+ <p/>
|
|
|
<div className={styles.divBottom}>
|
|
|
<Button
|
|
|
type="primary"
|
|
@@ -256,7 +287,7 @@ const TableList: React.FC<{}> = () => {
|
|
|
setShowMore(!showMore);
|
|
|
}}
|
|
|
>
|
|
|
- <DownOutlined />
|
|
|
+ <DownOutlined/>
|
|
|
</Button>
|
|
|
{showMore ? (
|
|
|
<div>
|
|
@@ -289,7 +320,7 @@ const TableList: React.FC<{}> = () => {
|
|
|
onClick={async () => {
|
|
|
confirm({
|
|
|
title: '确定删除吗?',
|
|
|
- icon: <ExclamationCircleOutlined />,
|
|
|
+ icon: <ExclamationCircleOutlined/>,
|
|
|
content: '删除后无法恢复',
|
|
|
okText: '确定',
|
|
|
okType: 'danger',
|
|
@@ -322,7 +353,7 @@ const TableList: React.FC<{}> = () => {
|
|
|
<Button
|
|
|
type="primary"
|
|
|
onClick={() => {
|
|
|
- setState({ step: Step.ADD });
|
|
|
+ setState({step: Step.ADD});
|
|
|
}}
|
|
|
>
|
|
|
编辑
|
|
@@ -331,7 +362,7 @@ const TableList: React.FC<{}> = () => {
|
|
|
<Button
|
|
|
type="primary"
|
|
|
onClick={() => {
|
|
|
- setState({ step: Step.MAIN });
|
|
|
+ setState({step: Step.MAIN});
|
|
|
}}
|
|
|
>
|
|
|
关闭
|
|
@@ -346,13 +377,22 @@ const TableList: React.FC<{}> = () => {
|
|
|
<Button
|
|
|
type="primary"
|
|
|
onClick={() => {
|
|
|
- setState({ showBack: true });
|
|
|
+ setState({showBack: true});
|
|
|
}}
|
|
|
>
|
|
|
显示反面
|
|
|
</Button>
|
|
|
</div>
|
|
|
)}
|
|
|
+ {/* 答案演练板 */}
|
|
|
+ <br/>
|
|
|
+ <TextArea
|
|
|
+ id={practice}
|
|
|
+ autoSize
|
|
|
+ value={backPractice}
|
|
|
+ onChange={(e) => setBackPractice(e.target.value)}
|
|
|
+ placeholder="答案演练板"
|
|
|
+ />
|
|
|
</div>
|
|
|
) : null}
|
|
|
|
|
@@ -360,7 +400,7 @@ const TableList: React.FC<{}> = () => {
|
|
|
<UpdateForm
|
|
|
onCancel={() => {
|
|
|
bindShortKey();
|
|
|
- setState({ step: Step.MAIN });
|
|
|
+ setState({step: Step.MAIN});
|
|
|
}}
|
|
|
modalVisible={state.step === Step.ADD}
|
|
|
values={memory}
|