diff --git a/emain/emain.ts b/emain/emain.ts index 28cf342c6..9bd7eb0df 100644 --- a/emain/emain.ts +++ b/emain/emain.ts @@ -525,6 +525,9 @@ function ensureBoundsAreVisible(bounds: electron.Rectangle): electron.Rectangle return bounds; } +electron.ipcMain.on("getIsDev", (event) => { + event.returnValue = isDev; +}); electron.ipcMain.on("getPlatform", (event, url) => { event.returnValue = unamePlatform; }); diff --git a/emain/preload.ts b/emain/preload.ts index 154dac0cb..875b5f0bd 100644 --- a/emain/preload.ts +++ b/emain/preload.ts @@ -4,6 +4,7 @@ const { contextBridge, ipcRenderer } = require("electron"); contextBridge.exposeInMainWorld("api", { + getIsDev: () => ipcRenderer.sendSync("getIsDev"), getPlatform: () => ipcRenderer.sendSync("getPlatform"), getCursorPoint: () => ipcRenderer.sendSync("getCursorPoint"), openNewWindow: () => ipcRenderer.send("openNewWindow"), diff --git a/frontend/app/block/block.tsx b/frontend/app/block/block.tsx index 87161804d..f3fffcd69 100644 --- a/frontend/app/block/block.tsx +++ b/frontend/app/block/block.tsx @@ -21,7 +21,9 @@ import clsx from "clsx"; import * as jotai from "jotai"; import * as React from "react"; +import { getLayoutStateAtomForTab } from "@/layout/lib/layoutAtom"; import { adaptFromReactOrNativeKeyEvent, checkKeyPressed } from "@/util/keyutil"; +import { isBlockMagnified } from "@/util/layoututil"; import "./block.less"; export interface LayoutComponentModel { @@ -263,6 +265,9 @@ const BlockFrame_Default_Component = ({ const preIconButton = util.useAtomValueSafe(viewModel.preIconButton); const endIconButtons = util.useAtomValueSafe(viewModel.endIconButtons); const customBg = util.useAtomValueSafe(viewModel.blockBg); + const tabId = globalStore.get(atoms.activeTabId); + const tabAtom = WOS.getWaveObjectAtom(WOS.makeORef("tab", tabId)); + const layoutTreeState = util.useAtomValueSafe(getLayoutStateAtomForTab(tabId, tabAtom)); if (preview) { isFocused = true; } @@ -302,6 +307,17 @@ const BlockFrame_Default_Component = ({ endIconsElem.push( ); + if (isBlockMagnified(layoutTreeState, blockId)) { + const magnifyDecl: HeaderIconButton = { + elemtype: "iconbutton", + icon: "regular@magnifying-glass-minus", + title: "Minimize", + click: layoutModel?.onMagnifyToggle, + }; + endIconsElem.push( + + ); + } const closeDecl: HeaderIconButton = { elemtype: "iconbutton", icon: "xmark-large", diff --git a/frontend/app/store/global.ts b/frontend/app/store/global.ts index 8e65383b5..d19ae3ed2 100644 --- a/frontend/app/store/global.ts +++ b/frontend/app/store/global.ts @@ -413,6 +413,15 @@ function getObjectId(obj: any): number { return objectIdWeakMap.get(obj); } +let cachedIsDev: boolean = null; + +function isDev() { + if (cachedIsDev == null) { + cachedIsDev = getApi().getIsDev(); + } + return cachedIsDev; +} + export { PLATFORM, WOS, @@ -428,6 +437,7 @@ export { globalWS, initGlobal, initWS, + isDev, sendWSCommand, setBlockFocus, setPlatform, diff --git a/frontend/app/tab/tabbar.less b/frontend/app/tab/tabbar.less index 2d9fadf0a..ef2d70bc8 100644 --- a/frontend/app/tab/tabbar.less +++ b/frontend/app/tab/tabbar.less @@ -28,6 +28,18 @@ height: 33px; } + .dev-label { + width: 26x; + height: 100%; + font-size: 26px; + user-select: none; + display: flex; + align-items: center; + justify-content: center; + margin-top: 2px; + color: var(--accent-color); + } + .add-tab-btn { width: 22px; height: 100%; diff --git a/frontend/app/tab/tabbar.tsx b/frontend/app/tab/tabbar.tsx index 62aa6a254..ee4af08d0 100644 --- a/frontend/app/tab/tabbar.tsx +++ b/frontend/app/tab/tabbar.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { WindowDrag } from "@/element/windowdrag"; -import { atoms } from "@/store/global"; +import { atoms, isDev } from "@/store/global"; import * as services from "@/store/services"; import { deleteLayoutStateAtomForTab } from "frontend/layout/lib/layoutAtom"; import { useAtomValue } from "jotai"; @@ -478,11 +478,19 @@ const TabBar = React.memo(({ workspace }: TabBarProps) => { }; const tabsWrapperWidth = tabIds.length * tabWidthRef.current; - console.log; + let devLabel: React.ReactNode = null; + if (isDev()) { + devLabel = ( +
+ +
+ ); + } return (
+ {devLabel}
{tabIds.map((tabId, index) => { diff --git a/frontend/types/custom.d.ts b/frontend/types/custom.d.ts index c7efbfce4..9c59e6066 100644 --- a/frontend/types/custom.d.ts +++ b/frontend/types/custom.d.ts @@ -30,6 +30,7 @@ declare global { }; type ElectronApi = { + getIsDev(): boolean; getCursorPoint: () => Electron.Point; getPlatform: () => NodeJS.Platform; diff --git a/frontend/util/layoututil.ts b/frontend/util/layoututil.ts index b118d6152..b5209e0cb 100644 --- a/frontend/util/layoututil.ts +++ b/frontend/util/layoututil.ts @@ -15,4 +15,16 @@ function findLeafIdFromBlockId(layoutTree: LayoutTreeState, block return null; } -export { findLeafIdFromBlockId }; +function isBlockMagnified(layoutTree: LayoutTreeState, blockId: string): boolean { + if (layoutTree?.leafs == null || layoutTree.magnifiedNodeId == null) { + return false; + } + for (let leaf of layoutTree.leafs) { + if (leaf.data.blockId == blockId) { + return layoutTree.magnifiedNodeId == leaf.id; + } + } + return false; +} + +export { findLeafIdFromBlockId, isBlockMagnified };