Shun Miyazawa 2 лет назад
Родитель
Сommit
f0e84e5353
1 измененных файлов с 59 добавлено и 88 удалено
  1. 59 88
      apps/app/src/components/PageStatusAlert.tsx

+ 59 - 88
apps/app/src/components/PageStatusAlert.tsx

@@ -3,30 +3,24 @@ import React, { useCallback, useMemo } from 'react';
 import { useTranslation } from 'next-i18next';
 import * as ReactDOMServer from 'react-dom/server';
 
+import { usePageStatusAlert } from '~/client/services/update-page/conflict';
 import { useIsGuestUser, useIsReadOnlyUser } from '~/stores/context';
-import { useEditingMarkdown, useIsConflict } from '~/stores/editor';
-import { useConflictDiffModal } from '~/stores/modal';
+import { useEditingMarkdown } from '~/stores/editor';
 import { useSWRMUTxCurrentPage, useSWRxCurrentPage } from '~/stores/page';
 import { useRemoteRevisionId, useRemoteRevisionLastUpdateUser } from '~/stores/remote-latest-page';
+import { EditorMode, useEditorMode } from '~/stores/ui';
 
 import { Username } from './User/Username';
 
 import styles from './PageStatusAlert.module.scss';
 
-type AlertComponentContents = {
-  additionalClasses: string[],
-  label: JSX.Element,
-  btn: JSX.Element
-}
-
 export const PageStatusAlert = (): JSX.Element => {
-
   const { t } = useTranslation();
-  const { data: isConflict } = useIsConflict();
   const { mutate: mutateEditingMarkdown } = useEditingMarkdown();
-  const { open: openConflictDiffModal } = useConflictDiffModal();
   const { data: isGuestUser } = useIsGuestUser();
   const { data: isReadOnlyUser } = useIsReadOnlyUser();
+  const { data: pageStatusAlertData } = usePageStatusAlert();
+  const { data: editorMode } = useEditorMode();
 
   // store remote latest page data
   const { data: remoteRevisionId } = useRemoteRevisionId();
@@ -42,92 +36,69 @@ export const PageStatusAlert = (): JSX.Element => {
   }, [mutateEditingMarkdown, mutatePageData]);
 
   const onClickResolveConflict = useCallback(() => {
-    // openConflictDiffModal();
-  }, [openConflictDiffModal]);
-
-  // TODO: re-impl for builtin editor
-  //
-  // const getContentsForSomeoneEditingAlert = useCallback((): AlertComponentContents => {
-  //   return {
-  //     additionalClasses: ['bg-success', 'd-hackmd-none'],
-  //     label:
-  // <>
-  //   <span className="material-symbols-outlined">person</span>
-  //   {t('hackmd.someone_editing')}
-  // </>,
-  //     btn:
-  // <a href="#hackmd" key="btnOpenHackmdSomeoneEditing" className="btn btn-outline-white">
-  //   <span class="material-symbols-outlined">description</span>
-  //   Open HackMD Editor
-  // </a>,
-  //   };
-  // }, [t]);
-
-  const getContentsForUpdatedAlert = useCallback((): AlertComponentContents => {
+    pageStatusAlertData?.onConflict?.();
+  }, [pageStatusAlertData]);
 
+  const alertContentsForView = useMemo(() => {
     const usernameComponentToString = ReactDOMServer.renderToString(<Username user={remoteRevisionLastUpdateUser} />);
+    return (
+      <>
+        <p className="card-text grw-card-label-container">
+          {/* eslint-disable-next-line react/no-danger */}
+          <span dangerouslySetInnerHTML={{ __html: `${usernameComponentToString} ${t('edited this page')}` }} />
+        </p>
+        <p className="card-text grw-card-btn-container">
+          <button
+            type="button"
+            onClick={() => refreshPage()}
+            className="btn btn-outline-white me-4"
+          >
+            <span className="material-symbols-outlined">refresh</span>
+            {t('Load latest')}
+          </button>
+        </p>
+      </>
+    );
+  }, [refreshPage, remoteRevisionLastUpdateUser, t]);
 
-    const label1 = isConflict
-      ? t('modal_resolve_conflict.file_conflicting_with_newer_remote')
-      // eslint-disable-next-line react/no-danger
-      : <span dangerouslySetInnerHTML={{ __html: `${usernameComponentToString} ${t('edited this page')}` }} />;
-
-    return {
-      additionalClasses: ['bg-warning text-dark'],
-      label:
-  <>
-    <span className="material-symbols-outlined">lightbulb</span>
-    {label1}
-  </>,
-      btn:
-  <>
-    <button type="button" onClick={() => refreshPage()} className="btn btn-outline-white me-4">
-      <span className="material-symbols-outlined">refresh</span>
-      {t('Load latest')}
-    </button>
-    { isConflict && (
-      <button
-        type="button"
-        onClick={onClickResolveConflict}
-        className="btn btn-outline-white"
-      >
-        <span className="material-symbols-outlined">description</span>
-        {t('modal_resolve_conflict.resolve_conflict')}
-      </button>
-    )}
-  </>,
-    };
-  }, [remoteRevisionLastUpdateUser, isConflict, t, onClickResolveConflict, refreshPage]);
-
-  const alertComponentContents = useMemo(() => {
-    const isRevisionOutdated = revision?._id !== remoteRevisionId;
-
-    // 'revision?._id' and 'remoteRevisionId' are can not be undefined
-    if (revision?._id == null || remoteRevisionId == null) { return }
-
-    // when remote revision is newer than both
-    if (isRevisionOutdated) {
-      return getContentsForUpdatedAlert();
-    }
-
-    return null;
-  }, [revision?._id, remoteRevisionId, getContentsForUpdatedAlert]);
+  const alertContentsForEditor = useMemo(() => {
+    return (
+      <>
+        <p className="card-text grw-card-label-container">
+          {t('modal_resolve_conflict.file_conflicting_with_newer_remote')}
+        </p>
+        <p className="card-text grw-card-btn-container">
+          <button
+            type="button"
+            onClick={onClickResolveConflict}
+            className="btn btn-outline-white"
+          >
+            <span className="material-symbols-outlined">description</span>
+            {t('modal_resolve_conflict.resolve_conflict')}
+          </button>
+        </p>
+      </>
+    );
+  }, [onClickResolveConflict, t]);
 
-  if (!!isGuestUser || !!isReadOnlyUser || alertComponentContents == null) { return <></> }
+  const isRevisionOutdated = (revision?._id != null || remoteRevisionId != null) && revision?._id !== remoteRevisionId;
+  if (!!isGuestUser || !!isReadOnlyUser || !isRevisionOutdated) {
+    return <></>;
+  }
 
-  const { additionalClasses, label, btn } = alertComponentContents;
+  const hasConflictHandler = pageStatusAlertData?.onConflict != null;
+  if (!hasConflictHandler && editorMode === EditorMode.Editor) {
+    return <></>;
+  }
 
   return (
-    <div className={`${styles['grw-page-status-alert']} card text-white fixed-bottom animated fadeInUp faster ${additionalClasses.join(' ')}`}>
+    <div className={`${styles['grw-page-status-alert']} card text-white fixed-bottom animated fadeInUp faster bg-warning text-dark`}>
       <div className="card-body">
-        <p className="card-text grw-card-label-container">
-          {label}
-        </p>
-        <p className="card-text grw-card-btn-container">
-          {btn}
-        </p>
+        { editorMode === EditorMode.View
+          ? alertContentsForView
+          : alertContentsForEditor
+        }
       </div>
     </div>
   );
-
 };