yohei0125 4 лет назад
Родитель
Сommit
8a1a029d72

+ 2 - 1
packages/app/src/client/services/ContextExtractor.tsx

@@ -6,7 +6,7 @@ import {
   useIsDeleted, useIsNotCreatable, useIsTrashPage, useIsUserPage, useLastUpdateUsername,
   useCurrentPageId, usePageIdOnHackmd, usePageUser, useCurrentPagePath, useRevisionCreatedAt, useRevisionId, useRevisionIdHackmdSynced,
   useShareLinkId, useShareLinksNumber, useTemplateTagData, useCurrentUpdatedAt, useCreator, useRevisionAuthor, useCurrentUser, useTargetAndAncestors,
-  useSlackChannels, useNotFoundTargetPathOrId, useIsSearchPage, useIsForbidden, useIsIdenticalPath,
+  useSlackChannels, useNotFoundTargetPathOrId, useIsSearchPage, useIsForbidden, useIsIdenticalPath, useIsRevisionBodyRendered,
 } from '../../stores/context';
 import {
   useIsDeviceSmallerThanMd, useIsDeviceSmallerThanLg,
@@ -139,6 +139,7 @@ const ContextExtractorOnce: FC = () => {
 
   // SearchResult
   useIsDeviceSmallerThanLg();
+  useIsRevisionBodyRendered(false);
 
   return null;
 };

+ 35 - 2
packages/app/src/components/Page/RevisionBody.jsx

@@ -2,8 +2,9 @@ import React from 'react';
 import PropTypes from 'prop-types';
 
 import { debounce } from 'throttle-debounce';
+import { useIsRevisionBodyRendered } from '~/stores/context';
 
-export default class RevisionBody extends React.PureComponent {
+class RevisionBody extends React.PureComponent {
 
   constructor(props) {
     super(props);
@@ -24,6 +25,17 @@ export default class RevisionBody extends React.PureComponent {
     if (MathJax != null && this.props.isMathJaxEnabled && this.props.renderMathJaxInRealtime) {
       this.renderMathJaxWithDebounce();
     }
+    console.log('YOOOOOOOOOOOOOOOOOOOOOOOO');
+    console.log(this.props.isRevisionBodyRendered);
+    if (this.props.onRevisionBodyRendered && !this.props.isRevisionBodyRendered) {
+      this.props.onRevisionBodyRendered();
+    }
+  }
+
+  componentWillUnmount() {
+    if (this.props.onRivisionBodyWillUnmount && this.props.isRevisionBodyRendered) {
+      this.props.onRivisionBodyWillUnmount();
+    }
   }
 
   componentWillReceiveProps(nextProps) {
@@ -64,7 +76,6 @@ export default class RevisionBody extends React.PureComponent {
             this.props.inputRef(elm);
           }
         }}
-        id="revision-body"
         className={`wiki ${additionalClassName}`}
         // eslint-disable-next-line react/no-danger
         dangerouslySetInnerHTML={this.generateInnerHtml(this.props.html)}
@@ -81,4 +92,26 @@ RevisionBody.propTypes = {
   renderMathJaxOnInit: PropTypes.bool,
   renderMathJaxInRealtime: PropTypes.bool,
   additionalClassName: PropTypes.string,
+  onRevisionBodyRendered: PropTypes.func,
+  onRivisionBodyWillUnmount: PropTypes.func,
+  isRevisionBodyRendered: PropTypes.bool,
+};
+
+export default (props) => {
+  const { mutate, data: isRevisionBodyRendered } = useIsRevisionBodyRendered();
+  const mutateOnComponentDidUpdate = () => {
+    mutate(true);
+  };
+  const mutateOnComponentWillUnmount = () => {
+    mutate(false);
+  };
+  return (
+    <RevisionBody
+      {...props}
+      onRevisionBodyRendered={mutateOnComponentDidUpdate}
+      onRivisionBodyWillUnmount={mutateOnComponentWillUnmount}
+      isRevisionBodyRendered={isRevisionBodyRendered}
+    >
+    </RevisionBody>
+  );
 };

+ 0 - 16
packages/app/src/components/Page/RevisionLoader.jsx

@@ -36,20 +36,6 @@ class LegacyRevisionLoader extends React.Component {
     }
   }
 
-  componentDidUpdate() {
-    console.log('state.isLoaded', this.state.isLoaded);
-    console.log('state.isLoading', this.state.isLoading);
-
-    // after loading
-    if (this.state.isLoaded) {
-      const wiki = document.getElementById('revision-body');
-      console.log(wiki);
-      const hightlightedElement = wiki.querySelector('.highlighted-keyword');
-      console.log(hightlightedElement);
-      this.props.onRevisionBodyRendered(hightlightedElement);
-    }
-  }
-
   async loadData() {
     if (!this.state.isLoaded && !this.state.isLoading) {
       this.setState({ isLoading: true });
@@ -121,7 +107,6 @@ class LegacyRevisionLoader extends React.Component {
         growiRenderer={this.props.growiRenderer}
         markdown={markdown}
         highlightKeywords={this.props.highlightKeywords}
-        onRevisionBodyRendered={this.props.onRevisionBodyRendered}
       />
     );
   }
@@ -141,7 +126,6 @@ LegacyRevisionLoader.propTypes = {
   revisionId: PropTypes.string.isRequired,
   lazy: PropTypes.bool,
   onRevisionLoaded: PropTypes.func,
-  onRevisionBodyRendered: PropTypes.func,
   highlightKeywords: PropTypes.string,
 };
 

+ 12 - 9
packages/app/src/components/SearchPage/SearchResultContent.tsx

@@ -1,5 +1,5 @@
 import React, {
-  FC, useRef, useState, useEffect, useCallback,
+  FC, useRef, useCallback, useEffect,
 } from 'react';
 
 import { IPageWithMeta } from '~/interfaces/page';
@@ -11,6 +11,8 @@ import { smoothScrollIntoView } from '~/client/util/smooth-scroll';
 import { GrowiSubNavigation } from '../Navbar/GrowiSubNavigation';
 import { SubNavButtons } from '../Navbar/SubNavButtons';
 
+import { useIsRevisionBodyRendered } from '../../stores/context';
+
 const SCROLL_OFFSET_TOP = 175; // approximate height of (navigation + subnavigation)
 
 type Props ={
@@ -23,15 +25,17 @@ type Props ={
 const SearchResultContent: FC<Props> = (props: Props) => {
   const contentRef = useRef(null);
 
+  const { data: isRevisionBodyRendered } = useIsRevisionBodyRendered();
 
-  const scrollTo = (element) => {
-    console.log('scrollTo emitted');
-
-    const searchResultPageContent = contentRef.current as HTMLElement | null;
-    if (searchResultPageContent != null && element != null) {
-      smoothScrollIntoView(element, SCROLL_OFFSET_TOP, searchResultPageContent);
+  useEffect(() => {
+    if (isRevisionBodyRendered && contentRef.current != null) {
+      const scrollTargetElement = contentRef.current as HTMLElement;
+      const highlightedKeyword = scrollTargetElement.querySelector('.highlighted-keyword') as HTMLElement;
+      if (highlightedKeyword) {
+        smoothScrollIntoView(highlightedKeyword, SCROLL_OFFSET_TOP, scrollTargetElement);
+      }
     }
-  };
+  }, [isRevisionBodyRendered]);
 
   const page = props.focusedSearchResultData?.pageData;
 
@@ -69,7 +73,6 @@ const SearchResultContent: FC<Props> = (props: Props) => {
           pagePath={page.path}
           revisionId={page.revision}
           highlightKeywords={props.searchingKeyword}
-          onRevisionBodyRendered={scrollTo}
         />
       </div>
     </div>

+ 4 - 0
packages/app/src/stores/context.tsx

@@ -131,6 +131,10 @@ export const useNotFoundTargetPathOrId = (initialData?: Nullable<NotFoundTargetP
   return useStaticSWR<Nullable<NotFoundTargetPathOrId>, Error>('notFoundTargetPathOrId', initialData);
 };
 
+export const useIsRevisionBodyRendered = (initialData?: boolean): SWRResponse<Nullable<boolean>, Error> => {
+  return useStaticSWR<Nullable<boolean>, Error>('isRevisionBodyRendered', initialData);
+};
+
 
 /** **********************************************************
  *                     Computed contexts