mirror of
https://github.com/antebudimir/feishin.git
synced 2026-01-01 10:23:33 +00:00
Lint all files
This commit is contained in:
parent
22af76b4d6
commit
30e52ebb54
334 changed files with 76519 additions and 75932 deletions
|
|
@ -3,29 +3,29 @@ import styled from 'styled-components';
|
|||
import { Titlebar } from '/@/renderer/features/titlebar/components/titlebar';
|
||||
|
||||
const WindowsTitlebarContainer = styled.div`
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
user-select: none;
|
||||
-webkit-app-region: drag;
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
user-select: none;
|
||||
-webkit-app-region: drag;
|
||||
`;
|
||||
|
||||
const ContentContainer = styled.div`
|
||||
display: flex;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
`;
|
||||
|
||||
export const AuthLayout = () => {
|
||||
return (
|
||||
<>
|
||||
<WindowsTitlebarContainer>
|
||||
<Titlebar />
|
||||
</WindowsTitlebarContainer>
|
||||
<ContentContainer>
|
||||
<Outlet />
|
||||
</ContentContainer>
|
||||
</>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<WindowsTitlebarContainer>
|
||||
<Titlebar />
|
||||
</WindowsTitlebarContainer>
|
||||
<ContentContainer>
|
||||
<Outlet />
|
||||
</ContentContainer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@ import { lazy } from 'react';
|
|||
import isElectron from 'is-electron';
|
||||
import styled from 'styled-components';
|
||||
import {
|
||||
useWindowSettings,
|
||||
useSettingsStore,
|
||||
useHotkeySettings,
|
||||
useGeneralSettings,
|
||||
useSettingsStoreActions,
|
||||
useWindowSettings,
|
||||
useSettingsStore,
|
||||
useHotkeySettings,
|
||||
useGeneralSettings,
|
||||
useSettingsStoreActions,
|
||||
} from '/@/renderer/store/settings.store';
|
||||
import { Platform, PlaybackType } from '/@/renderer/types';
|
||||
import { MainContent } from '/@/renderer/layouts/default-layout/main-content';
|
||||
|
|
@ -16,86 +16,86 @@ import { CommandPalette } from '/@/renderer/features/search/components/command-p
|
|||
import { useCommandPalette } from '/@/renderer/store';
|
||||
|
||||
if (!isElectron()) {
|
||||
useSettingsStore.getState().actions.setSettings({
|
||||
playback: {
|
||||
...useSettingsStore.getState().playback,
|
||||
type: PlaybackType.WEB,
|
||||
},
|
||||
});
|
||||
useSettingsStore.getState().actions.setSettings({
|
||||
playback: {
|
||||
...useSettingsStore.getState().playback,
|
||||
type: PlaybackType.WEB,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const Layout = styled.div<{ windowBarStyle: Platform }>`
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
'window-bar'
|
||||
'main-content'
|
||||
'player';
|
||||
grid-template-rows: ${(props) =>
|
||||
props.windowBarStyle === Platform.WINDOWS || props.windowBarStyle === Platform.MACOS
|
||||
? '30px calc(100vh - 120px) 90px'
|
||||
: '0px calc(100vh - 90px) 90px'};
|
||||
grid-template-columns: 1fr;
|
||||
gap: 0;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
'window-bar'
|
||||
'main-content'
|
||||
'player';
|
||||
grid-template-rows: ${(props) =>
|
||||
props.windowBarStyle === Platform.WINDOWS || props.windowBarStyle === Platform.MACOS
|
||||
? '30px calc(100vh - 120px) 90px'
|
||||
: '0px calc(100vh - 90px) 90px'};
|
||||
grid-template-columns: 1fr;
|
||||
gap: 0;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
const WindowBar = lazy(() =>
|
||||
import('/@/renderer/layouts/window-bar').then((module) => ({
|
||||
default: module.WindowBar,
|
||||
})),
|
||||
import('/@/renderer/layouts/window-bar').then((module) => ({
|
||||
default: module.WindowBar,
|
||||
})),
|
||||
);
|
||||
|
||||
interface DefaultLayoutProps {
|
||||
shell?: boolean;
|
||||
shell?: boolean;
|
||||
}
|
||||
|
||||
export const DefaultLayout = ({ shell }: DefaultLayoutProps) => {
|
||||
const { windowBarStyle } = useWindowSettings();
|
||||
const { opened, ...handlers } = useCommandPalette();
|
||||
const { bindings } = useHotkeySettings();
|
||||
const localSettings = isElectron() ? window.electron.localSettings : null;
|
||||
const settings = useGeneralSettings();
|
||||
const { setSettings } = useSettingsStoreActions();
|
||||
const { windowBarStyle } = useWindowSettings();
|
||||
const { opened, ...handlers } = useCommandPalette();
|
||||
const { bindings } = useHotkeySettings();
|
||||
const localSettings = isElectron() ? window.electron.localSettings : null;
|
||||
const settings = useGeneralSettings();
|
||||
const { setSettings } = useSettingsStoreActions();
|
||||
|
||||
const updateZoom = (increase: number) => {
|
||||
const newVal = settings.zoomFactor + increase;
|
||||
if (newVal > 300 || newVal < 50 || !isElectron()) return;
|
||||
setSettings({
|
||||
general: {
|
||||
...settings,
|
||||
zoomFactor: newVal,
|
||||
},
|
||||
});
|
||||
const updateZoom = (increase: number) => {
|
||||
const newVal = settings.zoomFactor + increase;
|
||||
if (newVal > 300 || newVal < 50 || !isElectron()) return;
|
||||
setSettings({
|
||||
general: {
|
||||
...settings,
|
||||
zoomFactor: newVal,
|
||||
},
|
||||
});
|
||||
localSettings?.setZoomFactor(settings.zoomFactor);
|
||||
};
|
||||
localSettings?.setZoomFactor(settings.zoomFactor);
|
||||
};
|
||||
localSettings?.setZoomFactor(settings.zoomFactor);
|
||||
|
||||
const zoomHotkeys: HotkeyItem[] = [
|
||||
[bindings.zoomIn.hotkey, () => updateZoom(5)],
|
||||
[bindings.zoomOut.hotkey, () => updateZoom(-5)],
|
||||
];
|
||||
const zoomHotkeys: HotkeyItem[] = [
|
||||
[bindings.zoomIn.hotkey, () => updateZoom(5)],
|
||||
[bindings.zoomOut.hotkey, () => updateZoom(-5)],
|
||||
];
|
||||
|
||||
useHotkeys([
|
||||
[bindings.globalSearch.hotkey, () => handlers.open()],
|
||||
...(isElectron() ? zoomHotkeys : []),
|
||||
]);
|
||||
useHotkeys([
|
||||
[bindings.globalSearch.hotkey, () => handlers.open()],
|
||||
...(isElectron() ? zoomHotkeys : []),
|
||||
]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Layout
|
||||
id="default-layout"
|
||||
windowBarStyle={windowBarStyle}
|
||||
>
|
||||
{windowBarStyle !== Platform.WEB && <WindowBar />}
|
||||
<MainContent shell={shell} />
|
||||
<PlayerBar />
|
||||
</Layout>
|
||||
<CommandPalette modalProps={{ handlers, opened }} />
|
||||
</>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<Layout
|
||||
id="default-layout"
|
||||
windowBarStyle={windowBarStyle}
|
||||
>
|
||||
{windowBarStyle !== Platform.WEB && <WindowBar />}
|
||||
<MainContent shell={shell} />
|
||||
<PlayerBar />
|
||||
</Layout>
|
||||
<CommandPalette modalProps={{ handlers, opened }} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
DefaultLayout.defaultProps = {
|
||||
shell: false,
|
||||
shell: false,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@ import { FullScreenPlayer } from '/@/renderer/features/player/components/full-sc
|
|||
import { useFullScreenPlayerStore } from '/@/renderer/store';
|
||||
|
||||
export const FullScreenOverlay = () => {
|
||||
const { expanded: isFullScreenPlayerExpanded } = useFullScreenPlayerStore();
|
||||
const { expanded: isFullScreenPlayerExpanded } = useFullScreenPlayerStore();
|
||||
|
||||
return (
|
||||
<AnimatePresence initial={false}>
|
||||
{isFullScreenPlayerExpanded && <FullScreenPlayer />}
|
||||
</AnimatePresence>
|
||||
);
|
||||
return (
|
||||
<AnimatePresence initial={false}>
|
||||
{isFullScreenPlayerExpanded && <FullScreenPlayer />}
|
||||
</AnimatePresence>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,33 +6,33 @@ import { Sidebar } from '/@/renderer/features/sidebar/components/sidebar';
|
|||
import { useSidebarStore } from '/@/renderer/store';
|
||||
|
||||
const SidebarContainer = styled.aside`
|
||||
position: relative;
|
||||
grid-area: sidebar;
|
||||
background: var(--sidebar-bg);
|
||||
border-right: var(--sidebar-border);
|
||||
position: relative;
|
||||
grid-area: sidebar;
|
||||
background: var(--sidebar-bg);
|
||||
border-right: var(--sidebar-border);
|
||||
`;
|
||||
|
||||
interface LeftSidebarProps {
|
||||
isResizing: boolean;
|
||||
startResizing: (direction: 'left' | 'right') => void;
|
||||
isResizing: boolean;
|
||||
startResizing: (direction: 'left' | 'right') => void;
|
||||
}
|
||||
|
||||
export const LeftSidebar = ({ isResizing, startResizing }: LeftSidebarProps) => {
|
||||
const sidebarRef = useRef<HTMLDivElement | null>(null);
|
||||
const { collapsed } = useSidebarStore();
|
||||
const sidebarRef = useRef<HTMLDivElement | null>(null);
|
||||
const { collapsed } = useSidebarStore();
|
||||
|
||||
return (
|
||||
<SidebarContainer id="sidebar">
|
||||
<ResizeHandle
|
||||
ref={sidebarRef}
|
||||
isResizing={isResizing}
|
||||
placement="right"
|
||||
onMouseDown={(e) => {
|
||||
e.preventDefault();
|
||||
startResizing('left');
|
||||
}}
|
||||
/>
|
||||
{collapsed ? <CollapsedSidebar /> : <Sidebar />}
|
||||
</SidebarContainer>
|
||||
);
|
||||
return (
|
||||
<SidebarContainer id="sidebar">
|
||||
<ResizeHandle
|
||||
ref={sidebarRef}
|
||||
isResizing={isResizing}
|
||||
placement="right"
|
||||
onMouseDown={(e) => {
|
||||
e.preventDefault();
|
||||
startResizing('left');
|
||||
}}
|
||||
/>
|
||||
{collapsed ? <CollapsedSidebar /> : <Sidebar />}
|
||||
</SidebarContainer>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -12,113 +12,117 @@ import { RightSidebar } from '/@/renderer/layouts/default-layout/right-sidebar';
|
|||
import { Spinner } from '/@/renderer/components';
|
||||
|
||||
const SideDrawerQueue = lazy(() =>
|
||||
import('/@/renderer/layouts/default-layout/side-drawer-queue').then((module) => ({
|
||||
default: module.SideDrawerQueue,
|
||||
})),
|
||||
import('/@/renderer/layouts/default-layout/side-drawer-queue').then((module) => ({
|
||||
default: module.SideDrawerQueue,
|
||||
})),
|
||||
);
|
||||
|
||||
const MINIMUM_SIDEBAR_WIDTH = 260;
|
||||
|
||||
const MainContentContainer = styled.div<{
|
||||
leftSidebarWidth: string;
|
||||
rightExpanded?: boolean;
|
||||
rightSidebarWidth?: string;
|
||||
shell?: boolean;
|
||||
sidebarCollapsed?: boolean;
|
||||
leftSidebarWidth: string;
|
||||
rightExpanded?: boolean;
|
||||
rightSidebarWidth?: string;
|
||||
shell?: boolean;
|
||||
sidebarCollapsed?: boolean;
|
||||
}>`
|
||||
position: relative;
|
||||
display: ${(props) => (props.shell ? 'flex' : 'grid')};
|
||||
grid-area: main-content;
|
||||
grid-template-areas: 'sidebar . right-sidebar';
|
||||
grid-template-rows: 1fr;
|
||||
grid-template-columns: ${(props) => (props.sidebarCollapsed ? '80px' : props.leftSidebarWidth)} 1fr ${(
|
||||
props,
|
||||
) => props.rightExpanded && props.rightSidebarWidth};
|
||||
position: relative;
|
||||
display: ${(props) => (props.shell ? 'flex' : 'grid')};
|
||||
grid-area: main-content;
|
||||
grid-template-areas: 'sidebar . right-sidebar';
|
||||
grid-template-rows: 1fr;
|
||||
grid-template-columns: ${(props) => (props.sidebarCollapsed ? '80px' : props.leftSidebarWidth)} 1fr ${(
|
||||
props,
|
||||
) => props.rightExpanded && props.rightSidebarWidth};
|
||||
|
||||
gap: 0;
|
||||
background: var(--main-bg);
|
||||
gap: 0;
|
||||
background: var(--main-bg);
|
||||
`;
|
||||
|
||||
export const MainContent = ({ shell }: { shell?: boolean }) => {
|
||||
const location = useLocation();
|
||||
const { collapsed, leftWidth, rightWidth, rightExpanded } = useSidebarStore();
|
||||
const { setSideBar } = useAppStoreActions();
|
||||
const { sideQueueType, showQueueDrawerButton } = useGeneralSettings();
|
||||
const [isResizing, setIsResizing] = useState(false);
|
||||
const [isResizingRight, setIsResizingRight] = useState(false);
|
||||
const location = useLocation();
|
||||
const { collapsed, leftWidth, rightWidth, rightExpanded } = useSidebarStore();
|
||||
const { setSideBar } = useAppStoreActions();
|
||||
const { sideQueueType, showQueueDrawerButton } = useGeneralSettings();
|
||||
const [isResizing, setIsResizing] = useState(false);
|
||||
const [isResizingRight, setIsResizingRight] = useState(false);
|
||||
|
||||
const showSideQueue = rightExpanded && location.pathname !== AppRoute.NOW_PLAYING;
|
||||
const rightSidebarRef = useRef<HTMLDivElement | null>(null);
|
||||
const showSideQueue = rightExpanded && location.pathname !== AppRoute.NOW_PLAYING;
|
||||
const rightSidebarRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
const startResizing = useCallback((position: 'left' | 'right') => {
|
||||
if (position === 'left') return setIsResizing(true);
|
||||
return setIsResizingRight(true);
|
||||
}, []);
|
||||
const startResizing = useCallback((position: 'left' | 'right') => {
|
||||
if (position === 'left') return setIsResizing(true);
|
||||
return setIsResizingRight(true);
|
||||
}, []);
|
||||
|
||||
const stopResizing = useCallback(() => {
|
||||
setIsResizing(false);
|
||||
setIsResizingRight(false);
|
||||
}, []);
|
||||
const stopResizing = useCallback(() => {
|
||||
setIsResizing(false);
|
||||
setIsResizingRight(false);
|
||||
}, []);
|
||||
|
||||
const resize = useCallback(
|
||||
(mouseMoveEvent: any) => {
|
||||
if (isResizing) {
|
||||
const width = mouseMoveEvent.clientX;
|
||||
const constrainedWidth = `${constrainSidebarWidth(width)}px`;
|
||||
const resize = useCallback(
|
||||
(mouseMoveEvent: any) => {
|
||||
if (isResizing) {
|
||||
const width = mouseMoveEvent.clientX;
|
||||
const constrainedWidth = `${constrainSidebarWidth(width)}px`;
|
||||
|
||||
if (width < MINIMUM_SIDEBAR_WIDTH - 100) {
|
||||
setSideBar({ collapsed: true });
|
||||
} else {
|
||||
setSideBar({ collapsed: false, leftWidth: constrainedWidth });
|
||||
}
|
||||
} else if (isResizingRight) {
|
||||
const start = Number(rightWidth.split('px')[0]);
|
||||
const { left } = rightSidebarRef!.current!.getBoundingClientRect();
|
||||
const width = `${constrainRightSidebarWidth(start + left - mouseMoveEvent.clientX)}px`;
|
||||
setSideBar({ rightWidth: width });
|
||||
}
|
||||
},
|
||||
[isResizing, isResizingRight, setSideBar, rightWidth],
|
||||
);
|
||||
if (width < MINIMUM_SIDEBAR_WIDTH - 100) {
|
||||
setSideBar({ collapsed: true });
|
||||
} else {
|
||||
setSideBar({ collapsed: false, leftWidth: constrainedWidth });
|
||||
}
|
||||
} else if (isResizingRight) {
|
||||
const start = Number(rightWidth.split('px')[0]);
|
||||
const { left } = rightSidebarRef!.current!.getBoundingClientRect();
|
||||
const width = `${constrainRightSidebarWidth(
|
||||
start + left - mouseMoveEvent.clientX,
|
||||
)}px`;
|
||||
setSideBar({ rightWidth: width });
|
||||
}
|
||||
},
|
||||
[isResizing, isResizingRight, setSideBar, rightWidth],
|
||||
);
|
||||
|
||||
const throttledResize = useMemo(() => throttle(resize, 50), [resize]);
|
||||
const throttledResize = useMemo(() => throttle(resize, 50), [resize]);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('mousemove', throttledResize);
|
||||
window.addEventListener('mouseup', stopResizing);
|
||||
return () => {
|
||||
window.removeEventListener('mousemove', throttledResize);
|
||||
window.removeEventListener('mouseup', stopResizing);
|
||||
};
|
||||
}, [throttledResize, stopResizing]);
|
||||
useEffect(() => {
|
||||
window.addEventListener('mousemove', throttledResize);
|
||||
window.addEventListener('mouseup', stopResizing);
|
||||
return () => {
|
||||
window.removeEventListener('mousemove', throttledResize);
|
||||
window.removeEventListener('mouseup', stopResizing);
|
||||
};
|
||||
}, [throttledResize, stopResizing]);
|
||||
|
||||
return (
|
||||
<MainContentContainer
|
||||
id="main-content"
|
||||
leftSidebarWidth={leftWidth}
|
||||
rightExpanded={showSideQueue && sideQueueType === 'sideQueue'}
|
||||
rightSidebarWidth={rightWidth}
|
||||
shell={shell}
|
||||
sidebarCollapsed={collapsed}
|
||||
>
|
||||
{!shell && (
|
||||
<>
|
||||
<Suspense fallback={<></>}>{showQueueDrawerButton && <SideDrawerQueue />}</Suspense>
|
||||
<FullScreenOverlay />
|
||||
<LeftSidebar
|
||||
isResizing={isResizing}
|
||||
startResizing={startResizing}
|
||||
/>
|
||||
<RightSidebar
|
||||
ref={rightSidebarRef}
|
||||
isResizing={isResizingRight}
|
||||
startResizing={startResizing}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<Suspense fallback={<Spinner container />}>
|
||||
<Outlet />
|
||||
</Suspense>
|
||||
</MainContentContainer>
|
||||
);
|
||||
return (
|
||||
<MainContentContainer
|
||||
id="main-content"
|
||||
leftSidebarWidth={leftWidth}
|
||||
rightExpanded={showSideQueue && sideQueueType === 'sideQueue'}
|
||||
rightSidebarWidth={rightWidth}
|
||||
shell={shell}
|
||||
sidebarCollapsed={collapsed}
|
||||
>
|
||||
{!shell && (
|
||||
<>
|
||||
<Suspense fallback={<></>}>
|
||||
{showQueueDrawerButton && <SideDrawerQueue />}
|
||||
</Suspense>
|
||||
<FullScreenOverlay />
|
||||
<LeftSidebar
|
||||
isResizing={isResizing}
|
||||
startResizing={startResizing}
|
||||
/>
|
||||
<RightSidebar
|
||||
ref={rightSidebarRef}
|
||||
isResizing={isResizingRight}
|
||||
startResizing={startResizing}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<Suspense fallback={<Spinner container />}>
|
||||
<Outlet />
|
||||
</Suspense>
|
||||
</MainContentContainer>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,15 +2,15 @@ import styled from 'styled-components';
|
|||
import { Playerbar } from '/@/renderer/features/player';
|
||||
|
||||
const PlayerbarContainer = styled.footer`
|
||||
z-index: 200;
|
||||
grid-area: player;
|
||||
background: var(--playerbar-bg);
|
||||
z-index: 200;
|
||||
grid-area: player;
|
||||
background: var(--playerbar-bg);
|
||||
`;
|
||||
|
||||
export const PlayerBar = () => {
|
||||
return (
|
||||
<PlayerbarContainer id="player-bar">
|
||||
<Playerbar />
|
||||
</PlayerbarContainer>
|
||||
);
|
||||
return (
|
||||
<PlayerbarContainer id="player-bar">
|
||||
<Playerbar />
|
||||
</PlayerbarContainer>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,134 +9,137 @@ import { useGeneralSettings, useSidebarStore, useWindowSettings } from '/@/rende
|
|||
import { Platform } from '/@/renderer/types';
|
||||
|
||||
const RightSidebarContainer = styled(motion.aside)`
|
||||
position: relative;
|
||||
grid-area: right-sidebar;
|
||||
height: 100%;
|
||||
background: var(--sidebar-bg);
|
||||
border-left: var(--sidebar-border);
|
||||
position: relative;
|
||||
grid-area: right-sidebar;
|
||||
height: 100%;
|
||||
background: var(--sidebar-bg);
|
||||
border-left: var(--sidebar-border);
|
||||
`;
|
||||
|
||||
const queueSidebarVariants: Variants = {
|
||||
closed: (rightWidth) => ({
|
||||
transition: { duration: 0.5 },
|
||||
width: rightWidth,
|
||||
x: 1000,
|
||||
zIndex: 120,
|
||||
}),
|
||||
open: (rightWidth) => ({
|
||||
transition: {
|
||||
duration: 0.5,
|
||||
ease: 'anticipate',
|
||||
},
|
||||
width: rightWidth,
|
||||
x: 0,
|
||||
zIndex: 120,
|
||||
}),
|
||||
closed: (rightWidth) => ({
|
||||
transition: { duration: 0.5 },
|
||||
width: rightWidth,
|
||||
x: 1000,
|
||||
zIndex: 120,
|
||||
}),
|
||||
open: (rightWidth) => ({
|
||||
transition: {
|
||||
duration: 0.5,
|
||||
ease: 'anticipate',
|
||||
},
|
||||
width: rightWidth,
|
||||
x: 0,
|
||||
zIndex: 120,
|
||||
}),
|
||||
};
|
||||
|
||||
const QueueDrawer = styled(motion.div)`
|
||||
background: var(--main-bg);
|
||||
border: 3px solid var(--generic-border-color);
|
||||
border-radius: 10px;
|
||||
background: var(--main-bg);
|
||||
border: 3px solid var(--generic-border-color);
|
||||
border-radius: 10px;
|
||||
`;
|
||||
|
||||
const queueDrawerVariants: Variants = {
|
||||
closed: (windowBarStyle) => ({
|
||||
height:
|
||||
windowBarStyle === Platform.WINDOWS || Platform.MACOS
|
||||
? 'calc(100vh - 205px)'
|
||||
: 'calc(100vh - 175px)',
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: '75px',
|
||||
transition: {
|
||||
duration: 0.4,
|
||||
ease: 'anticipate',
|
||||
},
|
||||
width: '450px',
|
||||
x: '50vw',
|
||||
}),
|
||||
open: (windowBarStyle) => ({
|
||||
boxShadow: '0px 0px 10px 0px rgba(0, 0, 0, 0.8)',
|
||||
height:
|
||||
windowBarStyle === Platform.WINDOWS || Platform.MACOS
|
||||
? 'calc(100vh - 205px)'
|
||||
: 'calc(100vh - 175px)',
|
||||
position: 'absolute',
|
||||
right: '20px',
|
||||
top: '75px',
|
||||
transition: {
|
||||
damping: 10,
|
||||
delay: 0,
|
||||
duration: 0.4,
|
||||
ease: 'anticipate',
|
||||
mass: 0.5,
|
||||
},
|
||||
width: '450px',
|
||||
x: 0,
|
||||
zIndex: 120,
|
||||
}),
|
||||
closed: (windowBarStyle) => ({
|
||||
height:
|
||||
windowBarStyle === Platform.WINDOWS || Platform.MACOS
|
||||
? 'calc(100vh - 205px)'
|
||||
: 'calc(100vh - 175px)',
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: '75px',
|
||||
transition: {
|
||||
duration: 0.4,
|
||||
ease: 'anticipate',
|
||||
},
|
||||
width: '450px',
|
||||
x: '50vw',
|
||||
}),
|
||||
open: (windowBarStyle) => ({
|
||||
boxShadow: '0px 0px 10px 0px rgba(0, 0, 0, 0.8)',
|
||||
height:
|
||||
windowBarStyle === Platform.WINDOWS || Platform.MACOS
|
||||
? 'calc(100vh - 205px)'
|
||||
: 'calc(100vh - 175px)',
|
||||
position: 'absolute',
|
||||
right: '20px',
|
||||
top: '75px',
|
||||
transition: {
|
||||
damping: 10,
|
||||
delay: 0,
|
||||
duration: 0.4,
|
||||
ease: 'anticipate',
|
||||
mass: 0.5,
|
||||
},
|
||||
width: '450px',
|
||||
x: 0,
|
||||
zIndex: 120,
|
||||
}),
|
||||
};
|
||||
|
||||
interface RightSidebarProps {
|
||||
isResizing: boolean;
|
||||
startResizing: (direction: 'left' | 'right') => void;
|
||||
isResizing: boolean;
|
||||
startResizing: (direction: 'left' | 'right') => void;
|
||||
}
|
||||
|
||||
export const RightSidebar = forwardRef(
|
||||
({ isResizing: isResizingRight, startResizing }: RightSidebarProps, ref: Ref<HTMLDivElement>) => {
|
||||
const { windowBarStyle } = useWindowSettings();
|
||||
const { rightWidth, rightExpanded } = useSidebarStore();
|
||||
const { sideQueueType } = useGeneralSettings();
|
||||
const location = useLocation();
|
||||
const showSideQueue = rightExpanded && location.pathname !== AppRoute.NOW_PLAYING;
|
||||
(
|
||||
{ isResizing: isResizingRight, startResizing }: RightSidebarProps,
|
||||
ref: Ref<HTMLDivElement>,
|
||||
) => {
|
||||
const { windowBarStyle } = useWindowSettings();
|
||||
const { rightWidth, rightExpanded } = useSidebarStore();
|
||||
const { sideQueueType } = useGeneralSettings();
|
||||
const location = useLocation();
|
||||
const showSideQueue = rightExpanded && location.pathname !== AppRoute.NOW_PLAYING;
|
||||
|
||||
return (
|
||||
<AnimatePresence
|
||||
key="queue-sidebar"
|
||||
presenceAffectsLayout
|
||||
initial={false}
|
||||
mode="sync"
|
||||
>
|
||||
{showSideQueue && (
|
||||
<>
|
||||
{sideQueueType === 'sideQueue' ? (
|
||||
<RightSidebarContainer
|
||||
return (
|
||||
<AnimatePresence
|
||||
key="queue-sidebar"
|
||||
animate="open"
|
||||
custom={rightWidth}
|
||||
exit="closed"
|
||||
id="sidebar-queue"
|
||||
initial="closed"
|
||||
variants={queueSidebarVariants}
|
||||
>
|
||||
<ResizeHandle
|
||||
ref={ref}
|
||||
isResizing={isResizingRight}
|
||||
placement="left"
|
||||
onMouseDown={(e) => {
|
||||
e.preventDefault();
|
||||
startResizing('right');
|
||||
}}
|
||||
/>
|
||||
<SidebarPlayQueue />
|
||||
</RightSidebarContainer>
|
||||
) : (
|
||||
<QueueDrawer
|
||||
key="queue-drawer"
|
||||
animate="open"
|
||||
custom={windowBarStyle}
|
||||
exit="closed"
|
||||
id="drawer-queue"
|
||||
initial="closed"
|
||||
variants={queueDrawerVariants}
|
||||
>
|
||||
<DrawerPlayQueue />
|
||||
</QueueDrawer>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
);
|
||||
},
|
||||
presenceAffectsLayout
|
||||
initial={false}
|
||||
mode="sync"
|
||||
>
|
||||
{showSideQueue && (
|
||||
<>
|
||||
{sideQueueType === 'sideQueue' ? (
|
||||
<RightSidebarContainer
|
||||
key="queue-sidebar"
|
||||
animate="open"
|
||||
custom={rightWidth}
|
||||
exit="closed"
|
||||
id="sidebar-queue"
|
||||
initial="closed"
|
||||
variants={queueSidebarVariants}
|
||||
>
|
||||
<ResizeHandle
|
||||
ref={ref}
|
||||
isResizing={isResizingRight}
|
||||
placement="left"
|
||||
onMouseDown={(e) => {
|
||||
e.preventDefault();
|
||||
startResizing('right');
|
||||
}}
|
||||
/>
|
||||
<SidebarPlayQueue />
|
||||
</RightSidebarContainer>
|
||||
) : (
|
||||
<QueueDrawer
|
||||
key="queue-drawer"
|
||||
animate="open"
|
||||
custom={windowBarStyle}
|
||||
exit="closed"
|
||||
id="drawer-queue"
|
||||
initial="closed"
|
||||
variants={queueDrawerVariants}
|
||||
>
|
||||
<DrawerPlayQueue />
|
||||
</QueueDrawer>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -10,132 +10,132 @@ import { useAppStore, useSidebarStore } from '/@/renderer/store';
|
|||
import { Platform } from '/@/renderer/types';
|
||||
|
||||
const QueueDrawerArea = styled(motion.div)`
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 25px;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 20px;
|
||||
height: 30px;
|
||||
user-select: none;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 25px;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 20px;
|
||||
height: 30px;
|
||||
user-select: none;
|
||||
`;
|
||||
|
||||
const QueueDrawer = styled(motion.div)`
|
||||
background: var(--main-bg);
|
||||
border: 3px solid var(--generic-border-color);
|
||||
border-radius: 10px;
|
||||
background: var(--main-bg);
|
||||
border: 3px solid var(--generic-border-color);
|
||||
border-radius: 10px;
|
||||
`;
|
||||
|
||||
const queueDrawerVariants: Variants = {
|
||||
closed: (windowBarStyle) => ({
|
||||
height:
|
||||
windowBarStyle === Platform.WINDOWS || Platform.MACOS
|
||||
? 'calc(100vh - 205px)'
|
||||
: 'calc(100vh - 175px)',
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: '75px',
|
||||
transition: {
|
||||
duration: 0.4,
|
||||
ease: 'anticipate',
|
||||
},
|
||||
width: '450px',
|
||||
x: '50vw',
|
||||
}),
|
||||
open: (windowBarStyle) => ({
|
||||
boxShadow: '0px 0px 10px 0px rgba(0, 0, 0, 0.8)',
|
||||
height:
|
||||
windowBarStyle === Platform.WINDOWS || Platform.MACOS
|
||||
? 'calc(100vh - 205px)'
|
||||
: 'calc(100vh - 175px)',
|
||||
position: 'absolute',
|
||||
right: '20px',
|
||||
top: '75px',
|
||||
transition: {
|
||||
damping: 10,
|
||||
delay: 0,
|
||||
duration: 0.4,
|
||||
ease: 'anticipate',
|
||||
mass: 0.5,
|
||||
},
|
||||
width: '450px',
|
||||
x: 0,
|
||||
zIndex: 120,
|
||||
}),
|
||||
closed: (windowBarStyle) => ({
|
||||
height:
|
||||
windowBarStyle === Platform.WINDOWS || Platform.MACOS
|
||||
? 'calc(100vh - 205px)'
|
||||
: 'calc(100vh - 175px)',
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: '75px',
|
||||
transition: {
|
||||
duration: 0.4,
|
||||
ease: 'anticipate',
|
||||
},
|
||||
width: '450px',
|
||||
x: '50vw',
|
||||
}),
|
||||
open: (windowBarStyle) => ({
|
||||
boxShadow: '0px 0px 10px 0px rgba(0, 0, 0, 0.8)',
|
||||
height:
|
||||
windowBarStyle === Platform.WINDOWS || Platform.MACOS
|
||||
? 'calc(100vh - 205px)'
|
||||
: 'calc(100vh - 175px)',
|
||||
position: 'absolute',
|
||||
right: '20px',
|
||||
top: '75px',
|
||||
transition: {
|
||||
damping: 10,
|
||||
delay: 0,
|
||||
duration: 0.4,
|
||||
ease: 'anticipate',
|
||||
mass: 0.5,
|
||||
},
|
||||
width: '450px',
|
||||
x: 0,
|
||||
zIndex: 120,
|
||||
}),
|
||||
};
|
||||
|
||||
const queueDrawerButtonVariants: Variants = {
|
||||
hidden: {
|
||||
opacity: 0,
|
||||
transition: { duration: 0.2 },
|
||||
x: 100,
|
||||
},
|
||||
visible: {
|
||||
opacity: 0.5,
|
||||
transition: { duration: 0.1, ease: 'anticipate' },
|
||||
x: 0,
|
||||
},
|
||||
hidden: {
|
||||
opacity: 0,
|
||||
transition: { duration: 0.2 },
|
||||
x: 100,
|
||||
},
|
||||
visible: {
|
||||
opacity: 0.5,
|
||||
transition: { duration: 0.1, ease: 'anticipate' },
|
||||
x: 0,
|
||||
},
|
||||
};
|
||||
|
||||
export const SideDrawerQueue = () => {
|
||||
const location = useLocation();
|
||||
const [drawer, drawerHandler] = useDisclosure(false);
|
||||
const { rightExpanded } = useSidebarStore();
|
||||
const location = useLocation();
|
||||
const [drawer, drawerHandler] = useDisclosure(false);
|
||||
const { rightExpanded } = useSidebarStore();
|
||||
|
||||
const drawerTimeout = useTimeout(() => drawerHandler.open(), 500);
|
||||
const drawerTimeout = useTimeout(() => drawerHandler.open(), 500);
|
||||
|
||||
const handleEnterDrawerButton = useCallback(() => {
|
||||
drawerTimeout.start();
|
||||
}, [drawerTimeout]);
|
||||
const handleEnterDrawerButton = useCallback(() => {
|
||||
drawerTimeout.start();
|
||||
}, [drawerTimeout]);
|
||||
|
||||
const handleLeaveDrawerButton = useCallback(() => {
|
||||
drawerTimeout.clear();
|
||||
}, [drawerTimeout]);
|
||||
const handleLeaveDrawerButton = useCallback(() => {
|
||||
drawerTimeout.clear();
|
||||
}, [drawerTimeout]);
|
||||
|
||||
const isQueueDrawerButtonVisible =
|
||||
!rightExpanded && !drawer && location.pathname !== AppRoute.NOW_PLAYING;
|
||||
const isQueueDrawerButtonVisible =
|
||||
!rightExpanded && !drawer && location.pathname !== AppRoute.NOW_PLAYING;
|
||||
|
||||
return (
|
||||
<>
|
||||
<AnimatePresence
|
||||
initial={false}
|
||||
mode="wait"
|
||||
>
|
||||
{isQueueDrawerButtonVisible && (
|
||||
<QueueDrawerArea
|
||||
key="queue-drawer-button"
|
||||
animate="visible"
|
||||
exit="hidden"
|
||||
initial="hidden"
|
||||
variants={queueDrawerButtonVariants}
|
||||
whileHover={{ opacity: 1, scale: 2, transition: { duration: 0.5 } }}
|
||||
onMouseEnter={handleEnterDrawerButton}
|
||||
onMouseLeave={handleLeaveDrawerButton}
|
||||
>
|
||||
<TbArrowBarLeft size={12} />
|
||||
</QueueDrawerArea>
|
||||
)}
|
||||
return (
|
||||
<>
|
||||
<AnimatePresence
|
||||
initial={false}
|
||||
mode="wait"
|
||||
>
|
||||
{isQueueDrawerButtonVisible && (
|
||||
<QueueDrawerArea
|
||||
key="queue-drawer-button"
|
||||
animate="visible"
|
||||
exit="hidden"
|
||||
initial="hidden"
|
||||
variants={queueDrawerButtonVariants}
|
||||
whileHover={{ opacity: 1, scale: 2, transition: { duration: 0.5 } }}
|
||||
onMouseEnter={handleEnterDrawerButton}
|
||||
onMouseLeave={handleLeaveDrawerButton}
|
||||
>
|
||||
<TbArrowBarLeft size={12} />
|
||||
</QueueDrawerArea>
|
||||
)}
|
||||
|
||||
{drawer && (
|
||||
<QueueDrawer
|
||||
key="queue-drawer"
|
||||
animate="open"
|
||||
exit="closed"
|
||||
initial="closed"
|
||||
variants={queueDrawerVariants}
|
||||
onMouseLeave={() => {
|
||||
// The drawer will close due to the delay when setting isReorderingQueue
|
||||
setTimeout(() => {
|
||||
if (useAppStore.getState().isReorderingQueue) return;
|
||||
drawerHandler.close();
|
||||
}, 50);
|
||||
}}
|
||||
>
|
||||
<DrawerPlayQueue />
|
||||
</QueueDrawer>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</>
|
||||
);
|
||||
{drawer && (
|
||||
<QueueDrawer
|
||||
key="queue-drawer"
|
||||
animate="open"
|
||||
exit="closed"
|
||||
initial="closed"
|
||||
variants={queueDrawerVariants}
|
||||
onMouseLeave={() => {
|
||||
// The drawer will close due to the delay when setting isReorderingQueue
|
||||
setTimeout(() => {
|
||||
if (useAppStore.getState().isReorderingQueue) return;
|
||||
drawerHandler.close();
|
||||
}, 50);
|
||||
}}
|
||||
>
|
||||
<DrawerPlayQueue />
|
||||
</QueueDrawer>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,49 +14,49 @@ import macMinHover from './assets/min-mac-hover.png';
|
|||
import macMin from './assets/min-mac.png';
|
||||
|
||||
const WindowsContainer = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100vw;
|
||||
color: var(--window-bar-fg);
|
||||
background-color: var(--window-bar-bg);
|
||||
-webkit-app-region: drag;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100vw;
|
||||
color: var(--window-bar-fg);
|
||||
background-color: var(--window-bar-bg);
|
||||
-webkit-app-region: drag;
|
||||
`;
|
||||
|
||||
const WindowsButtonGroup = styled.div`
|
||||
display: flex;
|
||||
width: 130px;
|
||||
height: 100%;
|
||||
-webkit-app-region: no-drag;
|
||||
display: flex;
|
||||
width: 130px;
|
||||
height: 100%;
|
||||
-webkit-app-region: no-drag;
|
||||
`;
|
||||
|
||||
const WindowsButton = styled.div<{ $exit?: boolean }>`
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
-webkit-app-region: no-drag;
|
||||
width: 50px;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
-webkit-app-region: no-drag;
|
||||
width: 50px;
|
||||
height: 30px;
|
||||
|
||||
img {
|
||||
width: 35%;
|
||||
height: 50%;
|
||||
}
|
||||
img {
|
||||
width: 35%;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: ${({ $exit }) => ($exit ? 'var(--danger-color)' : 'rgba(125, 125, 125, 30%)')};
|
||||
}
|
||||
&:hover {
|
||||
background: ${({ $exit }) => ($exit ? 'var(--danger-color)' : 'rgba(125, 125, 125, 30%)')};
|
||||
}
|
||||
`;
|
||||
|
||||
const PlayerStatusContainer = styled.div`
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
max-width: 45vw;
|
||||
padding-left: 1rem;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
max-width: 45vw;
|
||||
padding-left: 1rem;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
`;
|
||||
|
||||
const browser = isElectron() ? window.electron.browser : null;
|
||||
|
|
@ -66,192 +66,193 @@ const maximize = () => browser.maximize();
|
|||
const unmaximize = () => browser.unmaximize();
|
||||
|
||||
interface WindowBarControlsProps {
|
||||
controls: {
|
||||
handleClose: () => void;
|
||||
handleMaximize: () => void;
|
||||
handleMinimize: () => void;
|
||||
};
|
||||
title: string;
|
||||
controls: {
|
||||
handleClose: () => void;
|
||||
handleMaximize: () => void;
|
||||
handleMinimize: () => void;
|
||||
};
|
||||
title: string;
|
||||
}
|
||||
|
||||
const WindowsControls = ({ controls, title }: WindowBarControlsProps) => {
|
||||
const { handleClose, handleMaximize, handleMinimize } = controls;
|
||||
const { handleClose, handleMaximize, handleMinimize } = controls;
|
||||
|
||||
return (
|
||||
<WindowsContainer>
|
||||
<PlayerStatusContainer>
|
||||
<img
|
||||
alt=""
|
||||
height={18}
|
||||
src={appIcon}
|
||||
width={18}
|
||||
/>
|
||||
{title}
|
||||
</PlayerStatusContainer>
|
||||
<WindowsButtonGroup>
|
||||
<WindowsButton
|
||||
role="button"
|
||||
onClick={handleMinimize}
|
||||
>
|
||||
<RiSubtractLine size={19} />
|
||||
</WindowsButton>
|
||||
<WindowsButton
|
||||
role="button"
|
||||
onClick={handleMaximize}
|
||||
>
|
||||
<RiCheckboxBlankLine size={13} />
|
||||
</WindowsButton>
|
||||
<WindowsButton
|
||||
$exit
|
||||
role="button"
|
||||
onClick={handleClose}
|
||||
>
|
||||
<RiCloseLine size={19} />
|
||||
</WindowsButton>
|
||||
</WindowsButtonGroup>
|
||||
</WindowsContainer>
|
||||
);
|
||||
return (
|
||||
<WindowsContainer>
|
||||
<PlayerStatusContainer>
|
||||
<img
|
||||
alt=""
|
||||
height={18}
|
||||
src={appIcon}
|
||||
width={18}
|
||||
/>
|
||||
{title}
|
||||
</PlayerStatusContainer>
|
||||
<WindowsButtonGroup>
|
||||
<WindowsButton
|
||||
role="button"
|
||||
onClick={handleMinimize}
|
||||
>
|
||||
<RiSubtractLine size={19} />
|
||||
</WindowsButton>
|
||||
<WindowsButton
|
||||
role="button"
|
||||
onClick={handleMaximize}
|
||||
>
|
||||
<RiCheckboxBlankLine size={13} />
|
||||
</WindowsButton>
|
||||
<WindowsButton
|
||||
$exit
|
||||
role="button"
|
||||
onClick={handleClose}
|
||||
>
|
||||
<RiCloseLine size={19} />
|
||||
</WindowsButton>
|
||||
</WindowsButtonGroup>
|
||||
</WindowsContainer>
|
||||
);
|
||||
};
|
||||
|
||||
const MacOsContainer = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100vw;
|
||||
-webkit-app-region: drag;
|
||||
color: var(--window-bar-fg);
|
||||
background-color: var(--window-bar-bg);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100vw;
|
||||
-webkit-app-region: drag;
|
||||
color: var(--window-bar-fg);
|
||||
background-color: var(--window-bar-bg);
|
||||
`;
|
||||
|
||||
const MacOsButtonGroup = styled.div`
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 0.5rem;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 20px);
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 0.5rem;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 20px);
|
||||
height: 100%;
|
||||
|
||||
-webkit-app-region: no-drag;
|
||||
-webkit-app-region: no-drag;
|
||||
`;
|
||||
|
||||
export const MacOsButton = styled.div<{
|
||||
maxButton?: boolean;
|
||||
minButton?: boolean;
|
||||
restoreButton?: boolean;
|
||||
maxButton?: boolean;
|
||||
minButton?: boolean;
|
||||
restoreButton?: boolean;
|
||||
}>`
|
||||
grid-row: 1 / span 1;
|
||||
grid-column: ${(props) => (props.minButton ? 2 : props.maxButton || props.restoreButton ? 3 : 1)};
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
user-select: none;
|
||||
grid-row: 1 / span 1;
|
||||
grid-column: ${(props) =>
|
||||
props.minButton ? 2 : props.maxButton || props.restoreButton ? 3 : 1};
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
user-select: none;
|
||||
|
||||
img {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
img {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
`;
|
||||
|
||||
const MacOsControls = ({ controls, title }: WindowBarControlsProps) => {
|
||||
const { handleClose, handleMaximize, handleMinimize } = controls;
|
||||
const { handleClose, handleMaximize, handleMinimize } = controls;
|
||||
|
||||
const [hoverMin, setHoverMin] = useState(false);
|
||||
const [hoverMax, setHoverMax] = useState(false);
|
||||
const [hoverClose, setHoverClose] = useState(false);
|
||||
const [hoverMin, setHoverMin] = useState(false);
|
||||
const [hoverMax, setHoverMax] = useState(false);
|
||||
const [hoverClose, setHoverClose] = useState(false);
|
||||
|
||||
return (
|
||||
<MacOsContainer>
|
||||
<MacOsButtonGroup>
|
||||
<MacOsButton
|
||||
minButton
|
||||
className="button"
|
||||
id="min-button"
|
||||
onClick={handleMinimize}
|
||||
onMouseLeave={() => setHoverMin(false)}
|
||||
onMouseOver={() => setHoverMin(true)}
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
className="icon"
|
||||
draggable="false"
|
||||
src={hoverMin ? macMinHover : macMin}
|
||||
/>
|
||||
</MacOsButton>
|
||||
<MacOsButton
|
||||
maxButton
|
||||
className="button"
|
||||
id="max-button"
|
||||
onClick={handleMaximize}
|
||||
onMouseLeave={() => setHoverMax(false)}
|
||||
onMouseOver={() => setHoverMax(true)}
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
className="icon"
|
||||
draggable="false"
|
||||
src={hoverMax ? macMaxHover : macMax}
|
||||
/>
|
||||
</MacOsButton>
|
||||
<MacOsButton
|
||||
className="button"
|
||||
id="close-button"
|
||||
onClick={handleClose}
|
||||
onMouseLeave={() => setHoverClose(false)}
|
||||
onMouseOver={() => setHoverClose(true)}
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
className="icon"
|
||||
draggable="false"
|
||||
src={hoverClose ? macCloseHover : macClose}
|
||||
/>
|
||||
</MacOsButton>
|
||||
</MacOsButtonGroup>
|
||||
<PlayerStatusContainer>{title}</PlayerStatusContainer>
|
||||
</MacOsContainer>
|
||||
);
|
||||
return (
|
||||
<MacOsContainer>
|
||||
<MacOsButtonGroup>
|
||||
<MacOsButton
|
||||
minButton
|
||||
className="button"
|
||||
id="min-button"
|
||||
onClick={handleMinimize}
|
||||
onMouseLeave={() => setHoverMin(false)}
|
||||
onMouseOver={() => setHoverMin(true)}
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
className="icon"
|
||||
draggable="false"
|
||||
src={hoverMin ? macMinHover : macMin}
|
||||
/>
|
||||
</MacOsButton>
|
||||
<MacOsButton
|
||||
maxButton
|
||||
className="button"
|
||||
id="max-button"
|
||||
onClick={handleMaximize}
|
||||
onMouseLeave={() => setHoverMax(false)}
|
||||
onMouseOver={() => setHoverMax(true)}
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
className="icon"
|
||||
draggable="false"
|
||||
src={hoverMax ? macMaxHover : macMax}
|
||||
/>
|
||||
</MacOsButton>
|
||||
<MacOsButton
|
||||
className="button"
|
||||
id="close-button"
|
||||
onClick={handleClose}
|
||||
onMouseLeave={() => setHoverClose(false)}
|
||||
onMouseOver={() => setHoverClose(true)}
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
className="icon"
|
||||
draggable="false"
|
||||
src={hoverClose ? macCloseHover : macClose}
|
||||
/>
|
||||
</MacOsButton>
|
||||
</MacOsButtonGroup>
|
||||
<PlayerStatusContainer>{title}</PlayerStatusContainer>
|
||||
</MacOsContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export const WindowBar = () => {
|
||||
const playerStatus = useCurrentStatus();
|
||||
const { currentSong, index, length } = useQueueStatus();
|
||||
const { windowBarStyle } = useWindowSettings();
|
||||
const playerStatus = useCurrentStatus();
|
||||
const { currentSong, index, length } = useQueueStatus();
|
||||
const { windowBarStyle } = useWindowSettings();
|
||||
|
||||
const statusString = playerStatus === PlayerStatus.PAUSED ? '(Paused) ' : '';
|
||||
const queueString = length ? `(${index + 1} / ${length}) ` : '';
|
||||
const title = length ? `${statusString}${queueString}${currentSong?.name}` : 'Feishin';
|
||||
document.title = title;
|
||||
const statusString = playerStatus === PlayerStatus.PAUSED ? '(Paused) ' : '';
|
||||
const queueString = length ? `(${index + 1} / ${length}) ` : '';
|
||||
const title = length ? `${statusString}${queueString}${currentSong?.name}` : 'Feishin';
|
||||
document.title = title;
|
||||
|
||||
const [max, setMax] = useState(false);
|
||||
const [max, setMax] = useState(false);
|
||||
|
||||
const handleMinimize = () => minimize();
|
||||
const handleMinimize = () => minimize();
|
||||
|
||||
const handleMaximize = useCallback(() => {
|
||||
if (max) {
|
||||
unmaximize();
|
||||
} else {
|
||||
maximize();
|
||||
}
|
||||
setMax(!max);
|
||||
}, [max]);
|
||||
const handleMaximize = useCallback(() => {
|
||||
if (max) {
|
||||
unmaximize();
|
||||
} else {
|
||||
maximize();
|
||||
}
|
||||
setMax(!max);
|
||||
}, [max]);
|
||||
|
||||
const handleClose = useCallback(() => close(), []);
|
||||
const handleClose = useCallback(() => close(), []);
|
||||
|
||||
return (
|
||||
<>
|
||||
{windowBarStyle === Platform.WINDOWS && (
|
||||
<WindowsControls
|
||||
controls={{ handleClose, handleMaximize, handleMinimize }}
|
||||
title={title}
|
||||
/>
|
||||
)}
|
||||
{windowBarStyle === Platform.MACOS && (
|
||||
<MacOsControls
|
||||
controls={{ handleClose, handleMaximize, handleMinimize }}
|
||||
title={title}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
{windowBarStyle === Platform.WINDOWS && (
|
||||
<WindowsControls
|
||||
controls={{ handleClose, handleMaximize, handleMinimize }}
|
||||
title={title}
|
||||
/>
|
||||
)}
|
||||
{windowBarStyle === Platform.MACOS && (
|
||||
<MacOsControls
|
||||
controls={{ handleClose, handleMaximize, handleMinimize }}
|
||||
title={title}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue