import { useState, useEffect, useCallback } from "react"; import { editorStateService, memoService, userService } from "../services"; import { IMAGE_URL_REG, MEMO_LINK_REG, UNKNOWN_ID } from "../helpers/consts"; import * as utils from "../helpers/utils"; import { parseHtmlToRawText } from "../helpers/marked"; import Only from "./common/OnlyWhen"; import toastHelper from "./Toast"; import { showDialog } from "./Dialog"; import Image from "./Image"; import { formatMemoContent } from "./Memo"; import "../less/memo-card-dialog.less"; import Selector from "./common/Selector"; interface LinkedMemo extends Memo { createdAtStr: string; dateStr: string; } interface Props extends DialogProps { memo: Memo; } const MemoCardDialog: React.FC = (props: Props) => { const [memo, setMemo] = useState({ ...props.memo, }); const [linkMemos, setLinkMemos] = useState([]); const [linkedMemos, setLinkedMemos] = useState([]); const imageUrls = Array.from(memo.content.match(IMAGE_URL_REG) ?? []).map((s) => s.replace(IMAGE_URL_REG, "$1")); const visibilityList = [ { text: "PUBLIC", value: "PUBLIC" }, { text: "PROTECTED", value: "PROTECTED" }, { text: "PRIVATE", value: "PRIVATE" }, ]; useEffect(() => { const fetchLinkedMemos = async () => { try { const linkMemos: LinkedMemo[] = []; const matchedArr = [...memo.content.matchAll(MEMO_LINK_REG)]; for (const matchRes of matchedArr) { if (matchRes && matchRes.length === 3) { const id = Number(matchRes[2]); if (id === memo.id) { continue; } const memoTemp = memoService.getMemoById(id); if (memoTemp) { linkMemos.push({ ...memoTemp, createdAtStr: utils.getDateTimeString(memoTemp.createdTs), dateStr: utils.getDateString(memoTemp.createdTs), }); } } } setLinkMemos([...linkMemos]); const linkedMemos = await memoService.getLinkedMemos(memo.id); setLinkedMemos( linkedMemos .filter((m) => m.rowStatus === "NORMAL" && m.id !== memo.id) .sort((a, b) => utils.getTimeStampByDate(b.createdTs) - utils.getTimeStampByDate(a.createdTs)) .map((m) => ({ ...m, createdAtStr: utils.getDateTimeString(m.createdTs), dateStr: utils.getDateString(m.createdTs), })) ); } catch (error) { // do nth } }; fetchLinkedMemos(); }, [memo.id]); const handleMemoContentClick = useCallback(async (e: React.MouseEvent) => { const targetEl = e.target as HTMLElement; if (targetEl.className === "memo-link-text") { const nextMemoId = targetEl.dataset?.value; const memoTemp = memoService.getMemoById(Number(nextMemoId) ?? UNKNOWN_ID); if (memoTemp) { const nextMemo = { ...memoTemp, createdAtStr: utils.getDateTimeString(memoTemp.createdTs), }; setLinkMemos([]); setLinkedMemos([]); setMemo(nextMemo); } else { toastHelper.error("MEMO Not Found"); targetEl.classList.remove("memo-link-text"); } } }, []); const handleLinkedMemoClick = useCallback((memo: Memo) => { setLinkMemos([]); setLinkedMemos([]); setMemo(memo); }, []); const handleEditMemoBtnClick = () => { props.destroy(); editorStateService.setEditMemoWithId(memo.id); }; const handleVisibilitySelectorChange = async (visibility: Visibility) => { if (memo.visibility === visibility) { return; } await memoService.patchMemo({ id: memo.id, visibility: visibility, }); setMemo({ ...memo, visibility: visibility, }); }; return ( <>
handleVisibilitySelectorChange(value as Visibility)} />

{utils.getDateTimeString(memo.createdTs)}

<> /
0}>
{imageUrls.map((imgUrl, idx) => ( ))}
{linkMemos.map((_, idx) => { if (idx < 4) { return (
); } else { return null; } })}
{linkMemos.length > 0 ? (

{linkMemos.length} related MEMO

{linkMemos.map((memo, index) => { const rawtext = parseHtmlToRawText(formatMemoContent(memo.content)).replaceAll("\n", " "); return (
handleLinkedMemoClick(memo)}> {memo.dateStr} {rawtext}
); })}
) : null} {linkedMemos.length > 0 ? (

{linkedMemos.length} linked MEMO

{linkedMemos.map((memo, index) => { const rawtext = parseHtmlToRawText(formatMemoContent(memo.content)).replaceAll("\n", " "); return (
handleLinkedMemoClick(memo)}> {memo.dateStr} {rawtext}
); })}
) : null} ); }; export default function showMemoCardDialog(memo: Memo): void { showDialog( { className: "memo-card-dialog", }, MemoCardDialog, { memo } ); }