import React, { useCallback, useMemo } from 'react'; import { useTranslation } from 'next-i18next'; import { useHasDraftOnHackmd, useIsHackmdDraftUpdatingInRealtime, useRemoteRevisionId, useRevisionIdHackmdSynced, } from '~/stores/hackmd'; import { useSWRxCurrentPage } from '~/stores/page'; type AlertComponentContents = { additionalClasses: string[], label: JSX.Element, btn: JSX.Element } export const PageStatusAlert = (): JSX.Element => { const { t } = useTranslation(); const { data: isHackmdDraftUpdatingInRealtime } = useIsHackmdDraftUpdatingInRealtime(); const { data: hasDraftOnHackmd } = useHasDraftOnHackmd(); const { data: revisionIdHackmdSynced } = useRevisionIdHackmdSynced(); const { data: remoteRevisionId } = useRemoteRevisionId(); const { data: pageData } = useSWRxCurrentPage(); const revision = pageData?.revision; const refreshPage = useCallback(() => { window.location.reload(); }, []); const onClickResolveConflict = useCallback(() => { // this.props.pageContainer.setState({ // isConflictDiffModalOpen: true, // }); }, []); const getContentsForSomeoneEditingAlert = useCallback((): AlertComponentContents => { return { additionalClasses: ['bg-success', 'd-hackmd-none'], label: <> {t('hackmd.someone_editing')} , btn: Open HackMD Editor , }; }, [t]); const getContentsForDraftExistsAlert = useCallback((): AlertComponentContents => { return { additionalClasses: ['bg-success', 'd-hackmd-none'], label: <> {t('hackmd.this_page_has_draft')} , btn: Open HackMD Editor , }; }, [t]); const getContentsForUpdatedAlert = useCallback((): AlertComponentContents => { // const pageEditor = appContainer.getComponentInstance('PageEditor'); const isConflictOnEdit = false; // if (pageEditor != null) { // const markdownOnEdit = pageEditor.getMarkdown(); // isConflictOnEdit = markdownOnEdit !== pageContainer.state.markdown; // } // TODO: re-impl with Next.js way // const usernameComponentToString = ReactDOMServer.renderToString(); // const label1 = isConflictOnEdit // ? t('modal_resolve_conflict.file_conflicting_with_newer_remote') // // eslint-disable-next-line react/no-danger // : ; const label1 = '(TBD -- 2022.09.13)'; return { additionalClasses: ['bg-warning'], label: <> {label1} , btn: <> { isConflictOnEdit && ( )} , }; }, [t, onClickResolveConflict, refreshPage]); const alertComponentContents = useMemo(() => { const isRevisionOutdated = revision?._id !== remoteRevisionId; const isHackmdDocumentOutdated = revisionIdHackmdSynced !== remoteRevisionId; // when remote revision is newer than both if (isHackmdDocumentOutdated && isRevisionOutdated) { return getContentsForUpdatedAlert(); } // when someone editing with HackMD if (isHackmdDraftUpdatingInRealtime) { return getContentsForSomeoneEditingAlert(); } // when the draft of HackMD is newest if (hasDraftOnHackmd) { return getContentsForDraftExistsAlert(); } return null; }, [ revision?._id, remoteRevisionId, revisionIdHackmdSynced, isHackmdDraftUpdatingInRealtime, hasDraftOnHackmd, getContentsForUpdatedAlert, getContentsForSomeoneEditingAlert, getContentsForDraftExistsAlert, ]); if (alertComponentContents == null) { return <> } const { additionalClasses, label, btn } = alertComponentContents; return (

{label}

{btn}

); };