diff --git a/app/src/assets/scss/mobile.scss b/app/src/assets/scss/mobile.scss index 59884d169..bbf1e47f3 100644 --- a/app/src/assets/scss/mobile.scss +++ b/app/src/assets/scss/mobile.scss @@ -322,10 +322,7 @@ &__slash { &-title { - font-size: 12px; - color: var(--b3-theme-on-surface); - line-height: 12px; - padding: 8px; + height: 24px; } &-block { @@ -340,6 +337,7 @@ display: flex; align-items: center; margin-right: 8px; + position: relative; box-shadow: inset 0 0 0 .4px var(--b3-theme-on-surface-light); } @@ -349,12 +347,19 @@ } &-icon { - height: 24px; - width: 24px; + height: 20px; + width: 20px; padding: 6px; flex-shrink: 0; - margin: 6px 4px; - color: var(--b3-theme-on-surface); + margin: 8px 0 8px 8px; + font-size: 20px; + text-align: center; + line-height: 20px; + } + + &-text { + line-height: 48px; + margin-left: 8px; } } } diff --git a/app/src/mobile/util/keyboardToolbar.ts b/app/src/mobile/util/keyboardToolbar.ts index 526fd8157..b5a2da715 100644 --- a/app/src/mobile/util/keyboardToolbar.ts +++ b/app/src/mobile/util/keyboardToolbar.ts @@ -7,9 +7,15 @@ import {focusByRange, getSelectionPosition} from "../../protyle/util/selection"; let renderKeyboardToolbarTimeout: number; let showKeyboardToolbarUtil = false; -const getSlashItem = (value: string, icon: string, text:string) => { - return `
- +const getSlashItem = (value: string, icon: string, text: string, focus = "false") => { + let iconHTML + if (icon && icon.startsWith("icon")) { + iconHTML = `` + } else { + iconHTML = icon; + } + return `
+ ${iconHTML} ${text}
` } @@ -18,27 +24,123 @@ const renderSlashMenu = (protyle: IProtyle, toolbarElement: Element) => { protyle.hint.splitChar = "/"; protyle.hint.lastIndex = -1; const utilElement = toolbarElement.querySelector(".keyboard__util") as HTMLElement; - utilElement.innerHTML = `
-${window.siyuan.languages.general} -
+ utilElement.innerHTML = `
${getSlashItem(Constants.ZWSP, "iconMarkdown", window.siyuan.languages.template)} ${getSlashItem(Constants.ZWSP + 1, "iconBoth", window.siyuan.languages.widget)}
${getSlashItem(Constants.ZWSP + 2, "iconImage", window.siyuan.languages.assets)} - ${getSlashItem(Constants.ZWSP + 3, "iconRef", window.siyuan.languages.blockRef)} + ${getSlashItem("((", "iconRef", window.siyuan.languages.blockRef, "true")}
- ${getSlashItem("{{", "iconSQL", window.siyuan.languages.blockEmbed)} + ${getSlashItem("{{", "iconSQL", window.siyuan.languages.blockEmbed, "true")} ${getSlashItem(Constants.ZWSP + 5, "iconSparkles", "AI Chat")}
${getSlashItem(Constants.ZWSP + 4, "iconFile", window.siyuan.languages.newFile)}
-
-common +
+
+ ${getSlashItem("# " + Lute.Caret, "iconH1", window.siyuan.languages.heading1, "true")} + ${getSlashItem("## " + Lute.Caret, "iconH2", window.siyuan.languages.heading2, "true")} +
+
+ ${getSlashItem("### " + Lute.Caret, "iconH3", window.siyuan.languages.heading3, "true")} + ${getSlashItem("#### " + Lute.Caret, "iconH4", window.siyuan.languages.heading4, "true")} +
+
+ ${getSlashItem("##### " + Lute.Caret, "iconH5", window.siyuan.languages.heading5, "true")} + ${getSlashItem("###### " + Lute.Caret, "iconH6", window.siyuan.languages.heading6, "true")} +
+
+ ${getSlashItem("* " + Lute.Caret, "iconList", window.siyuan.languages.list, "true")} + ${getSlashItem("1. " + Lute.Caret, "iconOrderedList", window.siyuan.languages["ordered-list"], "true")} +
+
+ ${getSlashItem("* [ ] " + Lute.Caret, "iconCheck", window.siyuan.languages.check, "true")} + ${getSlashItem("> " + Lute.Caret, "iconQuote", window.siyuan.languages.quote, "true")} +
+
+ ${getSlashItem("```", "iconCode", window.siyuan.languages.code, "true")} + ${getSlashItem(`| ${Lute.Caret} | | |\n| --- | --- | --- |\n| | | |\n| | | |`, "iconTable", window.siyuan.languages.table, "true")} +
+
+ ${getSlashItem("---", "iconLine", window.siyuan.languages.line, "true")} + ${getSlashItem("$$", "iconMath", window.siyuan.languages.math)} +
+
+ ${getSlashItem("
", "iconHTML5", "HTML")} +
+
+
+
+ ${getSlashItem("emoji", "iconEmoji", window.siyuan.languages.emoji, "true")} + ${getSlashItem("a", "iconLink", window.siyuan.languages.link)} +
+
+ ${getSlashItem("strong", "iconBold", window.siyuan.languages.bold, "true")} + ${getSlashItem("em", "iconItalic", window.siyuan.languages.italic, "true")} +
+
+ ${getSlashItem("u", "iconUnderline", window.siyuan.languages.underline, "true")} + ${getSlashItem("s", "iconStrike", window.siyuan.languages.strike, "true")} +
+
+ ${getSlashItem("mark", "iconMark", window.siyuan.languages.mark, "true")} + ${getSlashItem("sup", "iconSup", window.siyuan.languages.sup, "true")} +
+
+ ${getSlashItem("sub", "iconSub", window.siyuan.languages.sub, "true")} + ${getSlashItem("tag", "iconTags", window.siyuan.languages.tag, "true")} +
+
+ ${getSlashItem("code", "iconInlineCode", window.siyuan.languages["inline-code"], "true")} + ${getSlashItem("inline-math", "iconMath", window.siyuan.languages["inline-math"])} +
+
+
+ ${getSlashItem(Constants.ZWSP + 3, "iconDownload", window.siyuan.languages.insertAsset + '', "true")} + ${getSlashItem('', "iconLanguage", window.siyuan.languages.insertIframeURL, "true")} +
+
+ ${getSlashItem("![]()", "iconImage", window.siyuan.languages.insertImgURL, "true")} + ${getSlashItem('', "iconVideo", window.siyuan.languages.insertVideoURL, "true")} +
+
+ ${getSlashItem('', "iconRecord", window.siyuan.languages.insertAudioURL, "true")} +
+
+
+
+ ${getSlashItem("```abc\n```", "", window.siyuan.languages.staff, "true")} + ${getSlashItem("```echarts\n```", "", window.siyuan.languages.chart, "true")} +
+
+ ${getSlashItem("```flowchart\n```", "", "Flow Chart", "true")} + ${getSlashItem("```graphviz\n```", "", "Graph", "true")} +
+
+ ${getSlashItem("```mermaid\n```", "", "Mermaid", "true")} + ${getSlashItem("```mindmap\n```", "", window.siyuan.languages.mindmap, "true")} +
+
+ ${getSlashItem("```plantuml\n```", "", "UML", "true")} +
+
+
+
+ ${getSlashItem(`style${Constants.ZWSP}color: var(--b3-card-info-color);background-color: var(--b3-card-info-background);`, '
A
', window.siyuan.languages.infoStyle, "true")} + ${getSlashItem(`style${Constants.ZWSP}color: var(--b3-card-success-color);background-color: var(--b3-card-success-background);`, '
A
', window.siyuan.languages.successStyle, "true")} +
+
+ ${getSlashItem(`style${Constants.ZWSP}color: var(--b3-card-warning-color);background-color: var(--b3-card-warning-background);`, '
A
', window.siyuan.languages.warningStyle, "true")} + ${getSlashItem(`style${Constants.ZWSP}color: var(--b3-card-error-color);background-color: var(--b3-card-error-background);`, '
A
', window.siyuan.languages.errorStyle, "true")} +
+
+ ${getSlashItem(`style${Constants.ZWSP}`, '
A
', window.siyuan.languages.clearFontStyle, "true")} +
`; protyle.hint.bindUploadEvent(protyle, utilElement); }; @@ -231,10 +333,15 @@ export const initKeyboardToolbar = () => { const slashBtnElement = hasClosestByClassName(event.target as HTMLElement, "keyboard__slash-item"); const protyle = window.siyuan.mobile.editor.protyle; if (slashBtnElement) { - protyle.hint.fill(decodeURIComponent(slashBtnElement.getAttribute("data-value")), protyle); - focusByRange(protyle.toolbar.range); - event.preventDefault(); - event.stopPropagation(); + const dataValue = decodeURIComponent(slashBtnElement.getAttribute("data-value")) + protyle.hint.fill(dataValue, protyle, false); // 点击后 range 会改变 + if (dataValue !== Constants.ZWSP + 3) { + event.preventDefault(); + event.stopPropagation(); + } + if (slashBtnElement.getAttribute("data-focus") === "true") { + focusByRange(protyle.toolbar.range); + } return; } const buttonElement = hasClosestByMatchTag(target, "BUTTON"); diff --git a/app/src/protyle/hint/index.ts b/app/src/protyle/hint/index.ts index 7ba9ae9ca..a4b14fd50 100644 --- a/app/src/protyle/hint/index.ts +++ b/app/src/protyle/hint/index.ts @@ -393,9 +393,11 @@ ${unicode2Emoji(emoji.unicode, true)}`; } } - public fill(value: string, protyle: IProtyle) { + public fill(value: string, protyle: IProtyle, updateRange = true) { hideElements(["hint", "toolbar"], protyle); - protyle.toolbar.range = getEditorRange(protyle.wysiwyg.element); + if (updateRange) { + protyle.toolbar.range = getEditorRange(protyle.wysiwyg.element); + } const range = protyle.toolbar.range; let nodeElement = hasClosestBlock(protyle.toolbar.range.startContainer) as HTMLElement; if (!nodeElement) {