From 58c737053642f59385d36735f0047593c3dd522a Mon Sep 17 00:00:00 2001 From: jeffvli Date: Tue, 28 Mar 2023 23:59:51 -0700 Subject: [PATCH] Add dedicated OS window bars (#22) --- src/renderer/components/scroll-area/index.tsx | 12 +- .../components/search-input/index.tsx | 2 +- .../hooks/use-fixed-table-header.tsx | 13 +- .../player/components/left-controls.tsx | 4 +- .../player/components/right-controls.tsx | 4 +- .../settings/components/general-tab.tsx | 22 +- .../components/sidebar-playlist-list.tsx | 158 ++++---- .../features/sidebar/components/sidebar.tsx | 6 +- .../hooks/use-should-pad-titlebar.tsx | 12 +- .../layouts/assets/close-mac-hover.png | Bin 0 -> 507 bytes src/renderer/layouts/assets/close-mac.png | Bin 0 -> 553 bytes src/renderer/layouts/assets/max-mac-hover.png | Bin 0 -> 566 bytes src/renderer/layouts/assets/max-mac.png | Bin 0 -> 557 bytes src/renderer/layouts/assets/min-mac-hover.png | Bin 0 -> 532 bytes src/renderer/layouts/assets/min-mac.png | Bin 0 -> 556 bytes src/renderer/layouts/default-layout.tsx | 374 ++---------------- .../layouts/default-layout/main-content.tsx | 345 ++++++++++++++++ .../layouts/default-layout/player-bar.tsx | 17 + src/renderer/layouts/window-bar.tsx | 251 ++++++++++++ src/renderer/router/titlebar-outlet.tsx | 12 +- src/renderer/store/app.store.ts | 10 +- src/renderer/store/player.store.ts | 18 +- src/renderer/store/settings.store.ts | 14 +- src/renderer/styles/ag-grid.scss | 4 + src/renderer/themes/default.scss | 7 +- 25 files changed, 823 insertions(+), 462 deletions(-) create mode 100644 src/renderer/layouts/assets/close-mac-hover.png create mode 100644 src/renderer/layouts/assets/close-mac.png create mode 100644 src/renderer/layouts/assets/max-mac-hover.png create mode 100644 src/renderer/layouts/assets/max-mac.png create mode 100644 src/renderer/layouts/assets/min-mac-hover.png create mode 100644 src/renderer/layouts/assets/min-mac.png create mode 100644 src/renderer/layouts/default-layout/main-content.tsx create mode 100644 src/renderer/layouts/default-layout/player-bar.tsx create mode 100644 src/renderer/layouts/window-bar.tsx diff --git a/src/renderer/components/scroll-area/index.tsx b/src/renderer/components/scroll-area/index.tsx index fabb0b25..555b5823 100644 --- a/src/renderer/components/scroll-area/index.tsx +++ b/src/renderer/components/scroll-area/index.tsx @@ -5,6 +5,8 @@ import { useMergedRef, useTimeout } from '@mantine/hooks'; import { motion, useScroll } from 'framer-motion'; import styled from 'styled-components'; import { PageHeader, PageHeaderProps } from '/@/renderer/components/page-header'; +import { useGeneralSettings } from '/@/renderer/store/settings.store'; +import { Platform } from '/@/renderer/types'; interface ScrollAreaProps extends MantineScrollAreaProps { children: React.ReactNode; @@ -26,16 +28,18 @@ const StyledScrollArea = styled(MantineScrollArea)` } `; -const StyledNativeScrollArea = styled.div<{ scrollBarOffset?: string }>` +const StyledNativeScrollArea = styled.div<{ scrollBarOffset?: string; windowBarStyle?: Platform }>` height: 100%; overflow-y: overlay !important; &::-webkit-scrollbar-track { - margin-top: ${(props) => props.scrollBarOffset || '65px'}; + margin-top: ${(props) => + props.windowBarStyle !== Platform.WEB ? '0px' : props.scrollBarOffset || '65px'}; } &::-webkit-scrollbar-thumb { - margin-top: ${(props) => props.scrollBarOffset || '65px'}; + margin-top: ${(props) => + props.windowBarStyle !== Platform.WEB ? '0px' : props.scrollBarOffset || '65px'}; } `; @@ -74,6 +78,7 @@ export const NativeScrollArea = forwardRef( }: NativeScrollAreaProps, ref: Ref, ) => { + const { windowBarStyle } = useGeneralSettings(); const [hideScrollbar, setHideScrollbar] = useState(false); const [hideHeader, setHideHeader] = useState(true); const { start, clear } = useTimeout( @@ -130,6 +135,7 @@ export const NativeScrollArea = forwardRef( ref={mergedRef} className={hideScrollbar ? 'hide-scrollbar' : undefined} scrollBarOffset={scrollBarOffset} + windowBarStyle={windowBarStyle} onMouseEnter={() => { setHideScrollbar(false); clear(); diff --git a/src/renderer/components/search-input/index.tsx b/src/renderer/components/search-input/index.tsx index 9e59ee63..a3580860 100644 --- a/src/renderer/components/search-input/index.tsx +++ b/src/renderer/components/search-input/index.tsx @@ -54,7 +54,7 @@ export const SearchInput = ({ padding: isOpened ? '10px' : 0, }, }} - width={isOpened ? openedWidth || 150 : initialWidth || 50} + width={isOpened ? openedWidth || 150 : initialWidth || 35} onChange={onChange} onKeyDown={handleEscape} /> diff --git a/src/renderer/components/virtual-table/hooks/use-fixed-table-header.tsx b/src/renderer/components/virtual-table/hooks/use-fixed-table-header.tsx index 09028e66..78df4049 100644 --- a/src/renderer/components/virtual-table/hooks/use-fixed-table-header.tsx +++ b/src/renderer/components/virtual-table/hooks/use-fixed-table-header.tsx @@ -1,12 +1,15 @@ import { useEffect, useRef } from 'react'; import { useInView } from 'framer-motion'; +import { useGeneralSettings } from '/@/renderer/store/settings.store'; +import { Platform } from '/@/renderer/types'; export const useFixedTableHeader = () => { const intersectRef = useRef(null); const tableContainerRef = useRef(null); + const { windowBarStyle } = useGeneralSettings(); const isNotPastTableIntersection = useInView(intersectRef, { - margin: '-68px 0px 0px 0px', + margin: windowBarStyle === Platform.WEB ? '-68px 0px 0px 0px' : '-98px 0px 0px 0px', }); const tableInView = useInView(tableContainerRef, { @@ -18,13 +21,19 @@ export const useFixedTableHeader = () => { const root = document.querySelector('main .ag-root'); if (isNotPastTableIntersection || !tableInView) { + if (windowBarStyle !== Platform.WEB) { + header?.classList.remove('window-frame'); + } header?.classList.remove('ag-header-fixed'); root?.classList.remove('ag-header-fixed-margin'); } else { + if (windowBarStyle !== Platform.WEB) { + header?.classList.add('window-frame'); + } header?.classList.add('ag-header-fixed'); root?.classList.add('ag-header-fixed-margin'); } - }, [isNotPastTableIntersection, tableInView]); + }, [isNotPastTableIntersection, tableInView, windowBarStyle]); return { intersectRef, tableContainerRef }; }; diff --git a/src/renderer/features/player/components/left-controls.tsx b/src/renderer/features/player/components/left-controls.tsx index 4498fc0e..ee4ec786 100644 --- a/src/renderer/features/player/components/left-controls.tsx +++ b/src/renderer/features/player/components/left-controls.tsx @@ -80,7 +80,7 @@ const LineItem = styled.div<{ $secondary?: boolean }>` `; export const LeftControls = () => { - const { setSidebar } = useAppStoreActions(); + const { setSideBar } = useAppStoreActions(); const { expanded: isFullScreenPlayerExpanded } = useFullScreenPlayerStore(); const setFullScreenPlayerStore = useSetFullScreenPlayerStore(); const hideImage = useAppStore((state) => state.sidebar.image); @@ -102,7 +102,7 @@ export const LeftControls = () => { const handleToggleSidebarImage = (e: MouseEvent) => { e.stopPropagation(); - setSidebar({ image: true }); + setSideBar({ image: true }); }; return ( diff --git a/src/renderer/features/player/components/right-controls.tsx b/src/renderer/features/player/components/right-controls.tsx index 04d7fba8..2a167030 100644 --- a/src/renderer/features/player/components/right-controls.tsx +++ b/src/renderer/features/player/components/right-controls.tsx @@ -28,7 +28,7 @@ export const RightControls = () => { const muted = useMuted(); const server = useCurrentServer(); const currentSong = useCurrentSong(); - const { setSidebar } = useAppStoreActions(); + const { setSideBar } = useAppStoreActions(); const { rightExpanded: isQueueExpanded } = useSidebarStore(); const { handleVolumeSlider, handleVolumeWheel, handleMute } = useRightControls(); @@ -145,7 +145,7 @@ export const RightControls = () => { icon={} tooltip={{ label: 'View queue', openDelay: 500 }} variant="secondary" - onClick={() => setSidebar({ rightExpanded: !isQueueExpanded })} + onClick={() => setSideBar({ rightExpanded: !isQueueExpanded })} /> { const settings = useGeneralSettings(); const { setSettings } = useSettingsStoreActions(); @@ -34,9 +41,18 @@ export const GeneralTab = () => { { control: (