import { memo } from "react"; import { IMAGE_URL_REG, LINK_REG, MEMO_LINK_REG, TAG_REG } from "../helpers/consts"; import { encodeHtml, parseMarkedToHtml, parseRawTextToHtml } from "../helpers/marked"; import utils from "../helpers/utils"; import useToggle from "../hooks/useToggle"; import { globalStateService, memoService } from "../services"; import Only from "./common/OnlyWhen"; import Image from "./Image"; import showMemoCardDialog from "./MemoCardDialog"; import showShareMemoImageDialog from "./ShareMemoImageDialog"; import toastHelper from "./Toast"; import "../less/memo.less"; interface Props { memo: Model.Memo; } const Memo: React.FC = (props: Props) => { const { memo: propsMemo } = props; const memo: FormattedMemo = { ...propsMemo, createdAtStr: utils.getDateTimeString(propsMemo.createdAt), }; const [showConfirmDeleteBtn, toggleConfirmDeleteBtn] = useToggle(false); const imageUrls = Array.from(memo.content.match(IMAGE_URL_REG) ?? []); const handleShowMemoStoryDialog = () => { showMemoCardDialog(memo); }; const handleMarkMemoClick = () => { globalStateService.setMarkMemoId(memo.id); }; const handleEditMemoClick = () => { globalStateService.setEditMemoId(memo.id); }; const handleDeleteMemoClick = async () => { if (showConfirmDeleteBtn) { try { await memoService.hideMemoById(memo.id); } catch (error: any) { toastHelper.error(error.message); } if (globalStateService.getState().editMemoId === memo.id) { globalStateService.setEditMemoId(""); } } else { toggleConfirmDeleteBtn(); } }; const handleMouseLeaveMemoWrapper = () => { if (showConfirmDeleteBtn) { toggleConfirmDeleteBtn(false); } }; const handleGenMemoImageBtnClick = () => { showShareMemoImageDialog(memo); }; const handleMemoContentClick = async (e: React.MouseEvent) => { const targetEl = e.target as HTMLElement; if (targetEl.className === "memo-link-text") { const memoId = targetEl.dataset?.value; const memoTemp = memoService.getMemoById(memoId ?? ""); if (memoTemp) { showMemoCardDialog(memoTemp); } else { toastHelper.error("MEMO Not Found"); targetEl.classList.remove("memo-link-text"); } } else if (targetEl.className === "todo-block") { // do nth } }; return (
{memo.createdAtStr}
查看详情 Mark 分享 编辑 {showConfirmDeleteBtn ? "确定删除!" : "删除"}
0}>
{imageUrls.map((imgUrl, idx) => ( ))}
); }; export function formatMemoContent(content: string) { content = encodeHtml(content); content = parseRawTextToHtml(content) .split("
") .map((t) => { return `

${t !== "" ? t : "
"}

`; }) .join(""); const { shouldUseMarkdownParser, shouldSplitMemoWord, shouldHideImageUrl } = globalStateService.getState(); if (shouldUseMarkdownParser) { content = parseMarkedToHtml(content); } if (shouldHideImageUrl) { content = content.replace(IMAGE_URL_REG, ""); } // 中英文之间加空格 if (shouldSplitMemoWord) { content = content .replace(/([\u4e00-\u9fa5])([A-Za-z0-9?.,;[\]]+)/g, "$1 $2") .replace(/([A-Za-z0-9?.,;[\]]+)([\u4e00-\u9fa5])/g, "$1 $2"); } content = content .replace(TAG_REG, "#$1") .replace(LINK_REG, "$1") .replace(MEMO_LINK_REG, "$1"); const tempDivContainer = document.createElement("div"); tempDivContainer.innerHTML = content; for (let i = 0; i < tempDivContainer.children.length; i++) { const c = tempDivContainer.children[i]; if (c.tagName === "P" && c.textContent === "" && c.firstElementChild?.tagName !== "BR") { c.remove(); i--; continue; } } return tempDivContainer.innerHTML; } export default memo(Memo);