diff --git a/electron-builder.yml b/electron-builder.yml
index c7c725df..09f8720d 100644
--- a/electron-builder.yml
+++ b/electron-builder.yml
@@ -42,7 +42,7 @@ mac:
target:
- target: dmg
arch:
- - x64
+# - x64
- arm64
linux:
target:
diff --git a/package.json b/package.json
index 7892c5a1..6a6717f2 100644
--- a/package.json
+++ b/package.json
@@ -29,9 +29,11 @@
"electron-log": "^4.4.8",
"electron-store": "^8.1.0",
"electron-updater": "^5.3.0",
+ "form-data": "^4.0.0",
"got": "^11.8.6",
"mime-types": "^2.1.35",
"mkdirp": "^3.0.0",
+ "node-fetch": "^2.6.13",
"node-watch": "^0.7.4",
"shiki": "^0.14.1",
"upath": "^2.0.1"
diff --git a/src/main/appMenus.ts b/src/main/appMenus.ts
index c01a78fe..f5588332 100644
--- a/src/main/appMenus.ts
+++ b/src/main/appMenus.ts
@@ -416,6 +416,12 @@ export const createAppMenus = () => {
shell.openExternal(`https://pb.bluemd.me/official/book/docs`)
}
},
+ {
+ label: 'Bluestone Website',
+ click: () => {
+ shell.openExternal('https://www.bluemd.me')
+ }
+ },
{
label: 'Github',
click: () => {
diff --git a/src/renderer/src/components/Nav.tsx b/src/renderer/src/components/Nav.tsx
index b0af7f01..aa24faf7 100644
--- a/src/renderer/src/components/Nav.tsx
+++ b/src/renderer/src/components/Nav.tsx
@@ -9,7 +9,7 @@ export const Nav = observer(() => {
const paths = useMemo(() => {
if (!treeStore.openNote) return ['']
return treeStore.getAbsolutePath(treeStore.openNote)
- }, [treeStore.openNote])
+ }, [treeStore.openNote?.filename])
return (
{
+ {/*
*/}
{
className={'text-lg duration-200 dark:group-hover:text-gray-300 group-hover:text-gray-700'}
/>
+ {/*
*/}
diff --git a/src/renderer/src/editor/elements/index.tsx b/src/renderer/src/editor/elements/index.tsx
index 136bda84..a3226e30 100644
--- a/src/renderer/src/editor/elements/index.tsx
+++ b/src/renderer/src/editor/elements/index.tsx
@@ -4,7 +4,7 @@ import {CodeCtx, CodeElement, CodeLine} from './code'
import {Blockquote} from './blockquote'
import {List, ListItem} from './list'
import {Head} from './head'
-import {CSSProperties, useContext, useMemo} from 'react'
+import React, {CSSProperties, useContext, useMemo} from 'react'
import {Paragraph} from './paragraph'
import {InlineChromiumBugfix} from '../utils/InlineChromiumBugfix'
import {Media} from './media'
@@ -12,7 +12,10 @@ import {useEditorStore} from '../store'
import {Point} from 'slate'
import {isAbsolute, join} from 'path'
import {treeStore} from '../../store/tree'
-
+const dragStart = (e: React.DragEvent) => {
+ e.preventDefault()
+ e.stopPropagation()
+}
export const MElement = (props: RenderElementProps) => {
switch (props.element.type) {
case 'blockquote':
@@ -77,6 +80,8 @@ export const MLeaf = (props: RenderLeafProps) => {
{
e.stopPropagation()
e.preventDefault()
@@ -106,6 +111,8 @@ export const MLeaf = (props: RenderLeafProps) => {
()
export const isMix = (t: Text) => {
return Object.keys(t).filter(key => ['bold', 'code', 'italic', 'strikethrough'].includes(key)).length > 1
}
+
+const textHtml = (t: Text) => {
+ let str = t.text || ''
+ if (t.highColor) str = `${str}`
+ if (t.code) str = `${str}
`
+ if (t.italic) str = `${str}`
+ if (t.bold) str = `${str}`
+ if (t.strikethrough) str = `${str}`
+ if (t.url) str = `${str}`
+ return str
+}
const textStyle = (t: Text) => {
if (!t.text) return ''
- if (t.highColor) return `${t.text}`
let str = t.text.replace(/(? {
return `${preStr}${str}${afterStr}`
}
const composeText = (t: Text, parent: any[]) => {
+ if (!t.text) return ''
+ if (t.highColor) return textHtml(t)
+
const siblings = parent[parent.length -1]?.children
const index = siblings?.findIndex(n => n === t)
- if (!t.text) return ''
- let str = textStyle(t)
+ let str = textStyle(t)!
if (t.url) {
str = `[${str}](${encodeURI(t.url)})`
} else if (isMix(t) && index !== -1) {
diff --git a/src/renderer/src/editor/parser/index.ts b/src/renderer/src/editor/parser/index.ts
index 4791899e..32f99323 100644
--- a/src/renderer/src/editor/parser/index.ts
+++ b/src/renderer/src/editor/parser/index.ts
@@ -39,7 +39,7 @@ const parseTable = (table: Table) => {
type: 'table-cell',
align: aligns?.[i] || undefined,
title: l === 0,
- children: c.children?.length ? parserBlock(c.children) : [{text: ''}]
+ children: c.children?.length ? parserBlock(c.children, false, c) : [{text: ''}]
}
})
}
@@ -51,8 +51,7 @@ const parserBlock = (nodes: Content[], top = false, parent?: Content) => {
let els:(Elements | Text) [] = []
let el:Element | null | Element[] = null
let preNode:null | Content = null
- let colorTag = ''
- let colorText = ''
+ let htmlTag:{tag: string, color?: string, url?: string}[] = []
for (let n of nodes) {
switch (n.type) {
case 'heading':
@@ -70,12 +69,34 @@ const parserBlock = (nodes: Content[], top = false, parent?: Content) => {
})
}
} else {
- const colorMatch = n.value.match(//)
- if (colorMatch) {
- colorTag = colorMatch[1]
- } else if (/^\s*<\/span>\s*$/.test(n.value)) {
- el = {text: colorText, highColor: colorTag}
- colorTag = ''
+ // date-be will be removed in a few versions
+ const htmlMatch = n.value.match(/<\/?(b|i|del|code|span|a).*?>/)
+ if (htmlMatch) {
+ const [str, tag] = htmlMatch
+ if (str.startsWith('') && htmlTag.length && htmlTag[htmlTag.length - 1].tag === tag) {
+ htmlTag.pop()
+ }
+ if (!str.startsWith('')) {
+ if (tag === 'span') {
+ const color = str.match(/style="color:\s*(#\w+)"/)
+ if (color) {
+ htmlTag.push({
+ tag: tag,
+ color: color[1]
+ })
+ }
+ } else if (tag === 'a') {
+ const url = str.match(/href="([\w:.\/_\-#\\]+)"/)
+ if (url) {
+ htmlTag.push({
+ tag: tag,
+ url: url[1]
+ })
+ }
+ } else {
+ htmlTag.push({tag: tag})
+ }
+ }
} else {
el = {text: n.value}
}
@@ -147,11 +168,18 @@ const parserBlock = (nodes: Content[], top = false, parent?: Content) => {
el = parseTable(n)
break
default:
- if (n.type === 'text' && colorTag) {
- colorText = n.value
+ if (n.type === 'text' && htmlTag.length) {
+ el = {text: n.value}
+ for (let t of htmlTag) {
+ if (t.tag === 'code') el.code = true
+ if (t.tag === 'i') el.italic = true
+ if (t.tag === 'b' || t.tag === 'strong') el.bold = true
+ if (t.tag === 'del') el.strikethrough = true
+ if (t.tag === 'span' && t.color) el.highColor = t.color
+ if (t.tag === 'a' && t.url) el.url = t.url
+ }
break
- }
- if (['strong', 'link', 'text', 'emphasis', 'delete', 'inlineCode'].includes(n.type)) {
+ } else if (['strong', 'link', 'text', 'emphasis', 'delete', 'inlineCode'].includes(n.type)) {
if (n.type === 'text') {
el = {text: n.value}
} else {
diff --git a/src/renderer/src/editor/tools/FloatBar.tsx b/src/renderer/src/editor/tools/FloatBar.tsx
index 3fbb6aca..1f77030f 100644
--- a/src/renderer/src/editor/tools/FloatBar.tsx
+++ b/src/renderer/src/editor/tools/FloatBar.tsx
@@ -205,7 +205,6 @@ export const FloatBar = observer(() => {
EditorUtils.highColor(store.editor)
} else {
EditorUtils.highColor(store.editor, localStorage.getItem('high-color') || '#10b981')
- EditorUtils.clearMarks(store.editor)
}
}}
>
@@ -255,7 +254,6 @@ export const FloatBar = observer(() => {
onClick={() => {
localStorage.setItem('high-color', c.color)
EditorUtils.highColor(store.editor, c.color)
- EditorUtils.clearMarks(store.editor, true)
setState({openSelectColor: false})
resize()
}}
diff --git a/src/renderer/src/editor/utils/editorUtils.ts b/src/renderer/src/editor/utils/editorUtils.ts
index c94bb2a2..41c3af5b 100644
--- a/src/renderer/src/editor/utils/editorUtils.ts
+++ b/src/renderer/src/editor/utils/editorUtils.ts
@@ -130,7 +130,7 @@ export class EditorUtils {
static toggleFormat(editor: Editor, format: any) {
const str = editor.selection ? Editor.string(editor, editor.selection) : ''
if (str) {
- EditorUtils.highColor(editor)
+ // EditorUtils.highColor(editor)
const isActive = EditorUtils.isFormatActive(editor, format)
Transforms.setNodes(
editor,
diff --git a/src/renderer/src/share b/src/renderer/src/share
index 167df658..916d0be1 160000
--- a/src/renderer/src/share
+++ b/src/renderer/src/share
@@ -1 +1 @@
-Subproject commit 167df658e9ec5249909d63c5f0b29dc85474d988
+Subproject commit 916d0be169f62df062522d3e577649a7aa09f53c
diff --git a/src/renderer/src/store/config.ts b/src/renderer/src/store/config.ts
index 33d3d57b..a968580e 100644
--- a/src/renderer/src/store/config.ts
+++ b/src/renderer/src/store/config.ts
@@ -40,13 +40,20 @@ class ConfigStore {
})
})
window.electron.ipcRenderer.on('changeConfig', action((e, key: any, value: any) => {
+ if (key === 'theme') {
+ this.setTheme(value, false)
+ }
this.config[key] = value
}))
}
- async setTheme(theme: typeof this.config.theme) {
+ async setTheme(theme: typeof this.config.theme, broadcast = true) {
+ if (theme === this.config.theme) return
const dark = await MainApi.getSystemDark()
runInAction(() => {
this.config.theme = theme
+ if (broadcast) {
+ MainApi.sendToAll('changeConfig', 'theme', theme)
+ }
if (theme === 'dark') {
document.documentElement.classList.add('dark')
this.config.dark = true
diff --git a/src/renderer/src/store/watch.ts b/src/renderer/src/store/watch.ts
index bea0386d..a4e47e5b 100644
--- a/src/renderer/src/store/watch.ts
+++ b/src/renderer/src/store/watch.ts
@@ -65,8 +65,7 @@ export class Watcher {
}
public onChange(e: 'remove' | 'update', path: string, node?: IFileItem) {
- const base = basename(path)
- if (path.split(sep).some(p => p.startsWith('.')) && base !== '.images') return
+ if (path.split(sep).some(p => p.startsWith('.') && p !== '.images')) return
const nodesMap = new Map(this.store.nodes.map(n => [n.filePath, n]))
const target = nodesMap.get(path)
const parent = nodesMap.get(join(path, '..'))!