diff --git a/app/src/assets/scss/base.scss b/app/src/assets/scss/base.scss index a96b9af7b..1274a0a58 100644 --- a/app/src/assets/scss/base.scss +++ b/app/src/assets/scss/base.scss @@ -55,7 +55,10 @@ ctrl+p 搜索: 202 .b3-menu: 210 // 需小于 .side-panel -#transactionTip & #keyboardToolbar: 212 +#transactionTip: 212 + +// 需大于 mobile .status +.keyboard: 222 // 需小于 .b3-dialog 关于中的锁屏密码设置 .side-panel: 220 diff --git a/app/src/assets/scss/mobile.scss b/app/src/assets/scss/mobile.scss index 63a5352ba..89977424d 100644 --- a/app/src/assets/scss/mobile.scss +++ b/app/src/assets/scss/mobile.scss @@ -97,9 +97,7 @@ &__title { flex: 1; - padding: 4px 8px; - border: 1px solid transparent; - background-color: transparent; + box-shadow: none; } &__search { @@ -228,10 +226,11 @@ box-sizing: border-box; height: 42px; background: var(--b3-theme-background); - z-index: 212; + z-index: 222; display: flex; border-top: 1px solid var(--b3-theme-surface-lighter); overflow: hidden; + flex-direction: column; &__dynamic { overflow: auto; @@ -242,14 +241,23 @@ } } + &__bar { + border-bottom: 1px solid var(--b3-theme-surface-lighter); + } + &__split { width: 1px; height: 28px; - background: var(--b3-border-color); + background-color: var(--b3-theme-surface-lighter); align-self: center; flex-shrink: 0; } + &__util { + flex: 1; + overflow: auto; + } + button { background: transparent; padding: 0; @@ -333,8 +341,6 @@ } .b3-menu { - width: 100%; - &__accelerator { display: none; } diff --git a/app/src/assets/template/mobile/index.tpl b/app/src/assets/template/mobile/index.tpl index 2078e09f5..633db86b1 100644 --- a/app/src/assets/template/mobile/index.tpl +++ b/app/src/assets/template/mobile/index.tpl @@ -2,7 +2,7 @@ - + diff --git a/app/src/mobile/util/keyboardToolbar.ts b/app/src/mobile/util/keyboardToolbar.ts index 91b4cae66..d9b324615 100644 --- a/app/src/mobile/util/keyboardToolbar.ts +++ b/app/src/mobile/util/keyboardToolbar.ts @@ -6,11 +6,13 @@ import {focusByRange, getSelectionPosition} from "../../protyle/util/selection"; import {removeBlock} from "../../protyle/wysiwyg/remove"; import {hintSlash} from "../../protyle/hint/extend"; -export const showKeyboardToolbar = (bottom = 0) => { +export const showKeyboardToolbar = (bottom = 0, height: number) => { if (getSelection().rangeCount === 0 || window.siyuan.config.editor.readOnly || window.siyuan.config.readonly) { return; } const toolbarElement = document.getElementById("keyboardToolbar"); + toolbarElement.setAttribute("data-keyboardheight", height.toString()) + hideKeyboardToolbarUtil(); if (!toolbarElement.classList.contains("fn__none")) { return; } @@ -37,12 +39,19 @@ export const showKeyboardToolbar = (bottom = 0) => { }; let renderKeyboardToolbarTimeout: number; +let showKeyboardToolbarUtil = false; export const renderKeyboardToolbar = () => { clearTimeout(renderKeyboardToolbarTimeout); renderKeyboardToolbarTimeout = window.setTimeout(() => { if (getSelection().rangeCount === 0 || window.siyuan.config.editor.readOnly || window.siyuan.config.readonly) { return; } + hideKeyboardToolbarUtil(); + if (window.innerHeight + 200 > ((window.orientation === 90 || window.orientation === -90) ? screen.width : screen.height)) { + hideKeyboardToolbar(); + return; + } + const dynamicElements = document.querySelectorAll("#keyboardToolbar .keyboard__dynamic"); const range = getSelection().getRangeAt(0); const selectText = range.toString(); @@ -85,6 +94,9 @@ export const renderKeyboardToolbar = () => { }; export const hideKeyboardToolbar = () => { + if (showKeyboardToolbarUtil) { + return; + } const toolbarElement = document.getElementById("keyboardToolbar"); toolbarElement.classList.add("fn__none"); }; @@ -93,52 +105,72 @@ export const hideKeyboard = () => { (document.activeElement as HTMLElement).blur(); }; +const renderKeyboardToolbarUtil = () => { + const toolbarElement = document.getElementById("keyboardToolbar"); + const keyboardHeight = (parseInt(toolbarElement.getAttribute("data-keyboardheight")) + 42) + "px" + toolbarElement.style.height = keyboardHeight + window.siyuan.mobile.editor.protyle.element.style.marginBottom = keyboardHeight + window.siyuan.menus.menu.remove(); + showKeyboardToolbarUtil = true; + setTimeout(() => { + showKeyboardToolbarUtil = false + }, 1000) +} + +const hideKeyboardToolbarUtil = () => { + document.getElementById("keyboardToolbar").style.height = "" + window.siyuan.mobile.editor.protyle.element.style.marginBottom = "" +} + export const initKeyboardToolbar = () => { document.addEventListener("selectionchange", () => { renderKeyboardToolbar(); }, false); const toolbarElement = document.getElementById("keyboardToolbar"); - toolbarElement.innerHTML = `
-
- - - - - - - - - - - - - - -
-
- - - - - - - - - - - - - - - - - - + toolbarElement.innerHTML = `
+
+
+ + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + +
+ +
- -`; +
`; toolbarElement.addEventListener("click", (event) => { const target = event.target as HTMLElement; const buttonElement = hasClosestByMatchTag(target, "BUTTON"); @@ -150,6 +182,7 @@ export const initKeyboardToolbar = () => { const type = buttonElement.getAttribute("data-type"); if (type === "done") { hideKeyboard(); + hideKeyboardToolbar(); return; } if (window.siyuan.config.readonly || window.siyuan.config.editor.readOnly || !window.siyuan.mobile.editor) { @@ -203,8 +236,16 @@ export const initKeyboardToolbar = () => { } else if (type === "add") { protyle.hint.splitChar = "/"; protyle.hint.lastIndex = -1; - protyle.hint.genHTML(hintSlash("", protyle), protyle); - focusByRange(range); + const utilElement = toolbarElement.querySelector(".keyboard__util") as HTMLElement + utilElement.innerHTML = protyle.hint.getHTMLByData(hintSlash("", protyle), false) + protyle.hint.bindUploadEvent(protyle, utilElement); + utilElement.addEventListener("click", (event) => { + const btnElement = hasClosestByClassName(event.target as HTMLElement, "b3-list-item"); + if (btnElement) { + protyle.hint.fill(decodeURIComponent(btnElement.getAttribute("data-value")), protyle); + } + }) + renderKeyboardToolbarUtil(); return; } else if (type === "more") { protyle.breadcrumb.showMenu(protyle, { @@ -215,7 +256,7 @@ export const initKeyboardToolbar = () => { return; } else if (type === "block") { protyle.gutter.renderMenu(protyle, nodeElement); - window.siyuan.menus.menu.popup({x: 0, y:0}, true); + window.siyuan.menus.menu.popup({x: 0, y: 0}, true); focusByRange(range); return; } else if (type === "outdent") { diff --git a/app/src/protyle/hint/index.ts b/app/src/protyle/hint/index.ts index 4097e9fc7..319955bcf 100644 --- a/app/src/protyle/hint/index.ts +++ b/app/src/protyle/hint/index.ts @@ -202,14 +202,25 @@ ${unicode2Emoji(emoji.unicode, true)}`; } } - public genHTML(data: IHintData[], protyle: IProtyle, hide = false, hasSearch = false) { - if (data.length === 0) { - if (!this.element.querySelector(".fn__loading") || hide) { - this.element.classList.add("fn__none"); - } - return; + public bindUploadEvent (protyle:IProtyle, element:HTMLElement) { + const uploadElement = element.querySelector('input[type="file"]'); + if (uploadElement) { + uploadElement.addEventListener("change", (event: InputEvent & { target: HTMLInputElement }) => { + if (event.target.files.length === 0) { + return; + } + const range = getEditorRange(protyle.wysiwyg.element); + if (this.lastIndex > -1) { + range.setStart(range.startContainer, this.lastIndex); + } + range.deleteContents(); + uploadFiles(protyle, event.target.files, event.target); + hideElements(["hint", "toolbar"], protyle); + }); } + } + public getHTMLByData(data: IHintData[], hasSearch = false) { let hintsHTML = ""; if (hasSearch) { hintsHTML = '
'; @@ -234,7 +245,18 @@ ${unicode2Emoji(emoji.unicode, true)}`; if (hasSearch) { hintsHTML = hintsHTML + "
"; } - this.element.innerHTML = hintsHTML; + return hintsHTML + } + + public genHTML(data: IHintData[], protyle: IProtyle, hide = false, hasSearch = false) { + if (data.length === 0) { + if (!this.element.querySelector(".fn__loading") || hide) { + this.element.classList.add("fn__none"); + } + return; + } + + this.element.innerHTML = this.getHTMLByData(data, hasSearch); this.element.classList.remove("fn__none"); // https://github.com/siyuan-note/siyuan/issues/4575 if (data[0].filter) { @@ -246,21 +268,7 @@ ${unicode2Emoji(emoji.unicode, true)}`; const textareaPosition = getSelectionPosition(protyle.wysiwyg.element); setPosition(this.element, textareaPosition.left, textareaPosition.top + 26, 30); this.element.scrollTop = 0; - const uploadElement = this.element.querySelector('input[type="file"]'); - if (uploadElement) { - uploadElement.addEventListener("change", (event: InputEvent & { target: HTMLInputElement }) => { - if (event.target.files.length === 0) { - return; - } - const range = getEditorRange(protyle.wysiwyg.element); - if (this.lastIndex > -1) { - range.setStart(range.startContainer, this.lastIndex); - } - range.deleteContents(); - uploadFiles(protyle, event.target.files, event.target); - hideElements(["hint", "toolbar"], protyle); - }); - } + this.bindUploadEvent(protyle, this.element); if (hasSearch) { const searchElement = this.element.querySelector("input.b3-text-field") as HTMLInputElement; const oldValue = this.element.querySelector("mark")?.textContent || ""; diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts index 10cc8a085..d75e54dc9 100644 --- a/app/src/types/index.d.ts +++ b/app/src/types/index.d.ts @@ -49,7 +49,7 @@ interface Window { goBack(): void - showKeyboardToolbar(bottom?: number): void + showKeyboardToolbar(bottom: number, height: number): void hideKeyboardToolbar(): void