Просмотр исходного кода

make PageEditorByHackmd function component

Kami-jo 3 лет назад
Родитель
Сommit
14a0dec6c1
1 измененных файлов с 178 добавлено и 195 удалено
  1. 178 195
      packages/app/src/components/PageEditorByHackmd.jsx

+ 178 - 195
packages/app/src/components/PageEditorByHackmd.jsx

@@ -6,7 +6,6 @@ import PropTypes from 'prop-types';
 import { useTranslation } from 'react-i18next';
 
 
-import { appContainer } from '~/client/base';
 import AppContainer from '~/client/services/AppContainer';
 import EditorContainer from '~/client/services/EditorContainer';
 import PageContainer from '~/client/services/PageContainer';
@@ -47,45 +46,41 @@ const PageEditorByHackmd = (props) => {
   const [errorMessage, setErrorMessage] = useState('');
   const [errorReason, setErrorReason] = useState('');
 
-  // componentWillMount() {
-  //   this.props.appContainer.registerComponentInstance('PageEditorByHackmd', this);
-  // }
-
-  // /**
-  //  * return markdown document of HackMD
-  //  * @return {Promise<string>}
-  //  */
-  // getMarkdown() {
-  //   const { t } = this.props;
-  //   if (!this.state.isInitialized) {
-  //     return Promise.reject(new Error(t('hackmd.not_initialized')));
-  //   }
-
-  //   return this.hackmdEditor.getValue();
-  // }
-
-  // /**
-  //  * reset initialized status
-  //  */
-  // reset() {
-  //   this.setState({ isInitialized: false });
-  // }
-
-  const getHackmdUri = () => {
+  const hackmdEditorRef = useRef(null);
+
+  useEffect(() => {
+    const pageEditorByHackmdInstance = {
+      getMarkdown: () => {
+        if (!isInitialized) {
+          return Promise.reject(new Error(t('hackmd.not_initialized')));
+        }
+
+        return hackmdEditorRef.current.getValue();
+      },
+    };
+    appContainer.registerComponentInstance('PageEditorByHackmd', pageEditorByHackmdInstance);
+  }, [appContainer, isInitialized, t]);
+
+  /**
+   * reset initialized status
+   */
+  const reset = () => {
+    setIsInitialized(false);
+  };
+
+  const getHackmdUri = useCallback(() => {
     const envVars = appContainer.getConfig().env;
     return envVars.HACKMD_URI;
+  }, [appContainer]);
+
+  const isResume = () => {
+    const {
+      pageIdOnHackmd, hasDraftOnHackmd, isHackmdDraftUpdatingInRealtime,
+    } = pageContainer.state;
+    const isPageExistsOnHackmd = (pageIdOnHackmd != null);
+    return (isPageExistsOnHackmd && hasDraftOnHackmd) || isHackmdDraftUpdatingInRealtime;
   };
 
-  // get isResume() {
-  //   const { pageContainer } = this.props;
-  //   const {
-  //     pageIdOnHackmd, hasDraftOnHackmd, isHackmdDraftUpdatingInRealtime,
-  //   } = pageContainer.state;
-
-  //   const isPageExistsOnHackmd = (pageIdOnHackmd != null);
-  //   return (isPageExistsOnHackmd && hasDraftOnHackmd) || isHackmdDraftUpdatingInRealtime;
-  // }
-
   const startToEdit = useCallback(async() => {
     const hackmdUri = getHackmdUri();
 
@@ -108,7 +103,7 @@ const PageEditorByHackmd = (props) => {
         throw new Error(res.error);
       }
 
-      await pageContainer.setState({ // ???????????????????
+      await pageContainer.setState({
         pageIdOnHackmd: res.pageIdOnHackmd,
         revisionIdHackmdSynced: res.revisionIdHackmdSynced,
       });
@@ -125,12 +120,12 @@ const PageEditorByHackmd = (props) => {
     setIsInitializing(false);
   }, [getHackmdUri, pageContainer, pageId]);
 
-  // /**
-  //  * Start to edit w/o any api request
-  //  */
-  // resumeToEdit() {
-  //   this.setState({ isInitialized: true });
-  // }
+  /**
+   * Start to edit w/o any api request
+   */
+  const resumeToEdit = () => {
+    setIsInitialized(true);
+  };
 
   const discardChanges = useCallback(async() => {
     const { pageId } = pageContainer.state;
@@ -212,147 +207,142 @@ const PageEditorByHackmd = (props) => {
     }
   }, [editorContainer, getHackmdUri, pageContainer.state.markdown, pageContainer.state.pageId]);
 
-  // penpalErrorOccuredHandler(error) {
-  //   const { pageContainer, t } = this.props;
-
-  //   pageContainer.showErrorToastr(error);
-
-  //   this.setState({
-  //     hasError: true,
-  //     errorMessage: t('hackmd.fail_to_connect'),
-  //     errorReason: error.toString(),
-  //   });
-  // }
-
-  // renderPreInitContent() {
-  //   const hackmdUri = this.getHackmdUri();
-  //   const { pageContainer, t } = this.props;
-  //   const {
-  //     revisionId, revisionIdHackmdSynced, remoteRevisionId, pageId,
-  //   } = pageContainer.state;
-  //   const isPageNotFound = pageId == null;
-
-  //   let content;
-
-  //   /*
-  //    * HackMD is not setup
-  //    */
-  //   if (hackmdUri == null) {
-  //     content = (
-  //       <div>
-  //         <p className="text-center hackmd-status-label"><i className="fa fa-file-text"></i> { t('hackmd.not_set_up')}</p>
-  //         {/* eslint-disable-next-line react/no-danger */}
-  //         <p dangerouslySetInnerHTML={{ __html: t('hackmd.need_to_associate_with_growi_to_use_hackmd_refer_to_this') }} />
-  //       </div>
-  //     );
-  //   }
-
-  //   /*
-  //   * used HackMD from NotFound Page
-  //   */
-  //   else if (isPageNotFound) {
-  //     content = (
-  //       <div className="text-center">
-  //         <p className="hackmd-status-label">
-  //           <i className="fa fa-file-text mr-2" />
-  //           { t('hackmd.used_for_not_found') }
-  //         </p>
-  //         {/* eslint-disable-next-line react/no-danger */}
-  //         <p dangerouslySetInnerHTML={{ __html: t('hackmd.need_to_make_page') }} />
-  //       </div>
-  //     );
-  //   }
-  //   /*
-  //    * Resume to edit or discard changes
-  //    */
-  //   else if (this.isResume) {
-  //     const isHackmdDocumentOutdated = revisionIdHackmdSynced !== remoteRevisionId;
-
-  //     content = (
-  //       <div>
-  //         <p className="text-center hackmd-status-label"><i className="fa fa-file-text"></i> HackMD is READY!</p>
-  //         <p className="text-center"><strong>{t('hackmd.unsaved_draft')}</strong></p>
-
-  //         { isHackmdDocumentOutdated && (
-  //           <div className="card border-warning">
-  //             <div className="card-header bg-warning"><i className="icon-fw icon-info"></i> {t('hackmd.draft_outdated')}</div>
-  //             <div className="card-body text-center">
-  //               {t('hackmd.based_on_revision')}&nbsp;
-  //               <a href={`?revision=${revisionIdHackmdSynced}`}><span className="badge badge-secondary">{revisionIdHackmdSynced.substr(-8)}</span></a>
-
-  //               <div className="text-center mt-3">
-  //                 <button
-  //                   className="btn btn-link btn-view-outdated-draft p-0"
-  //                   type="button"
-  //                   disabled={this.state.isInitializing}
-  //                   onClick={() => { return this.resumeToEdit() }}
-  //                 >
-  //                   {t('hackmd.view_outdated_draft')}
-  //                 </button>
-  //               </div>
-  //             </div>
-  //           </div>
-  //         ) }
-
-  //         { !isHackmdDocumentOutdated && (
-  //           <div className="text-center hackmd-resume-button-container mb-3">
-  //             <button
-  //               className="btn btn-success btn-lg waves-effect waves-light"
-  //               type="button"
-  //               disabled={this.state.isInitializing}
-  //               onClick={() => { return this.resumeToEdit() }}
-  //             >
-  //               <span className="btn-label"><i className="icon-fw icon-control-end"></i></span>
-  //               <span className="btn-text">{t('hackmd.resume_to_edit')}</span>
-  //             </button>
-  //           </div>
-  //         ) }
-
-  //         <div className="text-center hackmd-discard-button-container mb-3">
-  //           <button
-  //             className="btn btn-outline-secondary btn-lg waves-effect waves-light"
-  //             type="button"
-  //             onClick={() => { return this.discardChanges() }}
-  //           >
-  //             <span className="btn-label"><i className="icon-fw icon-control-start"></i></span>
-  //             <span className="btn-text">{t('hackmd.discard_changes')}</span>
-  //           </button>
-  //         </div>
-
-  //       </div>
-  //     );
-  //   }
-  //   /*
-  //    * Start to edit
-  //    */
-  //   else {
-  //     const isRevisionOutdated = revisionId !== remoteRevisionId;
-
-  //     content = (
-  //       <div>
-  //         <p className="text-muted text-center hackmd-status-label"><i className="fa fa-file-text"></i> HackMD is READY!</p>
-  //         <div className="text-center hackmd-start-button-container mb-3">
-  //           <button
-  //             className="btn btn-info btn-lg waves-effect waves-light"
-  //             type="button"
-  //             disabled={isRevisionOutdated || this.state.isInitializing}
-  //             onClick={() => { return this.startToEdit() }}
-  //           >
-  //             <span className="btn-label"><i className="icon-fw icon-paper-plane"></i></span>
-  //             {t('hackmd.start_to_edit')}
-  //           </button>
-  //         </div>
-  //         <p className="text-center">{t('hackmd.clone_page_content')}</p>
-  //       </div>
-  //     );
-  //   }
-
-  //   return (
-  //     <div className="hackmd-preinit d-flex justify-content-center align-items-center">
-  //       {content}
-  //     </div>
-  //   );
-  // }
+  const penpalErrorOccuredHandler = (error) => {
+    pageContainer.showErrorToastr(error);
+
+    setHasError(true);
+    setErrorMessage(t('hackmd.fail_to_connect'));
+    setErrorReason(error.toString());
+  };
+
+  const renderPreInitContent = () => {
+    const hackmdUri = getHackmdUri();
+    const {
+      revisionId, revisionIdHackmdSynced, remoteRevisionId, pageId,
+    } = pageContainer.state;
+    const isPageNotFound = pageId == null;
+
+    let content;
+
+    /*
+     * HackMD is not setup
+     */
+    if (hackmdUri == null) {
+      content = (
+        <div>
+          <p className="text-center hackmd-status-label"><i className="fa fa-file-text"></i> { t('hackmd.not_set_up')}</p>
+          {/* eslint-disable-next-line react/no-danger */}
+          <p dangerouslySetInnerHTML={{ __html: t('hackmd.need_to_associate_with_growi_to_use_hackmd_refer_to_this') }} />
+        </div>
+      );
+    }
+
+    /*
+    * used HackMD from NotFound Page
+    */
+    else if (isPageNotFound) {
+      content = (
+        <div className="text-center">
+          <p className="hackmd-status-label">
+            <i className="fa fa-file-text mr-2" />
+            { t('hackmd.used_for_not_found') }
+          </p>
+          {/* eslint-disable-next-line react/no-danger */}
+          <p dangerouslySetInnerHTML={{ __html: t('hackmd.need_to_make_page') }} />
+        </div>
+      );
+    }
+    /*
+     * Resume to edit or discard changes
+     */
+    else if (isResume()) {
+      const isHackmdDocumentOutdated = revisionIdHackmdSynced !== remoteRevisionId;
+
+      content = (
+        <div>
+          <p className="text-center hackmd-status-label"><i className="fa fa-file-text"></i> HackMD is READY!</p>
+          <p className="text-center"><strong>{t('hackmd.unsaved_draft')}</strong></p>
+
+          { isHackmdDocumentOutdated && (
+            <div className="card border-warning">
+              <div className="card-header bg-warning"><i className="icon-fw icon-info"></i> {t('hackmd.draft_outdated')}</div>
+              <div className="card-body text-center">
+                {t('hackmd.based_on_revision')}&nbsp;
+                <a href={`?revision=${revisionIdHackmdSynced}`}><span className="badge badge-secondary">{revisionIdHackmdSynced.substr(-8)}</span></a>
+
+                <div className="text-center mt-3">
+                  <button
+                    className="btn btn-link btn-view-outdated-draft p-0"
+                    type="button"
+                    disabled={isInitializing}
+                    onClick={() => { return resumeToEdit() }}
+                  >
+                    {t('hackmd.view_outdated_draft')}
+                  </button>
+                </div>
+              </div>
+            </div>
+          ) }
+
+          { !isHackmdDocumentOutdated && (
+            <div className="text-center hackmd-resume-button-container mb-3">
+              <button
+                className="btn btn-success btn-lg waves-effect waves-light"
+                type="button"
+                disabled={isInitializing}
+                onClick={() => { return resumeToEdit() }}
+              >
+                <span className="btn-label"><i className="icon-fw icon-control-end"></i></span>
+                <span className="btn-text">{t('hackmd.resume_to_edit')}</span>
+              </button>
+            </div>
+          ) }
+
+          <div className="text-center hackmd-discard-button-container mb-3">
+            <button
+              className="btn btn-outline-secondary btn-lg waves-effect waves-light"
+              type="button"
+              onClick={() => { return discardChanges() }}
+            >
+              <span className="btn-label"><i className="icon-fw icon-control-start"></i></span>
+              <span className="btn-text">{t('hackmd.discard_changes')}</span>
+            </button>
+          </div>
+
+        </div>
+      );
+    }
+    /*
+     * Start to edit
+     */
+    else {
+      const isRevisionOutdated = revisionId !== remoteRevisionId;
+
+      content = (
+        <div>
+          <p className="text-muted text-center hackmd-status-label"><i className="fa fa-file-text"></i> HackMD is READY!</p>
+          <div className="text-center hackmd-start-button-container mb-3">
+            <button
+              className="btn btn-info btn-lg waves-effect waves-light"
+              type="button"
+              disabled={isRevisionOutdated || isInitializing}
+              onClick={() => { return startToEdit() }}
+            >
+              <span className="btn-label"><i className="icon-fw icon-paper-plane"></i></span>
+              {t('hackmd.start_to_edit')}
+            </button>
+          </div>
+          <p className="text-center">{t('hackmd.clone_page_content')}</p>
+        </div>
+      );
+    }
+
+    return (
+      <div className="hackmd-preinit d-flex justify-content-center align-items-center">
+        {content}
+      </div>
+    );
+  };
 
   if (editorMode == null) {
     return null;
@@ -363,27 +353,26 @@ const PageEditorByHackmd = (props) => {
     markdown, pageIdOnHackmd,
   } = pageContainer.state;
 
-
   let content;
 
   if (isInitialized) {
     content = (
       <HackmdEditor
-        // ref={(c) => { this.hackmdEditor = c }}
+        ref={hackmdEditorRef}
         hackmdUri={hackmdUri}
         pageIdOnHackmd={pageIdOnHackmd}
-        // initializationMarkdown={this.isResume ? null : markdown}
+        initializationMarkdown={isResume() ? null : markdown}
         onChange={hackmdEditorChangeHandler}
         onSaveWithShortcut={(document) => {
           onSaveWithShortcut(document);
         }}
-        // onPenpalErrorOccured={this.penpalErrorOccuredHandler}
+        onPenpalErrorOccured={penpalErrorOccuredHandler}
       >
       </HackmdEditor>
     );
   }
   else {
-    // content = this.renderPreInitContent();
+    content = renderPreInitContent();
   }
 
 
@@ -412,18 +401,12 @@ const PageEditorByHackmd = (props) => {
 };
 
 PageEditorByHackmd.propTypes = {
-  t: PropTypes.func.isRequired, // i18next
-
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
   pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
   editorContainer: PropTypes.instanceOf(EditorContainer).isRequired,
 
   // TODO: remove this when omitting unstated is completed
-  editorMode: PropTypes.string.isRequired,
-  isSlackEnabled: PropTypes.bool.isRequired,
   pageTags: PropTypes.arrayOf(PropTypes.string),
-  slackChannels: PropTypes.string.isRequired,
-  grant: PropTypes.number.isRequired,
   grantGroupId: PropTypes.string,
   grantGroupName: PropTypes.string,
 };