Jelajahi Sumber

WIP: refactor editing tags

Yuki Takei 6 tahun lalu
induk
melakukan
f3a9f32efa

+ 6 - 3
src/client/js/app.js

@@ -107,7 +107,7 @@ if (isEnabledPlugins) {
  * @param {object} page Page instance
  * @param {object} page Page instance
  */
  */
 const saveWithShortcutSuccessHandler = function(page) {
 const saveWithShortcutSuccessHandler = function(page) {
-  const editorMode = appContainer.getCrowiForJquery().getCurrentEditorMode();
+  const { editorMode } = appContainer.state;
 
 
   // show toastr
   // show toastr
   toastr.success(undefined, 'Saved successfully', {
   toastr.success(undefined, 'Saved successfully', {
@@ -148,6 +148,9 @@ const saveWithShortcutSuccessHandler = function(page) {
     }
     }
   }
   }
 
 
+  // update tags
+  tagContainer.init();
+
   // hidden input
   // hidden input
   $('input[name="revision_id"]').val(newState.revisionId);
   $('input[name="revision_id"]').val(newState.revisionId);
 };
 };
@@ -164,7 +167,7 @@ const errorHandler = function(error) {
 };
 };
 
 
 const saveWithShortcut = function(markdown) {
 const saveWithShortcut = function(markdown) {
-  const editorMode = appContainer.getCrowiForJquery().getCurrentEditorMode();
+  const { editorMode } = appContainer.state;
 
 
   const { pageId, path } = pageContainer.state;
   const { pageId, path } = pageContainer.state;
   let { revisionId } = pageContainer.state;
   let { revisionId } = pageContainer.state;
@@ -200,7 +203,7 @@ const saveWithSubmitButtonSuccessHandler = function() {
 };
 };
 
 
 const saveWithSubmitButton = function(submitOpts) {
 const saveWithSubmitButton = function(submitOpts) {
-  const editorMode = appContainer.getCrowiForJquery().getCurrentEditorMode();
+  const { editorMode } = appContainer.state;
   if (editorMode == null) {
   if (editorMode == null) {
     // do nothing
     // do nothing
     return;
     return;

+ 0 - 1
src/client/js/components/Page/TagEditor.jsx

@@ -24,7 +24,6 @@ export default class TagEditor extends React.Component {
   }
   }
 
 
   show(tags) {
   show(tags) {
-    // const isEditorMode = this.props.crowi.getCrowiForJquery().getCurrentEditorMode();
     this.setState({ tags, isOpenModal: true });
     this.setState({ tags, isOpenModal: true });
   }
   }
 
 

+ 39 - 18
src/client/js/components/Page/TagLabels.jsx

@@ -7,6 +7,7 @@ import * as toastr from 'toastr';
 import { createSubscribedElement } from '../UnstatedUtils';
 import { createSubscribedElement } from '../UnstatedUtils';
 import AppContainer from '../../services/AppContainer';
 import AppContainer from '../../services/AppContainer';
 import PageContainer from '../../services/PageContainer';
 import PageContainer from '../../services/PageContainer';
+import EditorContainer from '../../services/EditorContainer';
 
 
 import TagEditor from './TagEditor';
 import TagEditor from './TagEditor';
 
 
@@ -23,31 +24,49 @@ class TagLabels extends React.Component {
     this.tagsUpdatedHandler = this.tagsUpdatedHandler.bind(this);
     this.tagsUpdatedHandler = this.tagsUpdatedHandler.bind(this);
   }
   }
 
 
+  /**
+   * @return tags data
+   *   1. pageContainer.state.tags if editorMode is null
+   *   2. editorContainer.state.tags if editorMode is not null
+   */
+  getEditTargetData() {
+    const { editorMode } = this.props.appContainer.state;
+    return (editorMode == null)
+      ? this.props.pageContainer.state.tags
+      : this.props.editorContainer.state.tags;
+  }
+
   showEditor() {
   showEditor() {
-    const { tags } = this.props.pageContainer.state;
-    this.tagEditor.show(tags);
+    this.tagEditor.show(this.getEditTargetData());
   }
   }
 
 
   async tagsUpdatedHandler(tags) {
   async tagsUpdatedHandler(tags) {
-    // TODO
-    // if (currentEditorMode == null) {
-    try {
+    const { appContainer, editorContainer } = this.props;
+    const { editorMode } = appContainer.state;
+
+    // post api request and update tags
+    if (editorMode == null) {
       const { pageContainer } = this.props;
       const { pageContainer } = this.props;
-      const { pageId } = this.props.pageContainer.state;
-      await this.props.appContainer.apiPost('/tags.update', { pageId, tags });
 
 
-      // update pageContainer.state
-      pageContainer.setState({ tags });
+      try {
+        const { pageId } = pageContainer.state;
+        await appContainer.apiPost('/tags.update', { pageId, tags });
 
 
-      this.apiSuccessHandler();
+        // update pageContainer.state
+        pageContainer.setState({ tags });
+        editorContainer.setState({ tags });
+
+        this.apiSuccessHandler();
+      }
+      catch (err) {
+        this.apiErrorHandler(err);
+        return;
+      }
     }
     }
-    catch (err) {
-      this.apiErrorHandler(err);
-      return;
+    // only update tags in editorContainer
+    else {
+      editorContainer.setState({ tags });
     }
     }
-    // else {
-    // update editorContainer.tags
-    // }
   }
   }
 
 
   apiSuccessHandler() {
   apiSuccessHandler() {
@@ -76,7 +95,8 @@ class TagLabels extends React.Component {
   render() {
   render() {
     const { t } = this.props;
     const { t } = this.props;
     const { pageId } = this.props.pageContainer.state;
     const { pageId } = this.props.pageContainer.state;
-    const { tags } = this.props.pageContainer.state;
+
+    const tags = this.getEditTargetData();
 
 
     const tagElements = tags.map((tag) => {
     const tagElements = tags.map((tag) => {
       return (
       return (
@@ -118,7 +138,7 @@ class TagLabels extends React.Component {
  * Wrapper component for using unstated
  * Wrapper component for using unstated
  */
  */
 const TagLabelsWrapper = (props) => {
 const TagLabelsWrapper = (props) => {
-  return createSubscribedElement(TagLabels, props, [AppContainer, PageContainer]);
+  return createSubscribedElement(TagLabels, props, [AppContainer, PageContainer, EditorContainer]);
 };
 };
 
 
 
 
@@ -126,6 +146,7 @@ TagLabels.propTypes = {
   t: PropTypes.func.isRequired, // i18next
   t: PropTypes.func.isRequired, // i18next
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
   pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
   pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
+  editorContainer: PropTypes.instanceOf(EditorContainer).isRequired,
 };
 };
 
 
 export default withTranslation()(TagLabelsWrapper);
 export default withTranslation()(TagLabelsWrapper);

+ 13 - 17
src/client/js/legacy/crowi.js

@@ -252,23 +252,6 @@ Crowi.highlightSelectedSection = function(hash) {
   }
   }
 };
 };
 
 
-/**
- * Return editor mode string
- * @return 'builtin' or 'hackmd' or null (not editing)
- */
-Crowi.getCurrentEditorMode = function() {
-  const isEditing = $('body').hasClass('on-edit');
-  if (!isEditing) {
-    return null;
-  }
-
-  if ($('body').hasClass('builtin-editor')) {
-    return 'builtin';
-  }
-
-  return 'hackmd';
-};
-
 $(() => {
 $(() => {
   const appContainer = window.appContainer;
   const appContainer = window.appContainer;
   const websocketContainer = appContainer.getContainer('WebsocketContainer');
   const websocketContainer = appContainer.getContainer('WebsocketContainer');
@@ -631,7 +614,11 @@ $(() => {
   } // end if pageId
   } // end if pageId
 
 
   // tab changing handling
   // tab changing handling
+  $('a[href="#revision-body"]').on('show.bs.tab', () => {
+    appContainer.setState({ editorMode: null });
+  });
   $('a[href="#edit"]').on('show.bs.tab', () => {
   $('a[href="#edit"]').on('show.bs.tab', () => {
+    appContainer.setState({ editorMode: 'builtin' });
     $('body').addClass('on-edit');
     $('body').addClass('on-edit');
     $('body').addClass('builtin-editor');
     $('body').addClass('builtin-editor');
   });
   });
@@ -640,6 +627,7 @@ $(() => {
     $('body').removeClass('builtin-editor');
     $('body').removeClass('builtin-editor');
   });
   });
   $('a[href="#hackmd"]').on('show.bs.tab', () => {
   $('a[href="#hackmd"]').on('show.bs.tab', () => {
+    appContainer.setState({ editorMode: 'hackmd' });
     $('body').addClass('on-edit');
     $('body').addClass('on-edit');
     $('body').addClass('hackmd');
     $('body').addClass('hackmd');
   });
   });
@@ -695,9 +683,13 @@ $(() => {
 });
 });
 
 
 window.addEventListener('load', (e) => {
 window.addEventListener('load', (e) => {
+  const { appContainer } = window;
+
   // hash on page
   // hash on page
   if (location.hash) {
   if (location.hash) {
     if ((location.hash === '#edit' || location.hash === '#edit-form') && $('.tab-pane#edit').length > 0) {
     if ((location.hash === '#edit' || location.hash === '#edit-form') && $('.tab-pane#edit').length > 0) {
+      appContainer.setState({ editorMode: 'builtin' });
+
       $('a[data-toggle="tab"][href="#edit"]').tab('show');
       $('a[data-toggle="tab"][href="#edit"]').tab('show');
       $('body').addClass('on-edit');
       $('body').addClass('on-edit');
       $('body').addClass('builtin-editor');
       $('body').addClass('builtin-editor');
@@ -706,6 +698,8 @@ window.addEventListener('load', (e) => {
       Crowi.setCaretLineAndFocusToEditor();
       Crowi.setCaretLineAndFocusToEditor();
     }
     }
     else if (location.hash === '#hackmd' && $('.tab-pane#hackmd').length > 0) {
     else if (location.hash === '#hackmd' && $('.tab-pane#hackmd').length > 0) {
+      appContainer.setState({ editorMode: 'hackmd' });
+
       $('a[data-toggle="tab"][href="#hackmd"]').tab('show');
       $('a[data-toggle="tab"][href="#hackmd"]').tab('show');
       $('body').addClass('on-edit');
       $('body').addClass('on-edit');
       $('body').addClass('hackmd');
       $('body').addClass('hackmd');
@@ -759,6 +753,8 @@ window.addEventListener('load', (e) => {
 });
 });
 
 
 window.addEventListener('hashchange', (e) => {
 window.addEventListener('hashchange', (e) => {
+  const { appContainer } = window;
+
   Crowi.unhighlightSelectedSection(Crowi.findHashFromUrl(e.oldURL));
   Crowi.unhighlightSelectedSection(Crowi.findHashFromUrl(e.oldURL));
   Crowi.highlightSelectedSection(Crowi.findHashFromUrl(e.newURL));
   Crowi.highlightSelectedSection(Crowi.findHashFromUrl(e.newURL));
   Crowi.modifyScrollTop();
   Crowi.modifyScrollTop();

+ 4 - 0
src/client/js/services/AppContainer.js

@@ -20,6 +20,10 @@ export default class AppContainer extends Container {
   constructor() {
   constructor() {
     super();
     super();
 
 
+    this.state = {
+      editorMode: null,
+    };
+
     const body = document.querySelector('body');
     const body = document.querySelector('body');
 
 
     this.me = body.dataset.currentUsername;
     this.me = body.dataset.currentUsername;