Przeglądaj źródła

Merge pull request #1035 from weseek/fix/1030-unsaved-warning

Fix/1030 unsaved warning
Yuki Takei 6 lat temu
rodzic
commit
ca74241ec2

+ 7 - 2
src/client/js/components/Page.jsx

@@ -5,6 +5,7 @@ import loggerFactory from '@alias/logger';
 import { createSubscribedElement } from './UnstatedUtils';
 import AppContainer from '../services/AppContainer';
 import PageContainer from '../services/PageContainer';
+import EditorContainer from '../services/EditorContainer';
 
 import MarkdownTable from '../models/MarkdownTable';
 
@@ -45,7 +46,7 @@ class Page extends React.Component {
   }
 
   async saveHandlerForHandsontableModal(markdownTable) {
-    const { pageContainer } = this.props;
+    const { pageContainer, editorContainer } = this.props;
 
     const newMarkdown = mtu.replaceMarkdownTableInMarkdown(
       markdownTable,
@@ -55,6 +56,9 @@ class Page extends React.Component {
     );
 
     try {
+      // disable unsaved warning
+      editorContainer.disableUnsavedWarning();
+
       // eslint-disable-next-line no-unused-vars
       const { page, tags } = await pageContainer.save(newMarkdown);
       logger.debug('success to save');
@@ -88,13 +92,14 @@ class Page extends React.Component {
  * Wrapper component for using unstated
  */
 const PageWrapper = (props) => {
-  return createSubscribedElement(Page, props, [AppContainer, PageContainer]);
+  return createSubscribedElement(Page, props, [AppContainer, PageContainer, EditorContainer]);
 };
 
 
 Page.propTypes = {
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
   pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
+  editorContainer: PropTypes.instanceOf(EditorContainer).isRequired,
 };
 
 export default PageWrapper;

+ 4 - 17
src/client/js/components/PageEditor.jsx

@@ -42,7 +42,6 @@ class PageEditor extends React.Component {
     this.onPreviewScroll = this.onPreviewScroll.bind(this);
     this.saveDraft = this.saveDraft.bind(this);
     this.clearDraft = this.clearDraft.bind(this);
-    this.showUnsavedWarning = this.showUnsavedWarning.bind(this);
 
     // get renderer
     this.growiRenderer = this.props.appContainer.getRenderer('editor');
@@ -58,7 +57,6 @@ class PageEditor extends React.Component {
     this.scrollEditorByPreviewScrollWithThrottle = throttle(20, this.scrollEditorByPreviewScroll);
     this.renderPreviewWithDebounce = debounce(50, throttle(100, this.renderPreview));
     this.saveDraftWithDebounce = debounce(800, this.saveDraft);
-
   }
 
   componentWillMount() {
@@ -66,20 +64,6 @@ class PageEditor extends React.Component {
 
     // initial rendering
     this.renderPreview(this.state.markdown);
-
-    window.addEventListener('beforeunload', this.showUnsavedWarning);
-  }
-
-  componentWillUnmount() {
-    window.removeEventListener('beforeunload', this.showUnsavedWarning);
-  }
-
-  showUnsavedWarning(e) {
-    if (!this.props.appContainer.getIsDocSaved()) {
-      // display browser default message
-      e.returnValue = '';
-      return '';
-    }
   }
 
   getMarkdown() {
@@ -110,7 +94,6 @@ class PageEditor extends React.Component {
   onMarkdownChanged(value) {
     this.renderPreviewWithDebounce(value);
     this.saveDraftWithDebounce();
-    this.props.appContainer.setIsDocSaved(false);
   }
 
   /**
@@ -121,6 +104,9 @@ class PageEditor extends React.Component {
     const optionsToSave = editorContainer.getCurrentOptionsToSave();
 
     try {
+      // disable unsaved warning
+      editorContainer.disableUnsavedWarning();
+
       // eslint-disable-next-line no-unused-vars
       const { page, tags } = await pageContainer.save(this.state.markdown, optionsToSave);
       logger.debug('success to save');
@@ -290,6 +276,7 @@ class PageEditor extends React.Component {
     if (!pageContainer.state.revisionId) {
       editorContainer.saveDraft(pageContainer.state.path, this.state.markdown);
     }
+    editorContainer.enableUnsavedWarning();
   }
 
   clearDraft() {

+ 15 - 10
src/client/js/components/PageEditorByHackmd.jsx

@@ -129,6 +129,9 @@ class PageEditorByHackmd extends React.Component {
     const optionsToSave = editorContainer.getCurrentOptionsToSave();
 
     try {
+      // disable unsaved warning
+      editorContainer.disableUnsavedWarning();
+
       // eslint-disable-next-line no-unused-vars
       const { page, tags } = await pageContainer.save(markdown, optionsToSave);
       logger.debug('success to save');
@@ -147,9 +150,9 @@ class PageEditorByHackmd extends React.Component {
   /**
    * onChange event of HackmdEditor handler
    */
-  hackmdEditorChangeHandler(body) {
+  async hackmdEditorChangeHandler(body) {
     const hackmdUri = this.getHackmdUri();
-    const { pageContainer } = this.props;
+    const { pageContainer, editorContainer } = this.props;
 
     if (hackmdUri == null) {
       // do nothing
@@ -157,20 +160,22 @@ class PageEditorByHackmd extends React.Component {
     }
 
     // do nothing if contents are same
-    if (pageContainer.state.markdown === body) {
+    if (this.state.markdown === body) {
       return;
     }
 
+    // enable unsaved warning
+    editorContainer.enableUnsavedWarning();
+
     const params = {
       pageId: pageContainer.state.pageId,
     };
-    this.props.appContainer.apiPost('/hackmd.saveOnHackmd', params)
-      .then((res) => {
-        // do nothing
-      })
-      .catch((err) => {
-        // do nothing
-      });
+    try {
+      await this.props.appContainer.apiPost('/hackmd.saveOnHackmd', params);
+    }
+    catch (err) {
+      logger.error(err);
+    }
   }
 
   render() {

+ 6 - 0
src/client/js/components/SavePageControls.jsx

@@ -47,11 +47,17 @@ class SavePageControls extends React.Component {
 
   save() {
     const { pageContainer, editorContainer } = this.props;
+    // disable unsaved warning
+    editorContainer.disableUnsavedWarning();
+    // save
     pageContainer.saveAndReload(editorContainer.getCurrentOptionsToSave());
   }
 
   saveAndOverwriteScopesOfDescendants() {
     const { pageContainer, editorContainer } = this.props;
+    // disable unsaved warning
+    editorContainer.disableUnsavedWarning();
+    // save
     const optionsToSave = Object.assign(editorContainer.getCurrentOptionsToSave(), {
       overwriteScopesOfDescendants: true,
     });

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

@@ -183,14 +183,6 @@ export default class AppContainer extends Container {
     return renderer;
   }
 
-  setIsDocSaved(isSaved) {
-    this.isDocSaved = isSaved;
-  }
-
-  getIsDocSaved() {
-    return this.isDocSaved;
-  }
-
   getEmojiStrategy() {
     return emojiStrategy;
   }

+ 20 - 0
src/client/js/services/EditorContainer.js

@@ -37,6 +37,8 @@ export default class EditorContainer extends Container {
       previewOptions: {},
     };
 
+    this.isSetBeforeunloadEventHandler = false;
+
     this.initStateGrant();
     this.initDrafts();
 
@@ -146,6 +148,24 @@ export default class EditorContainer extends Container {
     return opt;
   }
 
+  showUnsavedWarning(e) {
+    // display browser default message
+    e.returnValue = '';
+    return '';
+  }
+
+  disableUnsavedWarning() {
+    window.removeEventListener('beforeunload', this.showUnsavedWarning);
+    this.isSetBeforeunloadEventHandler = false;
+  }
+
+  enableUnsavedWarning() {
+    if (!this.isSetBeforeunloadEventHandler) {
+      window.addEventListener('beforeunload', this.showUnsavedWarning);
+      this.isSetBeforeunloadEventHandler = true;
+    }
+  }
+
   clearDraft(path) {
     delete this.drafts[path];
     window.localStorage.setItem('drafts', JSON.stringify(this.drafts));

+ 0 - 3
src/client/js/services/PageContainer.js

@@ -117,9 +117,6 @@ export default class PageContainer extends Container {
    * @param {Array[Tag]} tags Array of Tag
    */
   updateStateAfterSave(page, tags) {
-    // mark that the document is not editing
-    this.appContainer.setIsDocSaved(true);
-
     const { editorMode } = this.appContainer.state;
 
     // update state of PageContainer