fix: give electron app with minWidth = 640px (#1785)

This commit is contained in:
Peng Xiao
2023-04-03 15:20:58 +08:00
committed by GitHub
parent 487ef35563
commit 2cf8ab434e
10 changed files with 131 additions and 89 deletions

View File

@@ -18,6 +18,7 @@ async function createWindow() {
x: mainWindowState.x, x: mainWindowState.x,
y: mainWindowState.y, y: mainWindowState.y,
width: mainWindowState.width, width: mainWindowState.width,
minWidth: 640,
transparent: true, transparent: true,
visualEffectState: 'active', visualEffectState: 'active',
vibrancy: 'under-window', vibrancy: 'under-window',

View File

@@ -152,7 +152,7 @@ export const PageList: React.FC<PageListProps> = ({
{list.map((pageMeta, index) => { {list.map((pageMeta, index) => {
return ( return (
<StyledTableRow <StyledTableRow
data-testid={`page-list-item-${pageMeta.id}}`} data-testid={`page-list-item-${pageMeta.id}`}
key={`${pageMeta.id}-${index}`} key={`${pageMeta.id}-${index}`}
> >
<TableCell <TableCell

View File

@@ -5,8 +5,9 @@ export const StyledTableContainer = styled('div')(({ theme }) => {
return { return {
height: 'calc(100vh - 52px)', height: 'calc(100vh - 52px)',
padding: '78px 72px', padding: '78px 72px',
maxWidth: '100%',
overflowY: 'auto', overflowY: 'auto',
[theme.breakpoints.down('sm')]: { [theme.breakpoints.down('md')]: {
padding: '12px 24px', padding: '12px 24px',
}, },
}; };

View File

@@ -4,7 +4,10 @@ import type { HTMLAttributes, PropsWithChildren } from 'react';
import type React from 'react'; import type React from 'react';
import { forwardRef, useEffect, useMemo, useState } from 'react'; import { forwardRef, useEffect, useMemo, useState } from 'react';
import { useSidebarStatus } from '../../../hooks/affine/use-sidebar-status'; import {
useSidebarFloating,
useSidebarStatus,
} from '../../../hooks/affine/use-sidebar-status';
import { SidebarSwitch } from '../../affine/sidebar-switch'; import { SidebarSwitch } from '../../affine/sidebar-switch';
import { EditorOptionMenu } from './header-right-items/EditorOptionMenu'; import { EditorOptionMenu } from './header-right-items/EditorOptionMenu';
import SyncUser from './header-right-items/SyncUser'; import SyncUser from './header-right-items/SyncUser';
@@ -66,10 +69,16 @@ export const Header = forwardRef<
setShowWarning(shouldShowWarning()); setShowWarning(shouldShowWarning());
}, []); }, []);
const [open] = useSidebarStatus(); const [open] = useSidebarStatus();
const sidebarFloating = useSidebarFloating();
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<StyledHeaderContainer ref={ref} hasWarning={showWarning} {...props}> <StyledHeaderContainer
sidebarFloating={sidebarFloating && open}
ref={ref}
hasWarning={showWarning}
{...props}
>
<BrowserWarning <BrowserWarning
show={showWarning} show={showWarning}
onClose={() => { onClose={() => {

View File

@@ -7,7 +7,8 @@ import {
export const StyledHeaderContainer = styled('div')<{ export const StyledHeaderContainer = styled('div')<{
hasWarning: boolean; hasWarning: boolean;
}>(({ theme, hasWarning }) => { sidebarFloating: boolean;
}>(({ theme, hasWarning, sidebarFloating }) => {
return { return {
height: hasWarning ? '96px' : '52px', height: hasWarning ? '96px' : '52px',
flexShrink: 0, flexShrink: 0,
@@ -15,7 +16,7 @@ export const StyledHeaderContainer = styled('div')<{
top: 0, top: 0,
background: theme.colors.pageBackground, background: theme.colors.pageBackground,
zIndex: 1, zIndex: 1,
WebkitAppRegion: 'drag', WebkitAppRegion: sidebarFloating ? '' : 'drag',
button: { button: {
WebkitAppRegion: 'no-drag', WebkitAppRegion: 'no-drag',
}, },

View File

@@ -32,8 +32,6 @@ import {
StyledSliderBarInnerWrapper, StyledSliderBarInnerWrapper,
StyledSliderBarWrapper, StyledSliderBarWrapper,
StyledSliderModalBackground, StyledSliderModalBackground,
StyledSliderResizer,
StyledSliderResizerInner,
} from './style'; } from './style';
import { WorkspaceSelector } from './WorkspaceSelector'; import { WorkspaceSelector } from './WorkspaceSelector';
@@ -81,38 +79,17 @@ export const WorkSpaceSliderBar: React.FC<WorkSpaceSliderBarProps> = ({
openPage(page.id); openPage(page.id);
}, [createPage, openPage]); }, [createPage, openPage]);
const floatingSlider = useSidebarFloating(); const floatingSlider = useSidebarFloating();
const [sliderWidth, setSliderWidth] = useSidebarWidth(); const [sliderWidth] = useSidebarWidth();
const [isResizing, setIsResizing] = useSidebarResizing(); const [isResizing] = useSidebarResizing();
const show = isPublicWorkspace ? false : sidebarOpen; const show = isPublicWorkspace ? false : sidebarOpen;
const actualWidth = floatingSlider ? 'calc(10vw + 400px)' : sliderWidth; const actualWidth = floatingSlider ? 'calc(10vw + 400px)' : sliderWidth;
const onResizeStart = useCallback(() => {
let resized = false;
function onMouseMove(e: MouseEvent) {
const newWidth = Math.min(480, Math.max(e.clientX, 256));
setSliderWidth(newWidth);
setIsResizing(true);
resized = true;
}
document.addEventListener('mousemove', onMouseMove);
document.addEventListener(
'mouseup',
() => {
// if not resized, toggle sidebar
if (!resized) {
setSidebarOpen(o => !o);
}
setIsResizing(false);
document.removeEventListener('mousemove', onMouseMove);
},
{ once: true }
);
}, [setIsResizing, setSidebarOpen, setSliderWidth]);
useEffect(() => { useEffect(() => {
window.apis?.onSidebarVisibilityChange(sidebarOpen); window.apis?.onSidebarVisibilityChange(sidebarOpen);
}, [sidebarOpen]); }, [sidebarOpen]);
return ( return (
<> <>
<StyledSliderBarWrapper <StyledSliderBarWrapper
resizing={isResizing}
floating={floatingSlider} floating={floatingSlider}
show={show} show={show}
style={{ width: actualWidth }} style={{ width: actualWidth }}
@@ -222,15 +199,6 @@ export const WorkSpaceSliderBar: React.FC<WorkSpaceSliderBarProps> = ({
<PlusIcon /> {t('New Page')} <PlusIcon /> {t('New Page')}
</StyledNewPageButton> </StyledNewPageButton>
</StyledSliderBar> </StyledSliderBar>
{!floatingSlider && sidebarOpen && (
<StyledSliderResizer
data-testid="sliderBar-resizer"
isResizing={isResizing}
onMouseDown={onResizeStart}
>
<StyledSliderResizerInner isResizing={isResizing} />
</StyledSliderResizer>
)}
</StyledSliderBarWrapper> </StyledSliderBarWrapper>
<StyledSliderModalBackground <StyledSliderModalBackground
data-testid="sliderBar-modalBackground" data-testid="sliderBar-modalBackground"

View File

@@ -6,7 +6,8 @@ const macosElectron = environment.isDesktop && environment.isMacOs;
export const StyledSliderBarWrapper = styled('div')<{ export const StyledSliderBarWrapper = styled('div')<{
show: boolean; show: boolean;
floating: boolean; floating: boolean;
}>(({ theme, show, floating }) => { resizing: boolean;
}>(({ theme, show, floating, resizing }) => {
return { return {
height: '100%', height: '100%',
position: 'absolute', position: 'absolute',
@@ -14,12 +15,12 @@ export const StyledSliderBarWrapper = styled('div')<{
userSelect: 'none', userSelect: 'none',
}, },
zIndex: theme.zIndex.modal, zIndex: theme.zIndex.modal,
transition: 'transform .25s', transition: resizing ? '' : 'transform .3s',
transform: show ? 'translateX(0)' : 'translateX(-100%)', transform: show ? 'translateX(0)' : 'translateX(-100%)',
maxWidth: floating ? undefined : 'calc(100vw - 698px)', maxWidth: floating ? undefined : 'calc(100vw - 698px)',
background: background:
!floating && macosElectron ? 'transparent' : theme.colors.hubBackground, !floating && macosElectron ? 'transparent' : theme.colors.hubBackground,
borderRight: '1px solid', borderRight: macosElectron ? '' : '1px solid',
borderColor: theme.colors.borderColor, borderColor: theme.colors.borderColor,
}; };
}); });
@@ -41,6 +42,10 @@ export const StyledSidebarSwitchWrapper = styled('div')(() => {
height: '52px', height: '52px',
flexShrink: 0, flexShrink: 0,
padding: '0 16px', padding: '0 16px',
WebkitAppRegion: 'drag',
button: {
WebkitAppRegion: 'no-drag',
},
...displayFlex(macosElectron ? 'flex-end' : 'flex-start', 'center'), ...displayFlex(macosElectron ? 'flex-end' : 'flex-start', 'center'),
}; };
}); });
@@ -100,35 +105,3 @@ export const StyledSliderModalBackground = styled('div')<{ active: boolean }>(
}; };
} }
); );
export const StyledSliderResizer = styled('div')<{ isResizing: boolean }>(
() => {
return {
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
width: '12px',
transform: 'translateX(50%)',
cursor: 'col-resize',
zIndex: 1,
userSelect: 'none',
':hover > *': {
background: 'rgba(0, 0, 0, 0.1)',
},
};
}
);
export const StyledSliderResizerInner = styled('div')<{ isResizing: boolean }>(
({ isResizing }) => {
return {
transition: 'background .15s .1s',
position: 'absolute',
top: 0,
right: '50%',
bottom: 0,
transform: 'translateX(0.5px)',
width: '2px',
background: isResizing ? 'rgba(0, 0, 0, 0.1)' : 'transparent',
};
}
);

View File

@@ -47,6 +47,9 @@ import {
MainContainer, MainContainer,
MainContainerWrapper, MainContainerWrapper,
StyledPage, StyledPage,
StyledSliderResizer,
StyledSliderResizerInner,
StyledSpacer,
StyledToolWrapper, StyledToolWrapper,
} from './styles'; } from './styles';
@@ -255,14 +258,38 @@ export const WorkspaceLayoutInner: React.FC<React.PropsWithChildren> = ({
const handleOpenQuickSearchModal = useCallback(() => { const handleOpenQuickSearchModal = useCallback(() => {
setOpenQuickSearchModalAtom(true); setOpenQuickSearchModalAtom(true);
}, [setOpenQuickSearchModalAtom]); }, [setOpenQuickSearchModalAtom]);
const [resizingSidebar] = useSidebarResizing(); const [resizingSidebar, setIsResizing] = useSidebarResizing();
const lock = useAtomValue(workspaceLockAtom); const lock = useAtomValue(workspaceLockAtom);
const [sidebarOpen] = useSidebarStatus(); const [sidebarOpen, setSidebarOpen] = useSidebarStatus();
const sidebarFloating = useSidebarFloating(); const sidebarFloating = useSidebarFloating();
const [sidebarWidth] = useSidebarWidth(); const [sidebarWidth, setSliderWidth] = useSidebarWidth();
const paddingLeft = const actualSidebarWidth = sidebarFloating || !sidebarOpen ? 0 : sidebarWidth;
sidebarFloating || !sidebarOpen ? '0' : `${sidebarWidth}px`; const width = `calc(100% - ${actualSidebarWidth}px)`;
const [resizing] = useSidebarResizing(); const [resizing] = useSidebarResizing();
const onResizeStart = useCallback(() => {
let resized = false;
function onMouseMove(e: MouseEvent) {
const newWidth = Math.min(480, Math.max(e.clientX, 256));
setSliderWidth(newWidth);
setIsResizing(true);
resized = true;
}
document.addEventListener('mousemove', onMouseMove);
document.addEventListener(
'mouseup',
() => {
// if not resized, toggle sidebar
if (!resized) {
setSidebarOpen(o => !o);
}
setIsResizing(false);
document.removeEventListener('mousemove', onMouseMove);
},
{ once: true }
);
}, [setIsResizing, setSidebarOpen, setSliderWidth]);
if (lock) { if (lock) {
return <PageLoading />; return <PageLoading />;
} }
@@ -284,10 +311,23 @@ export const WorkspaceLayoutInner: React.FC<React.PropsWithChildren> = ({
currentPath={router.asPath.split('?')[0]} currentPath={router.asPath.split('?')[0]}
paths={isPublicWorkspace ? publicPathGenerator : pathGenerator} paths={isPublicWorkspace ? publicPathGenerator : pathGenerator}
/> />
<MainContainerWrapper <StyledSpacer
floating={sidebarFloating}
resizing={resizing} resizing={resizing}
style={{ paddingLeft: paddingLeft }} sidebarOpen={sidebarOpen}
style={{ width: actualSidebarWidth }}
> >
{!sidebarFloating && sidebarOpen && (
<StyledSliderResizer
data-testid="sliderBar-resizer"
isResizing={resizing}
onMouseDown={onResizeStart}
>
<StyledSliderResizerInner isResizing={resizing} />
</StyledSliderResizer>
)}
</StyledSpacer>
<MainContainerWrapper resizing={resizing} style={{ width: width }}>
<MainContainer className="main-container"> <MainContainer className="main-container">
<AffineWorkspaceEffect /> <AffineWorkspaceEffect />
{children} {children}

View File

@@ -18,6 +18,20 @@ export const StyledPage = styled('div')<{ resizing?: boolean }>(
} }
); );
export const StyledSpacer = styled('div')<{
sidebarOpen: boolean;
resizing: boolean;
floating: boolean;
}>(({ resizing, sidebarOpen, floating }) => {
return {
position: 'relative',
flexGrow: 1,
maxWidth: 'calc(100vw - 698px)',
minWidth: !floating && sidebarOpen ? '256px' : '0',
transition: resizing ? '' : 'width .3s, min-width .3s',
};
});
export const StyledWrapper = styled('div')(() => { export const StyledWrapper = styled('div')(() => {
return { return {
flexGrow: 1, flexGrow: 1,
@@ -27,14 +41,13 @@ export const StyledWrapper = styled('div')(() => {
}); });
export const MainContainerWrapper = styled('div')<{ resizing: boolean }>( export const MainContainerWrapper = styled('div')<{ resizing: boolean }>(
({ theme, resizing }) => { ({ resizing }) => {
return { return {
display: 'flex', display: 'flex',
flexGrow: 1, flexGrow: 1,
position: 'relative', position: 'relative',
maxWidth: '100vw', maxWidth: '100vw',
overflow: 'auto', overflow: 'auto',
transition: resizing ? '' : 'padding-left .25s',
}; };
} }
); );
@@ -43,10 +56,14 @@ export const MainContainer = styled('div')(({ theme }) => {
return { return {
position: 'relative', position: 'relative',
flexGrow: 1, flexGrow: 1,
maxWidth: '100%',
backgroundColor: theme.colors.pageBackground, backgroundColor: theme.colors.pageBackground,
[theme.breakpoints.up('md')]: { [theme.breakpoints.up('md')]: {
minWidth: '686px', minWidth: '686px',
}, },
[theme.breakpoints.down('sm')]: {
minWidth: '550px',
},
}; };
}); });
@@ -65,3 +82,36 @@ export const StyledToolWrapper = styled('div')(({ theme }) => {
}, },
}; };
}); });
export const StyledSliderResizer = styled('div')<{ isResizing: boolean }>(
({ theme }) => {
return {
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
width: '12px',
transform: 'translateX(50%)',
cursor: 'col-resize',
zIndex: theme.zIndex.modal,
userSelect: 'none',
':hover > *': {
background: 'rgba(0, 0, 0, 0.1)',
},
};
}
);
export const StyledSliderResizerInner = styled('div')<{ isResizing: boolean }>(
({ isResizing }) => {
return {
transition: 'background .15s .1s',
position: 'absolute',
top: 0,
right: '50%',
bottom: 0,
transform: 'translateX(0.5px)',
width: '2px',
background: isResizing ? 'rgba(0, 0, 0, 0.1)' : 'transparent',
};
}
);

View File

@@ -8,12 +8,8 @@ export const StyledTable = styled('table')<{ tableLayout: 'auto' | 'fixed' }>(
color: theme.colors.textColor, color: theme.colors.textColor,
tableLayout, tableLayout,
width: '100%', width: '100%',
minWidth: '600px',
borderCollapse: 'separate', borderCollapse: 'separate',
borderSpacing: '0', borderSpacing: '0',
[theme.breakpoints.down('sm')]: {
minWidth: 'unset',
},
}; };
} }
); );
@@ -45,6 +41,9 @@ export const StyledTableHead = styled('thead')(() => {
return { return {
fontWeight: 500, fontWeight: 500,
tr: { tr: {
td: {
whiteSpace: 'nowrap',
},
':hover': { ':hover': {
td: { td: {
background: 'unset', background: 'unset',