import { useEffect, useState } from "react"; import type { ImageStudioApp } from "@app/app"; import { BottomControlsIsland } from "./BottomControlsIsland"; import { CanvasViewport } from "./CanvasViewport"; import { LayersSheet } from "./LayersSheet"; import { ToolOverlay } from "./ToolOverlay"; import { labelForTool } from "./toolLabels"; import { resolveTransformTargetBounds, selectedTransformTarget } from "@editor/transform-targets"; import { handleDeleteSelectionKey, handleHistoryKey, keybindEventFromKeyboardEvent } from "@input/index"; import { useAppState } from "./useAppState"; import { useImageImport } from "./useImageImport"; import { useViewportActivityIsland } from "./useViewportActivityIsland"; import "./index.css"; export type AppProps = { app: ImageStudioApp; }; export function App({ app }: AppProps) { const state = useAppState(app.store); const zoomPercent = Math.round(state.editor.viewport.zoom * 100); const viewportActivityIsland = useViewportActivityIsland(state.editor.viewport); const imageImport = useImageImport(app.store); const [layersOpen, setLayersOpen] = useState(false); const transformTarget = state.editor.transformSession?.target ?? selectedTransformTarget(state.document, state.editor.selection); useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { const target = event.target; const editableTarget = target instanceof HTMLElement && (target.isContentEditable || target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLSelectElement); if (editableTarget) return; const historyConsumed = handleHistoryKey({ event: keybindEventFromKeyboardEvent(event), dispatch: app.store.dispatch }); if (historyConsumed) { event.preventDefault(); return; } if (event.altKey || event.ctrlKey || event.metaKey) return; if (event.key.toLowerCase() === "l") { setLayersOpen(true); event.preventDefault(); return; } const consumed = handleDeleteSelectionKey({ event: keybindEventFromKeyboardEvent(event), selection: app.store.getState().editor.selection, dispatch: app.store.dispatch, }); if (consumed) event.preventDefault(); }; window.addEventListener("keydown", handleKeyDown); return () => window.removeEventListener("keydown", handleKeyDown); }, [app.store]); const transformBounds = transformTarget ? resolveTransformTargetBounds(state.document, transformTarget) : undefined; return (
{imageImport.input}

Image Studio

{state.document.name} · {labelForTool(state.editor.tools.activeTool)} · {zoomPercent}% · {state.editor.viewport.size.w}× {state.editor.viewport.size.h}
setLayersOpen(false)} />
); } export default App;