Parcourir la source

Merge pull request #13 from crawlab-team/develop

Develop
Marvin Zhang il y a 5 ans
Parent
commit
9ecc323427

+ 1 - 0
package.json

@@ -52,6 +52,7 @@
     "hash.js": "^1.1.7",
     "lodash": "^4.17.11",
     "log4js": "^5.1.0",
+    "markdown-it": "^10.0.0",
     "moment": "^2.24.0",
     "mongoose": "^5.6.12",
     "morgan": "^1.9.1",

+ 3 - 41
src/components/GlobalHeader/RightContent.tsx

@@ -1,12 +1,8 @@
 import { Icon, Tooltip } from 'antd';
 import React from 'react';
 import { connect } from 'dva';
-import { formatMessage } from 'umi-plugin-react/locale';
 import { ConnectProps, ConnectState } from '@/models/connect';
 
-import Avatar from './AvatarDropdown';
-import HeaderSearch from '../HeaderSearch';
-import SelectLang from '../SelectLang';
 import styles from './index.less';
 
 export type SiderTheme = 'light' | 'dark';
@@ -25,45 +21,11 @@ const GlobalHeaderRight: React.SFC<GlobalHeaderRightProps> = props => {
 
   return (
     <div className={className}>
-      <HeaderSearch
-        className={`${styles.action} ${styles.search}`}
-        placeholder={formatMessage({
-          id: 'component.globalHeader.search',
-        })}
-        dataSource={[
-          formatMessage({
-            id: 'component.globalHeader.search.example1',
-          }),
-          formatMessage({
-            id: 'component.globalHeader.search.example2',
-          }),
-          formatMessage({
-            id: 'component.globalHeader.search.example3',
-          }),
-        ]}
-        onSearch={value => {
-          console.log('input', value);
-        }}
-        onPressEnter={value => {
-          console.log('enter', value);
-        }}
-      />
-      <Tooltip
-        title={formatMessage({
-          id: 'component.globalHeader.help',
-        })}
-      >
-        <a
-          target="_blank"
-          href="https://pro.ant.design/docs/getting-started"
-          rel="noopener noreferrer"
-          className={styles.action}
-        >
-          <Icon type="question-circle-o" />
+      <Tooltip title="Github">
+        <a href="https://github.com/crawlab-team/artipub" target="_blank">
+          <Icon type="github" className={styles.github}/>
         </a>
       </Tooltip>
-      <Avatar />
-      <SelectLang className={styles.action} />
     </div>
   );
 };

+ 6 - 0
src/components/GlobalHeader/index.less

@@ -72,6 +72,12 @@
       background: rgba(255, 255, 255, 0.85);
     }
   }
+  .github {
+    color: #000;
+    cursor: pointer;
+    margin: 0 12px;
+    padding: 0 12px;
+  }
 }
 
 .dark {

+ 2 - 13
src/pages/ArticleEdit/ArticleEdit.scss

@@ -51,25 +51,14 @@
 }
 
 .editor {
-  display: flex;
-  flex-basis: 50%;
-  flex-direction: column;
-  width: 50%;
-  height: 100%;
+  width: 100vw;
+  height: call(100vh - 500px);
   min-height: calc(100vh - 50px);
   overflow-y: auto;
   background-color: #f8f9fa;
   border-right: 1px solid #eee;
 }
 
-.preview {
-  display: flex;
-  flex-basis: 50%;
-  flex-direction: column;
-  width: 50%;
-  height: calc(100vh - 50px);
-}
-
 .footer {
   position: relative;
   z-index: 999;

+ 30 - 81
src/pages/ArticleEdit/ArticleEdit.tsx

@@ -1,23 +1,19 @@
-import React, { ChangeEventHandler, useEffect } from 'react';
+import React, {ChangeEventHandler, useEffect} from 'react';
 // import {PageHeaderWrapper} from '@ant-design/pro-layout';
 import BlankLayout from '@/layouts/BlankLayout';
 // import UserLayout from '@/layouts/UserLayout';
-import { ArticleModelState } from '@/models/article';
-import { ConnectProps, ConnectState, Dispatch } from '@/models/connect';
-import { connect } from 'dva';
-import { Button, Input, message } from 'antd';
-import { Controlled as CodeMirror } from 'react-codemirror2';
-import { Editor, EditorChange, ScrollInfo } from 'codemirror';
-import showdown from 'showdown';
+import {ArticleModelState} from '@/models/article';
+import {ConnectProps, ConnectState, Dispatch} from '@/models/connect';
+import {connect} from 'dva';
+import {Button, Input, message} from 'antd';
+// @ts-ignore
+import MarkdownIt from 'markdown-it';
+import MdEditor from "react-markdown-editor-lite";
 
 // 引入codemirror样式
 import style from './ArticleEdit.scss';
 import 'codemirror/mode/markdown/markdown';
-import { router } from 'umi';
-
-showdown.setOption('tables', true);
-showdown.setOption('tasklists', true);
-showdown.setFlavor('github');
+import {router} from 'umi';
 
 export interface ArticleEditProps extends ConnectProps {
   article: ArticleModelState;
@@ -25,7 +21,7 @@ export interface ArticleEditProps extends ConnectProps {
 }
 
 const ArticleEdit: React.FC<ArticleEditProps> = props => {
-  const { dispatch, article } = props;
+  const {dispatch, article} = props;
 
   const isEdit = (): Boolean => {
     return (
@@ -68,38 +64,27 @@ const ArticleEdit: React.FC<ArticleEditProps> = props => {
   };
 
   // 更新内容
-  const onContentChange = (editor: Editor, data: EditorChange, value: string) => {
+  const onContentChange = (data: any) => {
+    const text = data.text;
+    const html = data.html;
     if (dispatch) {
       dispatch({
         type: 'article/setArticleContent',
         payload: {
-          content: value,
+          content: text,
+          contentHtml: html,
         },
       });
-      setTimeout(() => {
-        updatePreview();
-      }, 0);
     }
   };
 
-  // markdown to html转换器
-  const converter = new showdown.Converter();
-
-  // 更新预览HTML
-  const updatePreview = () => {
-    if (!article || !article.currentArticle) return;
-    const $el = document.getElementById('content');
-    if (!$el) return;
-    const contentHtml = converter.makeHtml(article.currentArticle.content);
-    $el.innerHTML = contentHtml;
-    dispatch({
-      type: 'article/setArticleContentHtml',
-      payload: {
-        contentHtml,
-      },
-    });
+  const onImageUpload = (data: any) => {
+    console.log(data);
   };
 
+  // markdown to html转换器
+  const mdParser = new MarkdownIt();
+
   // 调整CodeMirror高度
   setTimeout(() => {
     const $el = document.querySelector('.CodeMirror');
@@ -108,24 +93,6 @@ const ArticleEdit: React.FC<ArticleEditProps> = props => {
     }
   }, 100);
 
-  // 首次渲染HTML
-  setTimeout(() => {
-    updatePreview();
-  }, 100);
-
-  // 监听左侧Markdown编辑上下滑动
-  const onEditorScroll = (editor: Editor, scrollInfo: ScrollInfo) => {
-    const $el = document.querySelector('#content') as HTMLDivElement;
-    if (!$el) return;
-    $el.scrollTo(
-      0,
-      Math.round((scrollInfo.top / scrollInfo.height) * ($el.scrollHeight + $el.clientHeight)),
-    );
-  };
-
-  // 监听预览上下滑动
-  const onPreviewScroll = (ev: any) => {};
-
   // 点击保存
   const onSave = async () => {
     if (article.currentArticle) {
@@ -192,39 +159,21 @@ const ArticleEdit: React.FC<ArticleEditProps> = props => {
 
         {/*主要内容*/}
         <div className={style.main}>
-          {/*左侧Markdown编辑器*/}
-          <div className={style.editor}>
-            <CodeMirror
-              className={style.codeMirror}
-              value={article.currentArticle ? article.currentArticle.content : ''}
-              options={{
-                mode: 'markdown',
-                theme: 'eclipse',
-                lineNumbers: true,
-                smartIndent: true,
-                lineWrapping: true,
-              }}
-              onBeforeChange={onContentChange}
-              onScroll={onEditorScroll}
-            />
-            <div className={style.footer}>
-              <label style={{ marginLeft: 20 }}>Markdown编辑器</label>
-            </div>
-          </div>
-
-          {/*右侧HTML预览*/}
-          <div id="preview" className={style.preview}>
-            <article id="content" className={style.content} onScroll={onPreviewScroll} />
-            <div className={style.footer}>
-              <label style={{ marginLeft: 20 }}>预览</label>
-            </div>
-          </div>
+          <MdEditor
+            style={{height: 'calc(100vh - 50px)'}}
+            value={article.currentArticle ? article.currentArticle.content : ''}
+            renderHTML={(text) => {
+              return mdParser.render(text);
+            }}
+            onChange={onContentChange}
+            onImageUpload={onImageUpload}
+          />
         </div>
       </div>
     </BlankLayout>
   );
 };
 
-export default connect(({ article }: ConnectState) => ({
+export default connect(({article}: ConnectState) => ({
   article,
 }))(ArticleEdit);