chore: expand/fold memo content button (#84)

* chore: toggle show all content button

* chore: update expand text

* chore: rename
This commit is contained in:
Steven 2022-06-22 08:36:09 +08:00 committed by GitHub
parent ceef257348
commit 1999260f9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 72 additions and 4 deletions

View File

@ -1,4 +1,4 @@
import { memo } from "react"; import { memo, useEffect, useRef, useState } from "react";
import { escape } from "lodash-es"; import { escape } from "lodash-es";
import { IMAGE_URL_REG, LINK_REG, MEMO_LINK_REG, TAG_REG, UNKNOWN_ID } from "../helpers/consts"; import { IMAGE_URL_REG, LINK_REG, MEMO_LINK_REG, TAG_REG, UNKNOWN_ID } from "../helpers/consts";
import { parseMarkedToHtml, parseRawTextToHtml } from "../helpers/marked"; import { parseMarkedToHtml, parseRawTextToHtml } from "../helpers/marked";
@ -12,19 +12,44 @@ import showShareMemoImageDialog from "./ShareMemoImageDialog";
import toastHelper from "./Toast"; import toastHelper from "./Toast";
import "../less/memo.less"; import "../less/memo.less";
const MAX_MEMO_CONTAINER_HEIGHT = 384;
interface Props { interface Props {
memo: Memo; memo: Memo;
} }
type ExpandButtonStatus = -1 | 0 | 1;
interface State {
expandButtonStatus: ExpandButtonStatus;
}
const Memo: React.FC<Props> = (props: Props) => { const Memo: React.FC<Props> = (props: Props) => {
const { memo: propsMemo } = props; const { memo: propsMemo } = props;
const memo = { const memo = {
...propsMemo, ...propsMemo,
createdAtStr: utils.getDateTimeString(propsMemo.createdTs), createdAtStr: utils.getDateTimeString(propsMemo.createdTs),
}; };
const [state, setState] = useState<State>({
expandButtonStatus: -1,
});
const memoContainerRef = useRef<HTMLDivElement>(null);
const [showConfirmDeleteBtn, toggleConfirmDeleteBtn] = useToggle(false); const [showConfirmDeleteBtn, toggleConfirmDeleteBtn] = useToggle(false);
const imageUrls = Array.from(memo.content.match(IMAGE_URL_REG) ?? []).map((s) => s.replace(IMAGE_URL_REG, "$1")); const imageUrls = Array.from(memo.content.match(IMAGE_URL_REG) ?? []).map((s) => s.replace(IMAGE_URL_REG, "$1"));
useEffect(() => {
if (!memoContainerRef) {
return;
}
if (Number(memoContainerRef.current?.clientHeight) > MAX_MEMO_CONTAINER_HEIGHT) {
setState({
...state,
expandButtonStatus: 0,
});
}
}, []);
const handleShowMemoStoryDialog = () => { const handleShowMemoStoryDialog = () => {
showMemoCardDialog(memo); showMemoCardDialog(memo);
}; };
@ -96,6 +121,13 @@ const Memo: React.FC<Props> = (props: Props) => {
} }
}; };
const handleShowMoreBtnClick = () => {
setState({
...state,
expandButtonStatus: Number(Boolean(!state.expandButtonStatus)) as ExpandButtonStatus,
});
};
return ( return (
<div className={`memo-wrapper ${"memos-" + memo.id} ${memo.pinned ? "pinned" : ""}`} onMouseLeave={handleMouseLeaveMemoWrapper}> <div className={`memo-wrapper ${"memos-" + memo.id} ${memo.pinned ? "pinned" : ""}`} onMouseLeave={handleMouseLeaveMemoWrapper}>
<div className="memo-top-wrapper"> <div className="memo-top-wrapper">
@ -139,10 +171,19 @@ const Memo: React.FC<Props> = (props: Props) => {
</div> </div>
</div> </div>
<div <div
className="memo-content-text" ref={memoContainerRef}
className={`memo-content-text ${state.expandButtonStatus === 0 ? "!max-h-96 overflow-y-hidden truncate" : ""}`}
onClick={handleMemoContentClick} onClick={handleMemoContentClick}
dangerouslySetInnerHTML={{ __html: formatMemoContent(memo.content) }} dangerouslySetInnerHTML={{ __html: formatMemoContent(memo.content) }}
></div> ></div>
{state.expandButtonStatus !== -1 && (
<div className="expand-btn-container">
<span className={`btn ${state.expandButtonStatus === 0 ? "expand-btn" : "fold-btn"}`} onClick={handleShowMoreBtnClick}>
{state.expandButtonStatus === 0 ? "Expand" : "Fold"}
<img className="icon-img" src="/icons/arrow-right.svg" alt="" />
</span>
</div>
)}
<Only when={imageUrls.length > 0}> <Only when={imageUrls.length > 0}>
<div className="images-wrapper"> <div className="images-wrapper">
{imageUrls.map((imgUrl, idx) => ( {imageUrls.map((imgUrl, idx) => (

View File

@ -28,8 +28,9 @@ const MemoTrashDialog: React.FC<Props> = (props: Props) => {
locationService.clearQuery(); locationService.clearQuery();
}, []); }, []);
const handleDeletedMemoAction = useCallback((memoId: MemoId) => { const handleDeletedMemoAction = useCallback(async (memoId: MemoId) => {
setDeletedMemos((deletedMemos) => deletedMemos.filter((memo) => memo.id !== memoId)); setDeletedMemos((deletedMemos) => deletedMemos.filter((memo) => memo.id !== memoId));
await memoService.fetchAllMemos();
}, []); }, []);
return ( return (

View File

@ -86,7 +86,33 @@
} }
> .memo-content-text { > .memo-content-text {
@apply w-full h-auto; @apply w-full h-auto transition-all;
}
> .expand-btn-container {
@apply w-full relative flex flex-row justify-start items-center;
> .btn {
@apply flex flex-row justify-start items-center px-2 py-1 my-1 text-xs rounded-lg border bg-gray-100 border-gray-200 opacity-80 shadow hover:opacity-60;
&.expand-btn {
@apply mt-2;
> .icon-img {
@apply rotate-90;
}
}
&.fold-btn {
> .icon-img {
@apply -rotate-90;
}
}
> .icon-img {
@apply w-4 h-auto transition-all;
}
}
} }
> .images-wrapper { > .images-wrapper {