mirror of
https://github.com/usememos/memos.git
synced 2024-12-19 00:51:30 +03:00
chore: remove memo card dialog (#475)
This commit is contained in:
parent
67195859dc
commit
de2eff474c
@ -11,7 +11,6 @@ import Icon from "./Icon";
|
||||
import toastHelper from "./Toast";
|
||||
import MemoContent from "./MemoContent";
|
||||
import MemoResources from "./MemoResources";
|
||||
import showMemoCardDialog from "./MemoCardDialog";
|
||||
import showShareMemoImageDialog from "./ShareMemoImageDialog";
|
||||
import showPreviewImageDialog from "./PreviewImageDialog";
|
||||
import "../less/memo.less";
|
||||
@ -51,14 +50,6 @@ const Memo: React.FC<Props> = (props: Props) => {
|
||||
};
|
||||
}, [i18n.language]);
|
||||
|
||||
const handleShowMemoStoryDialog = () => {
|
||||
if (isVisitorMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
showMemoCardDialog(memo);
|
||||
};
|
||||
|
||||
const handleViewMemoDetailPage = () => {
|
||||
navigate(`/m/${memo.id}`);
|
||||
};
|
||||
@ -116,7 +107,7 @@ const Memo: React.FC<Props> = (props: Props) => {
|
||||
const memoTemp = await memoService.getMemoById(Number(memoId) ?? UNKNOWN_ID);
|
||||
|
||||
if (memoTemp) {
|
||||
showMemoCardDialog(memoTemp);
|
||||
navigate(`/m/${memoTemp.id}`);
|
||||
} else {
|
||||
toastHelper.error(t("message.memo-not-found"));
|
||||
targetEl.classList.remove("memo-link-text");
|
||||
@ -209,9 +200,7 @@ const Memo: React.FC<Props> = (props: Props) => {
|
||||
{memo.pinned && <div className="corner-container"></div>}
|
||||
<div className="memo-top-wrapper">
|
||||
<div className="status-text-container">
|
||||
<span className="time-text" onClick={handleShowMemoStoryDialog}>
|
||||
{displayTimeStr}
|
||||
</span>
|
||||
<span className="time-text">{displayTimeStr}</span>
|
||||
{memo.visibility !== "PRIVATE" && !isVisitorMode && (
|
||||
<span
|
||||
className={`status-text ${memo.visibility.toLocaleLowerCase()}`}
|
||||
|
@ -1,225 +0,0 @@
|
||||
import copy from "copy-to-clipboard";
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { editorStateService, memoService, userService } from "../services";
|
||||
import { useAppSelector } from "../store";
|
||||
import { UNKNOWN_ID } from "../helpers/consts";
|
||||
import * as utils from "../helpers/utils";
|
||||
import { parseHTMLToRawText } from "../helpers/utils";
|
||||
import { marked } from "../labs/marked";
|
||||
import { MARK_REG } from "../labs/marked/parser";
|
||||
import toastHelper from "./Toast";
|
||||
import { generateDialog } from "./Dialog";
|
||||
import Icon from "./Icon";
|
||||
import MemoContent from "./MemoContent";
|
||||
import MemoResources from "./MemoResources";
|
||||
import showChangeMemoCreatedTsDialog from "./ChangeMemoCreatedTsDialog";
|
||||
import "../less/memo-card-dialog.less";
|
||||
|
||||
interface LinkedMemo extends Memo {
|
||||
createdAtStr: string;
|
||||
dateStr: string;
|
||||
}
|
||||
|
||||
interface Props extends DialogProps {
|
||||
memo: Memo;
|
||||
}
|
||||
|
||||
const MemoCardDialog: React.FC<Props> = (props: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const memos = useAppSelector((state) => state.memo.memos);
|
||||
const [memo, setMemo] = useState<Memo>({
|
||||
...props.memo,
|
||||
});
|
||||
const [linkMemos, setLinkMemos] = useState<LinkedMemo[]>([]);
|
||||
const [linkedMemos, setLinkedMemos] = useState<LinkedMemo[]>([]);
|
||||
const isVisitorMode = userService.isVisitorMode();
|
||||
|
||||
useEffect(() => {
|
||||
const fetchLinkedMemos = async () => {
|
||||
try {
|
||||
const linkMemos: LinkedMemo[] = [];
|
||||
const matchedArr = [...memo.content.matchAll(MARK_REG)];
|
||||
for (const matchRes of matchedArr) {
|
||||
if (matchRes && matchRes.length === 3) {
|
||||
const id = Number(matchRes[2]);
|
||||
if (id === memo.id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const memoTemp = await memoService.getMemoById(id);
|
||||
if (memoTemp) {
|
||||
linkMemos.push({
|
||||
...memoTemp,
|
||||
createdAtStr: utils.getDateTimeString(memoTemp.displayTs),
|
||||
dateStr: utils.getDateString(memoTemp.displayTs),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
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.displayTs) - utils.getTimeStampByDate(a.displayTs))
|
||||
.map((m) => ({
|
||||
...m,
|
||||
createdAtStr: utils.getDateTimeString(m.displayTs),
|
||||
dateStr: utils.getDateString(m.displayTs),
|
||||
}))
|
||||
);
|
||||
} catch (error) {
|
||||
// do nth
|
||||
}
|
||||
};
|
||||
|
||||
fetchLinkedMemos();
|
||||
memoService.getMemoById(memo.id).then((memo) => {
|
||||
setMemo(memo);
|
||||
});
|
||||
}, [memos, memo.id]);
|
||||
|
||||
const handleMemoCreatedAtClick = () => {
|
||||
if (isVisitorMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
showChangeMemoCreatedTsDialog(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 = await memoService.getMemoById(Number(nextMemoId) ?? UNKNOWN_ID);
|
||||
|
||||
if (memoTemp) {
|
||||
const nextMemo = {
|
||||
...memoTemp,
|
||||
createdAtStr: utils.getDateTimeString(memoTemp.displayTs),
|
||||
};
|
||||
setLinkMemos([]);
|
||||
setLinkedMemos([]);
|
||||
setMemo(nextMemo);
|
||||
} else {
|
||||
toastHelper.error(t("message.memo-not-found"));
|
||||
targetEl.classList.remove("memo-link-text");
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleLinkedMemoClick = useCallback((memo: Memo) => {
|
||||
setLinkMemos([]);
|
||||
setLinkedMemos([]);
|
||||
setMemo(memo);
|
||||
}, []);
|
||||
|
||||
const handleGotoMemoLinkBtnClick = () => {
|
||||
window.open(`/m/${memo.id}`);
|
||||
};
|
||||
|
||||
const handleEditMemoBtnClick = () => {
|
||||
props.destroy();
|
||||
editorStateService.setEditMemoWithId(memo.id);
|
||||
};
|
||||
|
||||
const handleCopyContent = () => {
|
||||
copy(memo.content);
|
||||
toastHelper.success(t("message.succeed-copy-content"));
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="memo-card-container">
|
||||
<div className="header-container">
|
||||
<p className="time-text" onClick={handleMemoCreatedAtClick}>
|
||||
{utils.getDateTimeString(memo.displayTs)}
|
||||
</p>
|
||||
<div className="btns-container">
|
||||
{!isVisitorMode && (
|
||||
<>
|
||||
<button className="btn edit-btn" onClick={handleGotoMemoLinkBtnClick}>
|
||||
<Icon.ExternalLink className="icon-img" />
|
||||
</button>
|
||||
<button className="btn copy-btn" onClick={handleCopyContent}>
|
||||
<Icon.Clipboard className="icon-img" />
|
||||
</button>
|
||||
<button className="btn edit-btn" onClick={handleEditMemoBtnClick}>
|
||||
<Icon.Edit3 className="icon-img" />
|
||||
</button>
|
||||
<span className="split-line">/</span>
|
||||
</>
|
||||
)}
|
||||
<button className="btn close-btn" onClick={props.destroy}>
|
||||
<Icon.X className="icon-img" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="memo-container">
|
||||
<MemoContent displayConfig={{ enableExpand: false }} content={memo.content} onMemoContentClick={handleMemoContentClick} />
|
||||
<MemoResources resourceList={memo.resourceList} />
|
||||
</div>
|
||||
<div className="layer-container"></div>
|
||||
{linkMemos.map((_, idx) => {
|
||||
if (idx < 4) {
|
||||
return (
|
||||
<div
|
||||
className="background-layer-container"
|
||||
key={idx}
|
||||
style={{
|
||||
bottom: (idx + 1) * -3 + "px",
|
||||
left: (idx + 1) * 5 + "px",
|
||||
width: `calc(100% - ${(idx + 1) * 10}px)`,
|
||||
zIndex: -idx - 1,
|
||||
}}
|
||||
></div>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
{linkMemos.length > 0 ? (
|
||||
<div className="linked-memos-wrapper">
|
||||
<p className="normal-text">{linkMemos.length} related MEMO</p>
|
||||
{linkMemos.map((memo, index) => {
|
||||
const rawtext = parseHTMLToRawText(marked(memo.content)).replaceAll("\n", " ");
|
||||
return (
|
||||
<div className="linked-memo-container" key={`${index}-${memo.id}`} onClick={() => handleLinkedMemoClick(memo)}>
|
||||
<span className="time-text">{memo.dateStr} </span>
|
||||
{rawtext}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
) : null}
|
||||
{linkedMemos.length > 0 ? (
|
||||
<div className="linked-memos-wrapper">
|
||||
<p className="normal-text">{linkedMemos.length} linked MEMO</p>
|
||||
{linkedMemos.map((memo, index) => {
|
||||
const rawtext = parseHTMLToRawText(marked(memo.content)).replaceAll("\n", " ");
|
||||
return (
|
||||
<div className="linked-memo-container" key={`${index}-${memo.id}`} onClick={() => handleLinkedMemoClick(memo)}>
|
||||
<span className="time-text">{memo.dateStr} </span>
|
||||
{rawtext}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default function showMemoCardDialog(memo: Memo): void {
|
||||
generateDialog(
|
||||
{
|
||||
className: "memo-card-dialog",
|
||||
},
|
||||
MemoCardDialog,
|
||||
{ memo }
|
||||
);
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
.dialog-wrapper.memo-card-dialog {
|
||||
@apply px-4;
|
||||
|
||||
> .dialog-container {
|
||||
@apply w-full p-0 bg-transparent flex flex-col justify-start items-center;
|
||||
|
||||
> .memo-card-container {
|
||||
@apply flex flex-col justify-start items-start relative w-128 max-w-full py-3 px-6 mb-3 rounded-lg bg-yellow-200;
|
||||
|
||||
> * {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
> .header-container {
|
||||
@apply flex flex-row justify-between items-center w-full h-auto pb-0 my-0;
|
||||
|
||||
> .time-text {
|
||||
@apply text-sm text-gray-500 font-mono;
|
||||
}
|
||||
|
||||
> .btns-container {
|
||||
@apply flex flex-row justify-end items-center;
|
||||
|
||||
> .btn {
|
||||
@apply flex flex-row justify-center items-center w-6 h-6 p-1 ml-2 rounded text-gray-600 hover:bg-white;
|
||||
}
|
||||
|
||||
> .split-line {
|
||||
@apply font-mono text-gray-300 ml-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .memo-container {
|
||||
@apply w-full flex flex-col justify-start items-start pt-2;
|
||||
}
|
||||
|
||||
> .normal-text {
|
||||
@apply mt-2 text-sm text-gray-500;
|
||||
}
|
||||
|
||||
> .layer-container,
|
||||
> .background-layer-container {
|
||||
@apply bg-white;
|
||||
position: absolute;
|
||||
bottom: -3px;
|
||||
left: 3px;
|
||||
width: calc(100% - 6px);
|
||||
height: 100%;
|
||||
border-radius: 8px;
|
||||
z-index: -1;
|
||||
border-bottom: 1px solid lightgray;
|
||||
}
|
||||
|
||||
> .layer-container {
|
||||
@apply bg-white;
|
||||
z-index: 0;
|
||||
border: 1px solid lightgray;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
> .linked-memos-wrapper {
|
||||
@apply flex flex-col justify-start items-start w-128 max-w-full mt-2 py-3 px-6 rounded-lg bg-white last:mb-8;
|
||||
|
||||
> .normal-text {
|
||||
@apply text-sm;
|
||||
}
|
||||
|
||||
> .linked-memo-container {
|
||||
@apply text-sm leading-6 mt-2 cursor-pointer max-w-full truncate hover:opacity-80;
|
||||
|
||||
> .time-text {
|
||||
@apply font-mono text-gray-500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -28,7 +28,7 @@
|
||||
@apply flex flex-row justify-start items-center;
|
||||
|
||||
> .time-text {
|
||||
@apply text-xs text-gray-400 cursor-pointer;
|
||||
@apply text-xs text-gray-400;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user