import React, { useCallback, useMemo } from 'react'; import { useTranslation } from 'next-i18next'; import * as ReactDOMServer from 'react-dom/server'; import { useIsGuestUser, useIsReadOnlyUser } from '~/stores/context'; import { useEditingMarkdown, useIsConflict } from '~/stores/editor'; import { useConflictDiffModal } from '~/stores/modal'; import { useSWRMUTxCurrentPage, useSWRxCurrentPage } from '~/stores/page'; import { useRemoteRevisionId, useRemoteRevisionLastUpdateUser } from '~/stores/remote-latest-page'; 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(); // store remote latest page data const { data: remoteRevisionId } = useRemoteRevisionId(); const { data: remoteRevisionLastUpdateUser } = useRemoteRevisionLastUpdateUser(); const { data: pageData } = useSWRxCurrentPage(); const { trigger: mutatePageData } = useSWRMUTxCurrentPage(); const revision = pageData?.revision; const refreshPage = useCallback(async() => { const updatedPageData = await mutatePageData(); mutateEditingMarkdown(updatedPageData?.revision.body); }, [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: // <> // // {t('hackmd.someone_editing')} // , // btn: // // // Open HackMD Editor // , // }; // }, [t]); const getContentsForUpdatedAlert = useCallback((): AlertComponentContents => { const usernameComponentToString = ReactDOMServer.renderToString(); const label1 = isConflict ? t('modal_resolve_conflict.file_conflicting_with_newer_remote') // eslint-disable-next-line react/no-danger : ; return { additionalClasses: ['bg-warning text-dark'], label: <> {label1} , btn: <> { isConflict && ( )} , }; }, [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]); if (!!isGuestUser || !!isReadOnlyUser || alertComponentContents == null) { return <> } const { additionalClasses, label, btn } = alertComponentContents; return (

{label}

{btn}

); };