mirror of
https://github.com/usememos/memos.git
synced 2024-10-04 23:38:46 +03:00
feat: update memo resource component
This commit is contained in:
parent
e5c9d8604d
commit
c7cf35c7de
@ -1,5 +1,6 @@
|
|||||||
import * as utils from "../helpers/utils";
|
import * as utils from "../helpers/utils";
|
||||||
import MemoContent, { DisplayConfig } from "./MemoContent";
|
import MemoContent, { DisplayConfig } from "./MemoContent";
|
||||||
|
import MemoResources from "./MemoResources";
|
||||||
import "../less/daily-memo.less";
|
import "../less/daily-memo.less";
|
||||||
|
|
||||||
interface DailyMemo extends Memo {
|
interface DailyMemo extends Memo {
|
||||||
@ -28,7 +29,10 @@ const DailyMemo: React.FC<Props> = (props: Props) => {
|
|||||||
<div className="time-wrapper">
|
<div className="time-wrapper">
|
||||||
<span className="normal-text">{memo.timeStr}</span>
|
<span className="normal-text">{memo.timeStr}</span>
|
||||||
</div>
|
</div>
|
||||||
<MemoContent content={memo.content} displayConfig={displayConfig} />
|
<div className="memo-container">
|
||||||
|
<MemoContent content={memo.content} displayConfig={displayConfig} />
|
||||||
|
<MemoResources memo={memo} />
|
||||||
|
</div>
|
||||||
<div className="split-line"></div>
|
<div className="split-line"></div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -126,7 +126,7 @@ const MemoEditor: React.FC = () => {
|
|||||||
if (editMemoId && editMemoId !== UNKNOWN_ID) {
|
if (editMemoId && editMemoId !== UNKNOWN_ID) {
|
||||||
const prevMemo = memoService.getMemoById(editMemoId ?? UNKNOWN_ID);
|
const prevMemo = memoService.getMemoById(editMemoId ?? UNKNOWN_ID);
|
||||||
|
|
||||||
if (prevMemo && prevMemo.content !== content) {
|
if (prevMemo) {
|
||||||
await memoService.patchMemo({
|
await memoService.patchMemo({
|
||||||
id: prevMemo.id,
|
id: prevMemo.id,
|
||||||
content,
|
content,
|
||||||
@ -347,11 +347,7 @@ const MemoEditor: React.FC = () => {
|
|||||||
{state.resourceList.map((resource) => {
|
{state.resourceList.map((resource) => {
|
||||||
return (
|
return (
|
||||||
<div key={resource.id} className="resource-container">
|
<div key={resource.id} className="resource-container">
|
||||||
{resource.type.includes("image") ? (
|
{resource.type.includes("image") ? <Icon.Image className="icon-img" /> : <Icon.FileText className="icon-img" />}
|
||||||
<Icon.Image className="icon-img" onClick={handleUploadFileBtnClick} />
|
|
||||||
) : (
|
|
||||||
<Icon.FileText className="icon-img" onClick={handleUploadFileBtnClick} />
|
|
||||||
)}
|
|
||||||
<span className="name-text">{resource.filename}</span>
|
<span className="name-text">{resource.filename}</span>
|
||||||
<Icon.X className="close-icon" onClick={() => handleDeleteResource(resource.id)} />
|
<Icon.X className="close-icon" onClick={() => handleDeleteResource(resource.id)} />
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,25 +1,40 @@
|
|||||||
import { IMAGE_URL_REG } from "../helpers/marked";
|
|
||||||
import Image from "./Image";
|
import Image from "./Image";
|
||||||
|
import Icon from "./Icon";
|
||||||
import "../less/memo-resources.less";
|
import "../less/memo-resources.less";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
className?: string;
|
|
||||||
memo: Memo;
|
memo: Memo;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MemoResources: React.FC<Props> = (props: Props) => {
|
const MemoResources: React.FC<Props> = (props: Props) => {
|
||||||
const { className, memo } = props;
|
const { memo } = props;
|
||||||
const imageUrls = Array.from(memo.content.match(IMAGE_URL_REG) ?? []).map((s) => s.replace(IMAGE_URL_REG, "$1"));
|
const imageList = memo.resourceList.filter((resource) => resource.type.includes("image"));
|
||||||
|
const otherResourceList = memo.resourceList.filter((resource) => !resource.type.includes("image"));
|
||||||
|
|
||||||
|
const handlPreviewBtnClick = (resource: Resource) => {
|
||||||
|
const resourceUrl = `${window.location.origin}/o/r/${resource.id}/${resource.filename}`;
|
||||||
|
window.open(resourceUrl);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="resource-wrapper">
|
<div className="resource-wrapper">
|
||||||
{imageUrls.length > 0 && (
|
{imageList.length > 0 && (
|
||||||
<div className={`images-wrapper ${className ?? ""}`}>
|
<div className="images-wrapper">
|
||||||
{imageUrls.map((imgUrl, idx) => (
|
{imageList.map((resource) => (
|
||||||
<Image className="memo-img" key={idx} imgUrl={imgUrl} />
|
<Image className="memo-img" key={resource.id} imgUrl={`/o/r/${resource.id}/${resource.filename}`} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
<div className="other-resource-wrapper">
|
||||||
|
{otherResourceList.map((resource) => {
|
||||||
|
return (
|
||||||
|
<div className="other-resource-container" key={resource.id} onClick={() => handlPreviewBtnClick(resource)}>
|
||||||
|
<Icon.FileText className="icon-img" />
|
||||||
|
<span className="name-text">{resource.filename}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -17,7 +17,11 @@
|
|||||||
@apply mt-px mr-4 w-12 h-7 shrink-0 text-xs leading-6 text-center font-mono rounded-lg bg-gray-100 border-2 border-white text-gray-600 z-10;
|
@apply mt-px mr-4 w-12 h-7 shrink-0 text-xs leading-6 text-center font-mono rounded-lg bg-gray-100 border-2 border-white text-gray-600 z-10;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .memo-content-container {
|
> .memo-container {
|
||||||
@apply flex flex-col justify-start items-start w-full overflow-x-hidden p-0 text-base;
|
@apply w-full overflow-x-hidden flex flex-col justify-start items-start;
|
||||||
|
|
||||||
|
> .memo-content-container {
|
||||||
|
@apply flex flex-col justify-start items-start w-full overflow-x-hidden p-0 text-base;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,4 +16,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> .other-resource-wrapper {
|
||||||
|
@apply w-full flex flex-row justify-start flex-wrap;
|
||||||
|
|
||||||
|
> .other-resource-container {
|
||||||
|
@apply mt-1 mr-1 max-w-full flex flex-row justify-start items-center flex-nowrap bg-gray-50 px-2 py-1 rounded cursor-pointer hover:bg-gray-100;
|
||||||
|
|
||||||
|
> .icon-img {
|
||||||
|
@apply w-4 h-auto mr-1 text-gray-500;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .name-text {
|
||||||
|
@apply text-gray-500 text-sm max-w-xs truncate font-mono;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
4
web/src/types/modules/memo.d.ts
vendored
4
web/src/types/modules/memo.d.ts
vendored
@ -6,7 +6,6 @@ interface Memo {
|
|||||||
id: MemoId;
|
id: MemoId;
|
||||||
|
|
||||||
creatorId: UserId;
|
creatorId: UserId;
|
||||||
creator: User;
|
|
||||||
createdTs: TimeStamp;
|
createdTs: TimeStamp;
|
||||||
updatedTs: TimeStamp;
|
updatedTs: TimeStamp;
|
||||||
rowStatus: RowStatus;
|
rowStatus: RowStatus;
|
||||||
@ -14,6 +13,9 @@ interface Memo {
|
|||||||
content: string;
|
content: string;
|
||||||
visibility: Visibility;
|
visibility: Visibility;
|
||||||
pinned: boolean;
|
pinned: boolean;
|
||||||
|
|
||||||
|
creator: User;
|
||||||
|
resourceList: Resource[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MemoCreate {
|
interface MemoCreate {
|
||||||
|
Loading…
Reference in New Issue
Block a user