chore: show inline image in daily review dialog (#135)

This commit is contained in:
boojack 2022-07-29 20:11:14 +08:00 committed by GitHub
parent 9994b1fabc
commit df7b4d54c6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 51 additions and 31 deletions

View file

@ -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 {

View file

@ -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>

View file

@ -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);

View file

@ -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";

View file

@ -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 {

View file

@ -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 };

View file

@ -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;
}