mirror of
https://github.com/usememos/memos.git
synced 2025-01-31 17:48:12 +08:00
chore: show inline image in daily review dialog (#135)
This commit is contained in:
parent
9994b1fabc
commit
df7b4d54c6
7 changed files with 51 additions and 31 deletions
|
@ -2,10 +2,10 @@ import { IMAGE_URL_REG } from "../helpers/consts";
|
|||
import * as utils from "../helpers/utils";
|
||||
import useToggle from "../hooks/useToggle";
|
||||
import { memoService } from "../services";
|
||||
import { formatMemoContent } from "../helpers/marked";
|
||||
import Only from "./common/OnlyWhen";
|
||||
import Image from "./Image";
|
||||
import toastHelper from "./Toast";
|
||||
import { formatMemoContent } from "./Memo";
|
||||
import "../less/memo.less";
|
||||
|
||||
interface Props {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import { IMAGE_URL_REG } from "../helpers/consts";
|
||||
import * as utils from "../helpers/utils";
|
||||
import Only from "./common/OnlyWhen";
|
||||
import { formatMemoContent } from "./Memo";
|
||||
import { formatMemoContent } from "../helpers/marked";
|
||||
import "../less/daily-memo.less";
|
||||
|
||||
interface DailyMemo extends Memo {
|
||||
|
@ -20,7 +18,6 @@ const DailyMemo: React.FC<Props> = (props: Props) => {
|
|||
createdAtStr: utils.getDateTimeString(propsMemo.createdTs),
|
||||
timeStr: utils.getTimeString(propsMemo.createdTs),
|
||||
};
|
||||
const imageUrls = Array.from(memo.content.match(IMAGE_URL_REG) ?? []).map((s) => s.replace(IMAGE_URL_REG, "$1"));
|
||||
|
||||
return (
|
||||
<div className="daily-memo-wrapper">
|
||||
|
@ -28,14 +25,14 @@ const DailyMemo: React.FC<Props> = (props: Props) => {
|
|||
<span className="normal-text">{memo.timeStr}</span>
|
||||
</div>
|
||||
<div className="memo-content-container">
|
||||
<div className="memo-content-text" dangerouslySetInnerHTML={{ __html: formatMemoContent(memo.content) }}></div>
|
||||
<Only when={imageUrls.length > 0}>
|
||||
<div className="images-container">
|
||||
{imageUrls.map((imgUrl, idx) => (
|
||||
<img key={idx} src={imgUrl} decoding="async" />
|
||||
))}
|
||||
</div>
|
||||
</Only>
|
||||
<div
|
||||
className="memo-content-text"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: formatMemoContent(memo.content, {
|
||||
inlineImage: true,
|
||||
}),
|
||||
}}
|
||||
></div>
|
||||
</div>
|
||||
<div className="split-line"></div>
|
||||
</div>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { memo, useEffect, useRef, useState } from "react";
|
||||
import { escape, indexOf } from "lodash-es";
|
||||
import { indexOf } from "lodash-es";
|
||||
import dayjs from "dayjs";
|
||||
import relativeTime from "dayjs/plugin/relativeTime";
|
||||
import { IMAGE_URL_REG, LINK_URL_REG, MEMO_LINK_REG, TAG_REG, UNKNOWN_ID } from "../helpers/consts";
|
||||
import { DONE_BLOCK_REG, parseMarkedToHtml, TODO_BLOCK_REG } from "../helpers/marked";
|
||||
import { IMAGE_URL_REG, UNKNOWN_ID } from "../helpers/consts";
|
||||
import { DONE_BLOCK_REG, formatMemoContent, TODO_BLOCK_REG } from "../helpers/marked";
|
||||
import { editorStateService, locationService, memoService, userService } from "../services";
|
||||
import Only from "./common/OnlyWhen";
|
||||
import toastHelper from "./Toast";
|
||||
|
@ -234,15 +234,4 @@ const Memo: React.FC<Props> = (props: Props) => {
|
|||
);
|
||||
};
|
||||
|
||||
export function formatMemoContent(content: string) {
|
||||
const tempElement = document.createElement("div");
|
||||
tempElement.innerHTML = parseMarkedToHtml(escape(content));
|
||||
|
||||
return tempElement.innerHTML
|
||||
.replace(IMAGE_URL_REG, "")
|
||||
.replace(MEMO_LINK_REG, "<span class='memo-link-text' data-value='$2'>$1</span>")
|
||||
.replace(LINK_URL_REG, "<a class='link' target='_blank' rel='noreferrer' href='$2'>$1</a>")
|
||||
.replace(TAG_REG, "<span class='tag-span'>#$1</span> ");
|
||||
}
|
||||
|
||||
export default memo(Memo);
|
||||
|
|
|
@ -2,12 +2,11 @@ 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 { formatMemoContent, parseHtmlToRawText } from "../helpers/marked";
|
||||
import Only from "./common/OnlyWhen";
|
||||
import toastHelper from "./Toast";
|
||||
import { generateDialog } from "./Dialog";
|
||||
import Image from "./Image";
|
||||
import { formatMemoContent } from "./Memo";
|
||||
import "../less/memo-card-dialog.less";
|
||||
import Selector from "./common/Selector";
|
||||
|
||||
|
|
|
@ -3,10 +3,10 @@ import { userService } from "../services";
|
|||
import toImage from "../labs/html2image";
|
||||
import { ANIMATION_DURATION, IMAGE_URL_REG } from "../helpers/consts";
|
||||
import * as utils from "../helpers/utils";
|
||||
import { formatMemoContent } from "../helpers/marked";
|
||||
import { generateDialog } from "./Dialog";
|
||||
import Only from "./common/OnlyWhen";
|
||||
import toastHelper from "./Toast";
|
||||
import { formatMemoContent } from "./Memo";
|
||||
import "../less/share-memo-image-dialog.less";
|
||||
|
||||
interface Props extends DialogProps {
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import { escape } from "lodash-es";
|
||||
import { IMAGE_URL_REG, LINK_URL_REG, MEMO_LINK_REG, TAG_REG } from "./consts";
|
||||
|
||||
const CODE_BLOCK_REG = /```([\s\S]*?)```/g;
|
||||
const BOLD_TEXT_REG = /\*\*(.+?)\*\*/g;
|
||||
const EM_TEXT_REG = /\*(.+?)\*/g;
|
||||
|
@ -28,4 +31,32 @@ const parseHtmlToRawText = (htmlStr: string): string => {
|
|||
return text;
|
||||
};
|
||||
|
||||
export { parseMarkedToHtml, parseHtmlToRawText };
|
||||
interface FormatterConfig {
|
||||
inlineImage: boolean;
|
||||
}
|
||||
const defaultFormatterConfig: FormatterConfig = {
|
||||
inlineImage: false,
|
||||
};
|
||||
|
||||
const formatMemoContent = (content: string, addtionConfig?: Partial<FormatterConfig>) => {
|
||||
const config = {
|
||||
...defaultFormatterConfig,
|
||||
...addtionConfig,
|
||||
};
|
||||
const tempElement = document.createElement("div");
|
||||
tempElement.innerHTML = parseMarkedToHtml(escape(content));
|
||||
|
||||
let outputString = tempElement.innerHTML;
|
||||
if (config.inlineImage) {
|
||||
outputString = outputString.replace(IMAGE_URL_REG, "<img class='img' src='$1' />");
|
||||
} else {
|
||||
outputString = outputString.replace(IMAGE_URL_REG, "");
|
||||
}
|
||||
|
||||
return outputString
|
||||
.replace(MEMO_LINK_REG, "<span class='memo-link-text' data-value='$2'>$1</span>")
|
||||
.replace(LINK_URL_REG, "<a class='link' target='_blank' rel='noreferrer' href='$2'>$1</a>")
|
||||
.replace(TAG_REG, "<span class='tag-span'>#$1</span> ");
|
||||
};
|
||||
|
||||
export { formatMemoContent, parseHtmlToRawText };
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
@apply inline-block w-full h-auto mb-1 last:mb-0 text-base leading-7 whitespace-pre-wrap break-all;
|
||||
}
|
||||
|
||||
.img {
|
||||
@apply float-left max-w-full w-full;
|
||||
}
|
||||
|
||||
.tag-span {
|
||||
@apply inline-block w-auto font-mono text-blue-600;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue