From 65f55b0dbedaffd437e825700edb58d1c0cec345 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sat, 23 Nov 2024 09:48:08 +0800 Subject: [PATCH] :art: Support HarmonyOS NEXT system https://github.com/siyuan-note/siyuan/issues/13184 --- app/src/config/about.ts | 6 +++--- app/src/config/index.ts | 4 ++-- app/src/dialog/processSystem.ts | 6 +++--- app/src/layout/topBar.ts | 4 ++-- app/src/menus/commonMenuItem.ts | 8 ++++---- app/src/menus/util.ts | 4 ++-- app/src/menus/workspace.ts | 6 +++--- app/src/mobile/menu/index.ts | 13 ++++++++++--- app/src/mobile/settings/about.ts | 6 +++--- app/src/protyle/breadcrumb/index.ts | 6 +++--- app/src/protyle/gutter/index.ts | 19 ++++++++----------- app/src/protyle/util/compatibility.ts | 12 ++++++++---- app/src/types/config.d.ts | 3 ++- app/src/util/assets.ts | 6 +++--- app/src/util/functions.ts | 4 ++-- 15 files changed, 58 insertions(+), 49 deletions(-) diff --git a/app/src/config/about.ts b/app/src/config/about.ts index 6f741abee78..0e68d0b0acf 100644 --- a/app/src/config/about.ts +++ b/app/src/config/about.ts @@ -7,7 +7,7 @@ import {fetchPost} from "../util/fetch"; import {setAccessAuthCode} from "./util/about"; import {exportLayout} from "../layout/util"; import {exitSiYuan, processSync} from "../dialog/processSystem"; -import {isInAndroid, isInIOS, isIPad, isMac, openByMobile, writeText} from "../protyle/util/compatibility"; +import {isInAndroid, isInHarmony, isInIOS, isIPad, isMac, openByMobile, writeText} from "../protyle/util/compatibility"; import {showMessage} from "../dialog/message"; import {Dialog} from "../dialog"; import {confirmDialog} from "../dialog/confirmDialog"; @@ -79,7 +79,7 @@ export const about = {
-
+
${window.siyuan.languages.about5} @@ -99,7 +99,7 @@ export const about = {
-
+
${window.siyuan.languages.about2}
${window.siyuan.languages.about3.replace("${port}", location.port)}
diff --git a/app/src/config/index.ts b/app/src/config/index.ts index 4c246f6ef8b..5662fbddd12 100644 --- a/app/src/config/index.ts +++ b/app/src/config/index.ts @@ -15,7 +15,7 @@ import {ai} from "./ai"; import {flashcard} from "./flashcard"; import {publish} from "./publish"; import {App} from "../index"; -import {isHuawei} from "../protyle/util/compatibility"; +import {isHuawei, isInHarmony} from "../protyle/util/compatibility"; import {Constants} from "../constants"; export const genItemPanel = (type: string, containerElement: Element, app: App) => { @@ -116,7 +116,7 @@ export const openSetting = (app: App) => {
  • ${window.siyuan.languages.assets}
  • ${window.siyuan.languages.export}
  • ${window.siyuan.languages.appearance}
  • -
  • ${window.siyuan.languages.bazaar}
  • +
  • ${window.siyuan.languages.bazaar}
  • ${window.siyuan.languages.search}
  • ${window.siyuan.languages.keymap}
  • ${window.siyuan.languages.account}
  • diff --git a/app/src/dialog/processSystem.ts b/app/src/dialog/processSystem.ts index 8091819139b..3699edf6990 100644 --- a/app/src/dialog/processSystem.ts +++ b/app/src/dialog/processSystem.ts @@ -23,7 +23,7 @@ import {setEmpty} from "../mobile/util/setEmpty"; import {hideAllElements, hideElements} from "../protyle/ui/hideElements"; import {App} from "../index"; import {saveScroll} from "../protyle/scroll/saveScroll"; -import {isInAndroid, isInIOS, setStorageVal} from "../protyle/util/compatibility"; +import {isInAndroid, isInHarmony, isInIOS, setStorageVal} from "../protyle/util/compatibility"; import {Plugin} from "../plugin"; const updateTitle = (rootID: string, tab: Tab, protyle?: IProtyle) => { @@ -301,7 +301,7 @@ export const exitSiYuan = async () => { /// #if !BROWSER ipcRenderer.send(Constants.SIYUAN_QUIT, location.port); /// #else - if (isInIOS() || isInAndroid()) { + if (isInIOS() || isInAndroid() || isInHarmony()) { window.location.href = "siyuan://api/system/exit"; } /// #endif @@ -341,7 +341,7 @@ export const exitSiYuan = async () => { /// #if !BROWSER ipcRenderer.send(Constants.SIYUAN_QUIT, location.port); /// #else - if (isInIOS() || isInAndroid()) { + if (isInIOS() || isInAndroid() || isInHarmony()) { window.location.href = "siyuan://api/system/exit"; } /// #endif diff --git a/app/src/layout/topBar.ts b/app/src/layout/topBar.ts index ec282847d5b..b54f477ffc0 100644 --- a/app/src/layout/topBar.ts +++ b/app/src/layout/topBar.ts @@ -1,5 +1,5 @@ import {getWorkspaceName} from "../util/noRelyPCFunction"; -import {isInAndroid, isInIOS, setStorageVal, updateHotkeyTip} from "../protyle/util/compatibility"; +import {isInAndroid, isInHarmony, isInIOS, setStorageVal, updateHotkeyTip} from "../protyle/util/compatibility"; import {exitSiYuan, processSync} from "../dialog/processSystem"; import {goBack, goForward} from "../util/backForward"; import {syncGuide} from "../sync/syncGuide"; @@ -54,7 +54,7 @@ export const initBar = (app: App) => {
    -
    +
    diff --git a/app/src/menus/commonMenuItem.ts b/app/src/menus/commonMenuItem.ts index fd1e3ea153c..9f9c2630786 100644 --- a/app/src/menus/commonMenuItem.ts +++ b/app/src/menus/commonMenuItem.ts @@ -6,7 +6,7 @@ import {getSearch, isMobile, isValidAttrName} from "../util/functions"; import {isLocalPath, movePathTo, moveToPath, pathPosix} from "../util/pathName"; import {MenuItem} from "./Menu"; import {saveExport} from "../protyle/export"; -import {isInAndroid, openByMobile, writeText} from "../protyle/util/compatibility"; +import {isInAndroid, isInHarmony, openByMobile} from "../protyle/util/compatibility"; import {fetchPost, fetchSyncPost} from "../util/fetch"; import {hideMessage, showMessage} from "../dialog/message"; import {Dialog} from "../dialog"; @@ -710,7 +710,7 @@ export const openMenu = (app: App, src: string, onlyMenu: boolean, showAccelerat const submenu = []; /// #if MOBILE submenu.push({ - label: isInAndroid() ? window.siyuan.languages.useDefault : window.siyuan.languages.useBrowserView, + label: isInAndroid() || isInHarmony() ? window.siyuan.languages.useDefault : window.siyuan.languages.useBrowserView, accelerator: showAccelerator ? window.siyuan.languages.click : "", click: () => { openByMobile(src); @@ -781,7 +781,7 @@ export const openMenu = (app: App, src: string, onlyMenu: boolean, showAccelerat }); /// #else submenu.push({ - label: isInAndroid() ? window.siyuan.languages.useDefault : window.siyuan.languages.useBrowserView, + label: isInAndroid() || isInHarmony() ? window.siyuan.languages.useDefault : window.siyuan.languages.useBrowserView, accelerator: showAccelerator ? window.siyuan.languages.click : "", click: () => { openByMobile(src); @@ -807,7 +807,7 @@ export const openMenu = (app: App, src: string, onlyMenu: boolean, showAccelerat }); /// #else submenu.push({ - label: isInAndroid() ? window.siyuan.languages.useDefault : window.siyuan.languages.useBrowserView, + label: isInAndroid() || isInHarmony() ? window.siyuan.languages.useDefault : window.siyuan.languages.useBrowserView, accelerator: showAccelerator ? window.siyuan.languages.click : "", click: () => { openByMobile(src); diff --git a/app/src/menus/util.ts b/app/src/menus/util.ts index 1065662879d..d1763d75cf2 100644 --- a/app/src/menus/util.ts +++ b/app/src/menus/util.ts @@ -9,7 +9,7 @@ import {Constants} from "../constants"; import {openNewWindowById} from "../window/openNewWindow"; import {MenuItem} from "./Menu"; import {App} from "../index"; -import {isInAndroid, openByMobile, updateHotkeyTip} from "../protyle/util/compatibility"; +import {isInAndroid, isInHarmony, openByMobile, updateHotkeyTip} from "../protyle/util/compatibility"; import {checkFold} from "../util/noRelyPCFunction"; export const exportAsset = (src: string) => { @@ -172,7 +172,7 @@ export const openEditorTab = (app: App, ids: string[], notebookId?: string, path }; export const copyPNGByLink = (link: string) => { - if (isInAndroid()) { + if (isInAndroid() || isInHarmony()) { window.JSAndroid.writeImageClipboard(link); return; } else { diff --git a/app/src/menus/workspace.ts b/app/src/menus/workspace.ts index a9b69f094b4..3ec84feae00 100644 --- a/app/src/menus/workspace.ts +++ b/app/src/menus/workspace.ts @@ -7,7 +7,7 @@ import {getOpenNotebookCount, originalPath, pathPosix, showFileInFolder} from ". import {fetchNewDailyNote, mountHelp, newDailyNote} from "../util/mount"; import {fetchPost} from "../util/fetch"; import {Constants} from "../constants"; -import {isInAndroid, isInIOS, isIPad, setStorageVal, writeText} from "../protyle/util/compatibility"; +import {isInAndroid, isInHarmony, isInIOS, isIPad, setStorageVal, writeText} from "../protyle/util/compatibility"; import {openCard} from "../card/openCard"; import {openSetting} from "../config"; import {getAllDocks} from "../layout/getAll"; @@ -317,7 +317,7 @@ export const workspaceMenu = (app: App, rect: DOMRect) => { }); }); /// #endif - if (!isBrowser() || isInIOS() || isInAndroid()) { + if (!isBrowser() || isInIOS() || isInAndroid() || isInHarmony()) { window.siyuan.menus.menu.append(new MenuItem({ id: "workspaceList", label: window.siyuan.languages.workspaceList, @@ -497,7 +497,7 @@ export const workspaceMenu = (app: App, rect: DOMRect) => { } }).element); /// #endif - if (isIPad() || isInAndroid() || !isBrowser()) { + if (isIPad() || isInAndroid() || isInHarmony() || !isBrowser()) { window.siyuan.menus.menu.append(new MenuItem({id: "separator_3", type: "separator"}).element); window.siyuan.menus.menu.append(new MenuItem({ id: "safeQuit", diff --git a/app/src/mobile/menu/index.ts b/app/src/mobile/menu/index.ts index 3d8c09c4fbf..da6684c27a1 100644 --- a/app/src/mobile/menu/index.ts +++ b/app/src/mobile/menu/index.ts @@ -16,7 +16,14 @@ import {initAbout} from "../settings/about"; import {getRecentDocs} from "./getRecentDocs"; import {initEditor} from "../settings/editor"; import {App} from "../../index"; -import {isDisabledFeature, isHuawei, isInAndroid, isInIOS, isIPhone} from "../../protyle/util/compatibility"; +import { + isDisabledFeature, + isHuawei, + isInAndroid, + isInHarmony, + isInIOS, + isIPhone +} from "../../protyle/util/compatibility"; import {newFile} from "../../util/newFile"; import {afterLoadPlugin} from "../../plugin/loader"; import {commandPanel} from "../../boot/globalEvent/command/panel"; @@ -88,8 +95,8 @@ export const initRightMenu = (app: App) => { -
    - -
    +
    ${window.siyuan.languages.about5}
    ${window.siyuan.languages.importConfTip}
    -
    +
    ${window.siyuan.languages.workspaceList}
    diff --git a/app/src/protyle/breadcrumb/index.ts b/app/src/protyle/breadcrumb/index.ts index bb8b1605bc3..13949e08b29 100644 --- a/app/src/protyle/breadcrumb/index.ts +++ b/app/src/protyle/breadcrumb/index.ts @@ -28,7 +28,7 @@ import {Menu} from "../../plugin/Menu"; import {getNoContainerElement} from "../wysiwyg/getBlock"; import {openTitleMenu} from "../header/openTitleMenu"; import {emitOpenMenu} from "../../plugin/EventBus"; -import {isInAndroid, isIPad, isMac, updateHotkeyTip} from "../util/compatibility"; +import {isInAndroid, isInHarmony, isIPad, isMac, updateHotkeyTip} from "../util/compatibility"; import {resize} from "../util/resize"; import {listIndent, listOutdent} from "../wysiwyg/list"; import {improveBreadcrumbAppearance} from "../wysiwyg/renderBacklink"; @@ -44,7 +44,7 @@ export class Breadcrumb { element.className = "protyle-breadcrumb"; let padHTML = ""; /// #if BROWSER && !MOBILE - if (isIPad() || isInAndroid()) { + if (isIPad() || isInAndroid() || isInHarmony()) { padHTML = ` @@ -295,7 +295,7 @@ ${padHTML} window.siyuan.menus.menu.remove(); }); window.siyuan.menus.menu.append(uploadMenu); - if (!isInAndroid()) { + if (!isInAndroid() && !isInHarmony()) { window.siyuan.menus.menu.append(new MenuItem({ id: this.mediaRecorder?.isRecording ? "endRecord" : "startRecord", current: this.mediaRecorder && this.mediaRecorder.isRecording, diff --git a/app/src/protyle/gutter/index.ts b/app/src/protyle/gutter/index.ts index 592ce3ba322..81579332c61 100644 --- a/app/src/protyle/gutter/index.ts +++ b/app/src/protyle/gutter/index.ts @@ -3,7 +3,8 @@ import { hasClosestByClassName, hasClosestByMatchTag, hasClosestByTag, - hasTopClosestByClassName, isInEmbedBlock + hasTopClosestByClassName, + isInEmbedBlock } from "../util/hasClosest"; import {getIconByType} from "../../editor/getIcon"; import {enterBack, iframeMenu, setFold, tableMenu, videoMenu, zoomOut} from "../../menus/protyle"; @@ -12,6 +13,7 @@ import {copySubMenu, openAttr, openFileAttr, openWechatNotify} from "../../menus import { copyPlainText, isInAndroid, + isInHarmony, isMac, isOnlyMeta, openByMobile, @@ -21,7 +23,8 @@ import { import { transaction, turnsIntoOneTransaction, - turnsIntoTransaction, turnsOneInto, + turnsIntoTransaction, + turnsOneInto, updateBatchTransaction, updateTransaction } from "../wysiwyg/transaction"; @@ -33,13 +36,7 @@ import {blockRender} from "../render/blockRender"; import {getContenteditableElement, getTopAloneElement, isNotEditBlock} from "../wysiwyg/getBlock"; import * as dayjs from "dayjs"; import {fetchPost} from "../../util/fetch"; -import { - cancelSB, - genEmptyElement, - getLangByType, - insertEmptyBlock, - jumpToParent, -} from "../../block/util"; +import {cancelSB, genEmptyElement, getLangByType, insertEmptyBlock, jumpToParent,} from "../../block/util"; import {countBlockWord} from "../../layout/status"; import {Constants} from "../../constants"; import {mathRender} from "../render/mathRender"; @@ -1656,7 +1653,7 @@ export class Gutter { label: `${window.siyuan.languages.copy} ${window.siyuan.languages.headings1}`, click() { fetchPost("/api/block/getHeadingChildrenDOM", {id}, (response) => { - if (isInAndroid()) { + if (isInAndroid() || isInHarmony()) { window.JSAndroid.writeHTMLClipboard(protyle.lute.BlockDOM2StdMd(response.data).trimEnd(), response.data + Constants.ZWSP); } else { writeText(response.data + Constants.ZWSP); @@ -1670,7 +1667,7 @@ export class Gutter { label: `${window.siyuan.languages.cut} ${window.siyuan.languages.headings1}`, click() { fetchPost("/api/block/getHeadingChildrenDOM", {id}, (response) => { - if (isInAndroid()) { + if (isInAndroid() || isInHarmony()) { window.JSAndroid.writeHTMLClipboard(protyle.lute.BlockDOM2StdMd(response.data).trimEnd(), response.data + Constants.ZWSP); } else { writeText(response.data + Constants.ZWSP); diff --git a/app/src/protyle/util/compatibility.ts b/app/src/protyle/util/compatibility.ts index e0f641a9af6..b00cd516303 100644 --- a/app/src/protyle/util/compatibility.ts +++ b/app/src/protyle/util/compatibility.ts @@ -21,7 +21,7 @@ export const openByMobile = (uri: string) => { window.webkit.messageHandlers.openLink.postMessage("https://" + uri); } } - } else if (isInAndroid()) { + } else if (isInAndroid() || isInHarmony()) { window.JSAndroid.openExternal(uri); } else { window.open(uri); @@ -29,7 +29,7 @@ export const openByMobile = (uri: string) => { }; export const readText = () => { - if (isInAndroid()) { + if (isInAndroid() || isInHarmony()) { return window.JSAndroid.readClipboard(); } return navigator.clipboard.readText(); @@ -42,7 +42,7 @@ export const writeText = (text: string) => { } try { // navigator.clipboard.writeText 抛出异常不进入 catch,这里需要先处理移动端复制 - if (isInAndroid()) { + if (isInAndroid() || isInHarmony()) { window.JSAndroid.writeClipboard(text); return; } @@ -54,7 +54,7 @@ export const writeText = (text: string) => { } catch (e) { if (isInIOS()) { window.webkit.messageHandlers.setClipboard.postMessage(text); - } else if (isInAndroid()) { + } else if (isInAndroid() || isInHarmony()) { window.JSAndroid.writeClipboard(text); } else { const textElement = document.createElement("textarea"); @@ -136,6 +136,10 @@ export const isInIOS = () => { return window.siyuan.config.system.container === "ios" && window.webkit?.messageHandlers; }; +export const isInHarmony = () => { + return window.siyuan.config.system.container === "harmony"; +} + // Mac,Windows 快捷键展示 export const updateHotkeyTip = (hotkey: string) => { if (isMac()) { diff --git a/app/src/types/config.d.ts b/app/src/types/config.d.ts index 421be973c33..7ffb602a203 100644 --- a/app/src/types/config.d.ts +++ b/app/src/types/config.d.ts @@ -1540,9 +1540,10 @@ declare namespace Config { * - `docker`: Docker container * - `android`: Android device * - `ios`: iOS device + * - `harmony`: HarmonyOS device * - `std`: Desktop Electron environment */ - export type TSystemContainer = "docker" | "android" | "ios" | "std"; + export type TSystemContainer = "docker" | "android" | "ios" | "harmony" | "std"; /** * SiYuan Network proxy configuration diff --git a/app/src/util/assets.ts b/app/src/util/assets.ts index d2ffad69437..50bd82d6b1a 100644 --- a/app/src/util/assets.ts +++ b/app/src/util/assets.ts @@ -7,7 +7,7 @@ import {exportLayout} from "../layout/util"; /// #endif import {fetchPost} from "./fetch"; import {appearance} from "../config/appearance"; -import {isInAndroid, isInIOS} from "../protyle/util/compatibility"; +import {isInAndroid, isInHarmony, isInIOS} from "../protyle/util/compatibility"; const loadThirdIcon = (iconURL: string, data: Config.IAppearance) => { addScript(iconURL, "iconDefaultScript").then(() => { @@ -329,7 +329,7 @@ const rgba2hex = (rgba: string) => { }; const updateMobileTheme = (OSTheme: string) => { - if (isInIOS() || isInAndroid()) { + if (isInIOS() || isInAndroid() || isInHarmony()) { setTimeout(() => { const backgroundColor = rgba2hex(getComputedStyle(document.body).getPropertyValue("--b3-theme-background").trim()); let mode = window.siyuan.config.appearance.mode; @@ -342,7 +342,7 @@ const updateMobileTheme = (OSTheme: string) => { } if (isInIOS()) { window.webkit.messageHandlers.changeStatusBar.postMessage((backgroundColor || (mode === 0 ? "#fff" : "#1e1e1e")) + " " + mode); - } else if (isInAndroid()) { + } else if (isInAndroid() || isInHarmony()) { window.JSAndroid.changeStatusBarColor(backgroundColor, mode); } }, 500); // 移动端需要加载完才可以获取到颜色 diff --git a/app/src/util/functions.ts b/app/src/util/functions.ts index 555a8418b8d..843e28ba951 100644 --- a/app/src/util/functions.ts +++ b/app/src/util/functions.ts @@ -2,9 +2,9 @@ export const isMobile = () => { return document.getElementById("sidebar") ? true : false; }; -// "windows" | "linux" | "darwin" | "docker" | "android" | "ios" +// "windows" | "linux" | "darwin" | "docker" | "android" | "ios" | "harmony" export const getBackend = () => { - if (["docker", "ios", "android"].includes(window.siyuan.config.system.container)) { + if (["docker", "ios", "android", "harmony"].includes(window.siyuan.config.system.container)) { return window.siyuan.config.system.container; } else { return window.siyuan.config.system.os;