diff --git a/package.json b/package.json index b18a170..345ea28 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codeslide.net", - "version": "0.3.1", + "version": "0.3.2", "private": true, "dependencies": { "@ant-design/icons": "^4.8.1", diff --git a/src/App.tsx b/src/App.tsx index 4999714..2b40e74 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -25,6 +25,7 @@ export const App = () => { const selectedItem = useStore(getSelectedShape); const selectedSet = useStore(getSelectedItems); const sidebarWidth = useStore(s => s.ui.sidebarSize); + const footerHeight = useStore(s => s.ui.footerSize); const applicationMode = useStore(s => s.ui.selectedMode); const margin = { @@ -85,7 +86,9 @@ export const App = () => { - + + + { - + diff --git a/src/const/vogues.ts b/src/const/vogues.ts index 794a70e..be09e3b 100644 --- a/src/const/vogues.ts +++ b/src/const/vogues.ts @@ -12,6 +12,7 @@ export const vogues = { common: { canvasWidth: 1280, canvasHeight: 720, + close: 0, dragSize: 12, editorMargin: 13, editorPad: 10, @@ -23,7 +24,6 @@ export const vogues = { maxImgSize: 300, shapeWidth: 38, sidebarCode: 600, - sidebarClose: 0, sidebarShape: 38, selectionThickness: 1, previewWidth: 128, @@ -40,6 +40,7 @@ export const vogues = { selectionLock: '#f00', selectionStroke: '#080', transparent: 'rgba(0, 0, 0, 0)', + white: '#fff', }, option: { strokeThickness: [0, 1, 2, 3, 4, 6, 8, 10], diff --git a/src/icons/icon.tsx b/src/icons/icon.tsx index a4a160f..6b5a964 100644 --- a/src/icons/icon.tsx +++ b/src/icons/icon.tsx @@ -164,6 +164,10 @@ export const TriangleIcon = () => ( ); +export const PageIcon = () => ( + +) + export const ParagraphIcon = () => ( ); diff --git a/src/style/_common.scss b/src/style/_common.scss index 5be7291..10ec540 100644 --- a/src/style/_common.scss +++ b/src/style/_common.scss @@ -342,8 +342,10 @@ header { &-segment { gap: 3px; - border-radius: 14px; + border-radius: 20px; padding: 3px 4px; + display: inline-flex; + background-color: $color-background; } } diff --git a/src/wireframes/components/AnimationView.tsx b/src/wireframes/components/AnimationView.tsx index 969a4d8..6010757 100644 --- a/src/wireframes/components/AnimationView.tsx +++ b/src/wireframes/components/AnimationView.tsx @@ -21,14 +21,19 @@ export const AnimationView = () => { const dispatch = useDispatch(); const diagram = useStore(getDiagram); const animation = useStore(s => s.ui.selectedAnimation); + const isFooter = useStore(s => s.ui.footerSize) == vogues.common.previewHeight ? 1 : 0; - const viewPadd = vogues.common.editorMargin * 2 + 10 * 3 + vogues.common.headerHeight + vogues.common.shapeWidth + (vogues.common.previewHeight + vogues.common.editorMargin + vogues.common.previewPadBot) + vogues.common.selectionThickness * 4; + const viewPadd = vogues.common.editorMargin * 2 + 10 * 3 + vogues.common.headerHeight + vogues.common.shapeWidth + isFooter * (vogues.common.previewHeight + vogues.common.editorMargin + vogues.common.previewPadBot) + vogues.common.selectionThickness * 4; const [viewHeight, setViewHeight] = useState(window.innerHeight - viewPadd); useEffect(() => { window.addEventListener('resize', () => setViewHeight(window.innerHeight - viewPadd)); }, []); + useEffect(() => { + setViewHeight(window.innerHeight - viewPadd); + }, [isFooter]); + if (!diagram) { return null; } diff --git a/src/wireframes/components/headers/ModeHeader.tsx b/src/wireframes/components/headers/ModeHeader.tsx index 414cd05..9c0b561 100644 --- a/src/wireframes/components/headers/ModeHeader.tsx +++ b/src/wireframes/components/headers/ModeHeader.tsx @@ -6,37 +6,56 @@ * Copyright (c) Do Duc Quan. All rights reserved. */ -import { Segmented } from "antd"; +import { Button, Tooltip } from "antd"; import * as React from "react"; -import { setMode, setSidebarSize } from "@app/wireframes/model"; -import { AnimationIcon, DesignIcon, IconOutline } from "@app/icons/icon"; +import { setFooterSize, setMode, setSidebarSize, useStore } from "@app/wireframes/model"; +import { AnimationIcon, PageIcon, IconOutline } from "@app/icons/icon"; import { useDispatch } from "react-redux"; -import { SegmentedValue } from "antd/es/segmented"; import { vogues } from "@app/const"; export const ModeHeader = React.memo(() => { const dispatch = useDispatch(); + const isAnimationOn = useStore(s => s.ui.sidebarSize) !== vogues.common.close; + const isPageOn = useStore(s => s.ui.footerSize) !== vogues.common.close; - const modeMenu = [ - { value: 'design', icon: }, - { value: 'animation', icon: }, - ]; + const togglePagePanel = () => { + if (isPageOn) { + dispatch(setFooterSize(vogues.common.close)); + } else { + dispatch(setFooterSize(vogues.common.previewHeight)); + } + } - const modeMenuEvt = (key: SegmentedValue) => { - if (key == 'design') { - dispatch(setSidebarSize(vogues.common.sidebarClose)); + const toggleAnimationPanel = () => { + if (isAnimationOn) { + dispatch(setSidebarSize(vogues.common.close)); dispatch(setMode('design')); } else { dispatch(setSidebarSize(vogues.common.sidebarCode)); dispatch(setMode('animation')); } - }; + } return ( - modeMenuEvt(value)} - /> + <> +
+ +
+ ) }); diff --git a/src/wireframes/components/tools/ZoomTool.tsx b/src/wireframes/components/tools/ZoomTool.tsx index d777b19..1805094 100644 --- a/src/wireframes/components/tools/ZoomTool.tsx +++ b/src/wireframes/components/tools/ZoomTool.tsx @@ -18,14 +18,15 @@ import type { MenuProps } from 'antd'; export const ZoomTool = React.memo(() => { const dispatch = useDispatch(); const editorSize = useStore(getEditor).size; - const sidebarSize = useStore(s => s.ui.sidebarSize); + const sidebarWidth = useStore(s => s.ui.sidebarSize); + const isFooter = useStore(s => s.ui.footerSize) == vogues.common.previewHeight ? 1 : 0; const [zoomValue, setZoomValue] = useState('Fit'); const zoomPad = { - vertical: vogues.common.editorMargin * 2 + vogues.common.editorPad * 3 + vogues.common.headerHeight + vogues.common.shapeWidth + (vogues.common.previewHeight + vogues.common.editorMargin + vogues.common.previewPadBot) + vogues.common.selectionThickness * 4, - horizontal: vogues.common.editorMargin * 4 + vogues.common.editorPad * 2 + vogues.common.sidebarShape + vogues.common.selectionThickness * 4, + vertical: vogues.common.editorMargin * 2 + vogues.common.editorPad * 3 + vogues.common.headerHeight + vogues.common.shapeWidth + isFooter * (vogues.common.previewHeight + vogues.common.editorMargin + vogues.common.previewPadBot) + vogues.common.selectionThickness * 4, + horizontal: vogues.common.editorMargin * 4 + vogues.common.editorPad * 3 + vogues.common.sidebarShape + vogues.common.selectionThickness * 4, } - const [areaSize, setAreaSize] = useState(new Vec2(window.innerWidth - zoomPad.horizontal - sidebarSize, window.innerHeight - zoomPad.vertical)); + const [areaSize, setAreaSize] = useState(new Vec2(window.innerWidth - zoomPad.horizontal - sidebarWidth, window.innerHeight - zoomPad.vertical)); const isZoom = (key: string) => { setZoomValue(key); @@ -33,7 +34,7 @@ export const ZoomTool = React.memo(() => { }; const getWindowSize = () => { - setAreaSize(new Vec2(window.innerWidth - zoomPad.horizontal - sidebarSize, window.innerHeight - zoomPad.vertical)); + setAreaSize(new Vec2(window.innerWidth - zoomPad.horizontal - sidebarWidth, window.innerHeight - zoomPad.vertical)); } // Get area size value on resizing window @@ -54,8 +55,7 @@ export const ZoomTool = React.memo(() => { getWindowSize(); isZoom(zoomValue); } - - }, [sidebarSize, editorSize]); + }, [isFooter, sidebarWidth, editorSize]); const getZoomValue = (value: string) => { switch (value) { diff --git a/src/wireframes/model/actions/ui.ts b/src/wireframes/model/actions/ui.ts index 47c4cf0..b39abee 100644 --- a/src/wireframes/model/actions/ui.ts +++ b/src/wireframes/model/actions/ui.ts @@ -33,6 +33,11 @@ export const setSidebarSize = return { payload: { size } }; }); +export const setFooterSize = + createAction('ui/footerSize', (size: number) => { + return { payload: { size } }; + }); + export const setMode = createAction('ui/mode', (mode: ModeType) => { return { payload: { mode } }; @@ -75,6 +80,9 @@ export function ui(initialState: UIState): Reducer { .addCase(setSidebarSize, (state, action) => { state.sidebarSize = action.payload.size; }) + .addCase(setFooterSize, (state, action) => { + state.footerSize = action.payload.size; + }) .addCase(setMode, (state, action) => { state.selectedMode = action.payload.mode; }) diff --git a/src/wireframes/model/ui-state.ts b/src/wireframes/model/ui-state.ts index 008fdf0..ac48596 100644 --- a/src/wireframes/model/ui-state.ts +++ b/src/wireframes/model/ui-state.ts @@ -19,9 +19,12 @@ export interface UIState { // The info toast from any loading operation. infoToast?: string; - // The size for right sidebar + // The size for right sidebar. sidebarSize: number; + // The size for pages section. + footerSize: number; + // The mode for the application. selectedMode: ModeType; @@ -41,10 +44,11 @@ export interface UIStateInStore { export const createInitialUIState: () => UIState = () => { return { + footerSize: vogues.common.previewHeight, zoom: 1, selectedColor: 'palette', selectedMode: 'design', selectedAnimation: 'script', - sidebarSize: vogues.common.sidebarClose, + sidebarSize: vogues.common.close, }; };