diff --git a/web/src/components/AboutSiteDialog.tsx b/web/src/components/AboutSiteDialog.tsx index 19f76548..0c3ac1e7 100644 --- a/web/src/components/AboutSiteDialog.tsx +++ b/web/src/components/AboutSiteDialog.tsx @@ -12,45 +12,23 @@ const AboutSiteDialog: React.FC = ({ destroy }: Props) => { <>

- 🤠关于 Memos + 🤠About Memos

-

一个碎片化知识记录工具。

-
- 为何做这个? - -
- 有何特点呢? - -
- - 🤔 问题反馈 - +

+ An open-source alternative to flomo. +

+

You are in charge of your data and customizations.

+

Built with React and Go.


Enjoy it and have fun~


- Last updated on 2021/11/26 16:17:44 🎉 + Last updated on 2021/12/09 10:14:32 🎉

diff --git a/web/src/components/MemoEditor.tsx b/web/src/components/MemoEditor.tsx index 9986ad18..d3ad8306 100644 --- a/web/src/components/MemoEditor.tsx +++ b/web/src/components/MemoEditor.tsx @@ -16,26 +16,27 @@ const MemoEditor: React.FC = (props: Props) => { const { className, editMemoId } = props; const { globalState } = useContext(appContext); const editorRef = useRef(null); - const prevGlobalStateRef = useRef(globalState); useEffect(() => { if (globalState.markMemoId) { - const editorCurrentValue = editorRef.current?.getContent(); - const memoLinkText = `${editorCurrentValue ? "\n" : ""}Mark: [@MEMO](${globalState.markMemoId})`; - editorRef.current?.insertText(memoLinkText); - globalStateService.setMarkMemoId(""); + if (editMemoId === globalState.editMemoId || (!editMemoId && !globalState.editMemoId)) { + const editorCurrentValue = editorRef.current?.getContent(); + const memoLinkText = `${editorCurrentValue ? "\n" : ""}Mark: [@MEMO](${globalState.markMemoId})`; + editorRef.current?.insertText(memoLinkText); + globalStateService.setMarkMemoId(""); + } } + }, [globalState.markMemoId]); - if (editMemoId && globalState.editMemoId) { - const editMemo = memoService.getMemoById(globalState.editMemoId); + useEffect(() => { + if (editMemoId) { + const editMemo = memoService.getMemoById(editMemoId); if (editMemo) { editorRef.current?.setContent(editMemo.content ?? ""); editorRef.current?.focus(); } } - - prevGlobalStateRef.current = globalState; - }, [globalState.markMemoId, globalState.editMemoId]); + }, [editMemoId]); const handleSaveBtnClick = useCallback(async (content: string) => { if (content === "") { diff --git a/web/src/helpers/marked.ts b/web/src/helpers/marked.ts index 3b4cacae..ddc9843a 100644 --- a/web/src/helpers/marked.ts +++ b/web/src/helpers/marked.ts @@ -54,7 +54,7 @@ const parseCodeToPrism = (codeStr: string): string => { const parseMarkedToHtml = (markedStr: string): string => { const htmlText = parseCodeToPrism(markedStr) - .replace(DOT_LI_REG, "") + .replace(DOT_LI_REG, "") .replace(NUM_LI_REG, "$1.") .replace(TODO_BLOCK_REG, "") .replace(DONE_BLOCK_REG, "") diff --git a/web/src/labs/html2image/convertResourceToDataURL.ts b/web/src/labs/html2image/convertResourceToDataURL.ts index 2a5729a7..cfcbcb75 100644 --- a/web/src/labs/html2image/convertResourceToDataURL.ts +++ b/web/src/labs/html2image/convertResourceToDataURL.ts @@ -1,8 +1,8 @@ -const cachedResource = new Map(); +const cachedResourceMap = new Map(); function convertResourceToDataURL(url: string, useCache = true): Promise { - if (useCache && cachedResource.has(url)) { - return Promise.resolve(cachedResource.get(url) as string); + if (useCache && cachedResourceMap.has(url)) { + return Promise.resolve(cachedResourceMap.get(url) as string); } return new Promise(async (resolve) => { @@ -11,7 +11,7 @@ function convertResourceToDataURL(url: string, useCache = true): Promise var reader = new FileReader(); reader.onloadend = () => { const base64Url = reader.result as string; - cachedResource.set(url, base64Url); + cachedResourceMap.set(url, base64Url); resolve(base64Url); }; reader.readAsDataURL(blob); diff --git a/web/src/labs/html2image/getFontsStyleElement.ts b/web/src/labs/html2image/getFontsStyleElement.ts new file mode 100644 index 00000000..1385a8d2 --- /dev/null +++ b/web/src/labs/html2image/getFontsStyleElement.ts @@ -0,0 +1,46 @@ +import convertResourceToDataURL from "./convertResourceToDataURL"; + +async function getFontsStyleElement(element: HTMLElement) { + const styleSheets = element.ownerDocument.styleSheets; + const fontFamilyStyles: CSSStyleDeclaration[] = []; + + for (const sheet of styleSheets) { + for (const rule of sheet.cssRules) { + if (rule.constructor.name === "CSSFontFaceRule") { + fontFamilyStyles.push((rule as CSSFontFaceRule).style); + } + } + } + + const styleElement = document.createElement("style"); + + for (const f of fontFamilyStyles) { + const fontFamily = f.getPropertyValue("font-family"); + const fontWeight = f.getPropertyValue("font-weight"); + const src = f.getPropertyValue("src"); + const resourceUrls = src.split(",").map((s) => { + return s.replace(/url\("?(.+?)"?\)/, "$1"); + }); + let base64Urls = []; + + for (const url of resourceUrls) { + try { + const base64Url = await convertResourceToDataURL(url); + base64Urls.push(`url("${base64Url}")`); + } catch (error) { + // do nth + } + } + + styleElement.innerHTML += ` + @font-face { + font-family: "${fontFamily}"; + src: ${base64Urls.join(",")}; + font-weight: ${fontWeight}; + }`; + } + + return styleElement; +} + +export default getFontsStyleElement; diff --git a/web/src/labs/html2image/index.ts b/web/src/labs/html2image/index.ts index a4957318..f5b8012b 100644 --- a/web/src/labs/html2image/index.ts +++ b/web/src/labs/html2image/index.ts @@ -5,8 +5,8 @@ * 1. html-to-image: https://github.com/bubkoo/html-to-image * 2. : https://developer.mozilla.org/en-US/docs/Web/SVG/Element/foreignObject */ -import convertResourceToDataURL from "./convertResourceToDataURL"; import getCloneStyledElement from "./getCloneStyledElement"; +import getFontsStyleElement from "./getFontsStyleElement"; type Options = Partial<{ backgroundColor: string; @@ -29,14 +29,14 @@ function convertSVGToDataURL(svg: SVGElement): string { } function generateSVGElement(width: number, height: number, element: HTMLElement): SVGSVGElement { - const xmlns = "http://www.w3.org/2000/svg"; - const svg = document.createElementNS(xmlns, "svg"); + const xmlNS = "http://www.w3.org/2000/svg"; + const svgElement = document.createElementNS(xmlNS, "svg"); - svg.setAttribute("width", `${width}`); - svg.setAttribute("height", `${height}`); - svg.setAttribute("viewBox", `0 0 ${width} ${height}`); + svgElement.setAttribute("width", `${width}`); + svgElement.setAttribute("height", `${height}`); + svgElement.setAttribute("viewBox", `0 0 ${width} ${height}`); - const foreignObject = document.createElementNS(xmlns, "foreignObject"); + const foreignObject = document.createElementNS(xmlNS, "foreignObject"); foreignObject.setAttribute("width", "100%"); foreignObject.setAttribute("height", "100%"); @@ -45,44 +45,9 @@ function generateSVGElement(width: number, height: number, element: HTMLElement) foreignObject.setAttribute("externalResourcesRequired", "true"); foreignObject.appendChild(element); - svg.appendChild(foreignObject); + svgElement.appendChild(foreignObject); - return svg; -} - -// TODO need rethink how to get the needed font-family -async function getFontsStyleElement() { - const styleElement = document.createElement("style"); - - const fonts = [ - { - name: "DINPro", - url: "/fonts/DINPro-Regular.otf", - weight: "normal", - }, - { - name: "DINPro", - url: "/fonts/DINPro-Bold.otf", - weight: "bold", - }, - { - name: "ubuntu-mono", - url: "/fonts/UbuntuMono.ttf", - weight: "normal", - }, - ]; - - for (const f of fonts) { - const base64Url = await convertResourceToDataURL(f.url); - styleElement.innerHTML += ` - @font-face { - font-family: "${f.name}"; - src: url("${base64Url}"); - font-weight: ${f.weight}; - }`; - } - - return styleElement; + return svgElement; } export async function toSVG(element: HTMLElement, options?: Options) { @@ -95,7 +60,7 @@ export async function toSVG(element: HTMLElement, options?: Options) { } const svg = generateSVGElement(width, height, clonedElement); - svg.prepend(await getFontsStyleElement()); + svg.prepend(await getFontsStyleElement(element)); const url = convertSVGToDataURL(svg); diff --git a/web/src/less/about-site-dialog.less b/web/src/less/about-site-dialog.less index 608976df..9f40a37d 100644 --- a/web/src/less/about-site-dialog.less +++ b/web/src/less/about-site-dialog.less @@ -7,10 +7,8 @@ > .dialog-content-container { line-height: 1.8; - > ul { - margin: 4px 0; - padding-left: 4px; - width: 100%; + > p { + margin: 2px 0; } > hr { @@ -26,6 +24,7 @@ font-size: 13px; color: gray; white-space: pre-wrap; + .mono-font-family(); } .pre-text { diff --git a/web/src/less/memolist.less b/web/src/less/memolist.less index b2cb3301..2684d375 100644 --- a/web/src/less/memolist.less +++ b/web/src/less/memolist.less @@ -9,6 +9,7 @@ > .memo-edit { margin-top: 8px; + width: 100%; } > .status-text-container {