feat: add history back & forward for desktop app (#1926)

This commit is contained in:
Qi
2023-04-14 17:19:52 +08:00
committed by GitHub
parent bd387f6551
commit 261a41f8da
10 changed files with 72 additions and 65 deletions

View File

@@ -14,7 +14,7 @@ async function createWindow() {
const browserWindow = new BrowserWindow({ const browserWindow = new BrowserWindow({
titleBarStyle: isMacOS() ? 'hiddenInset' : 'default', titleBarStyle: isMacOS() ? 'hiddenInset' : 'default',
trafficLightPosition: { x: 20, y: 18 }, trafficLightPosition: { x: 24, y: 18 },
x: mainWindowState.x, x: mainWindowState.x,
y: mainWindowState.y, y: mainWindowState.y,
width: mainWindowState.width, width: mainWindowState.width,

View File

@@ -12,7 +12,8 @@ export const StyledCollapsedButton = styled('button')<{
}>(({ collapse, show = true, theme }) => { }>(({ collapse, show = true, theme }) => {
return { return {
width: '16px', width: '16px',
height: '16px', height: '100%',
...displayFlex('center', 'center'),
fontSize: '16px', fontSize: '16px',
position: 'absolute', position: 'absolute',
left: '0', left: '0',
@@ -21,9 +22,13 @@ export const StyledCollapsedButton = styled('button')<{
margin: 'auto', margin: 'auto',
color: theme.colors.iconColor, color: theme.colors.iconColor,
opacity: '.6', opacity: '.6',
transition: 'opacity .15s ease-in-out',
display: show ? 'flex' : 'none', display: show ? 'flex' : 'none',
svg: { svg: {
transform: `rotate(${collapse ? '0' : '-90'}deg)`, transform: `rotate(${collapse ? '-90' : '0'}deg)`,
},
':hover': {
opacity: '1',
}, },
}; };
}); });

View File

@@ -103,7 +103,7 @@ export const NavigationPath = ({
> >
<IconButton <IconButton
data-testid="navigation-path-expand-btn" data-testid="navigation-path-expand-btn"
size="middle" size="small"
className="collapse-btn" className="collapse-btn"
onClick={() => { onClick={() => {
setOpenExtend(!openExtend); setOpenExtend(!openExtend);
@@ -158,9 +158,7 @@ const NavigationPathExtendPanel = ({
show={open} show={open}
data-testid="navigation-path-expand-panel" data-testid="navigation-path-expand-panel"
> >
<div className="tree-container"> <TreeView data={data} indent={10} disableCollapse={true} />
<TreeView data={data} indent={10} disableCollapse={true} />
</div>
</StyledNavPathExtendContainer> </StyledNavPathExtendContainer>
); );
}; };

View File

@@ -55,12 +55,7 @@ export const StyledNavPathExtendContainer = styled('div')<{ show: boolean }>(
transition: 'top .15s', transition: 'top .15s',
fontSize: theme.font.sm, fontSize: theme.font.sm,
color: theme.colors.secondaryTextColor, color: theme.colors.secondaryTextColor,
paddingTop: '46px', padding: '46px 12px 0 15px',
paddingRight: '12px',
'.tree-container': {
padding: '0 12px 0 15px',
},
}; };
} }
); );

View File

@@ -3,7 +3,7 @@ import type { PageMeta } from '@blocksuite/store';
export function findPath(metas: PageMeta[], meta: PageMeta): PageMeta[] { export function findPath(metas: PageMeta[], meta: PageMeta): PageMeta[] {
function helper(group: PageMeta[]): PageMeta[] { function helper(group: PageMeta[]): PageMeta[] {
const last = group[group.length - 1]; const last = group[group.length - 1];
const parent = metas.find(m => m.subpageIds.includes(last.id)); const parent = metas.find(m => (m.subpageIds ?? []).includes(last.id));
if (parent) { if (parent) {
return helper([...group, parent]); return helper([...group, parent]);
} }

View File

@@ -0,0 +1,31 @@
import { IconButton } from '@affine/component';
import { ArrowLeftSmallIcon, ArrowRightSmallIcon } from '@blocksuite/icons';
import { StyledRouteNavigationWrapper } from './shared-styles';
export const RouteNavigation = () => {
if (!environment.isDesktop) {
return <></>;
}
return (
<StyledRouteNavigationWrapper>
<IconButton
size="middle"
onClick={() => {
window.history.back();
}}
>
<ArrowLeftSmallIcon />
</IconButton>
<IconButton
size="middle"
onClick={() => {
window.history.forward();
}}
style={{ marginLeft: '32px' }}
>
<ArrowRightSmallIcon />
</IconButton>
</StyledRouteNavigationWrapper>
);
};

View File

@@ -26,12 +26,13 @@ import { SidebarSwitch } from '../../affine/sidebar-switch';
import { ChangeLog } from './changeLog'; import { ChangeLog } from './changeLog';
import Favorite from './favorite'; import Favorite from './favorite';
import { Pinboard } from './Pinboard'; import { Pinboard } from './Pinboard';
import { RouteNavigation } from './RouteNavigation';
import { StyledListItem } from './shared-styles'; import { StyledListItem } from './shared-styles';
import { import {
StyledLink, StyledLink,
StyledNewPageButton, StyledNewPageButton,
StyledScrollWrapper, StyledScrollWrapper,
StyledSidebarSwitchWrapper, StyledSidebarHeader,
StyledSliderBar, StyledSliderBar,
StyledSliderBarInnerWrapper, StyledSliderBarInnerWrapper,
StyledSliderBarWrapper, StyledSliderBarWrapper,
@@ -115,13 +116,14 @@ export const WorkSpaceSliderBar: React.FC<WorkSpaceSliderBarProps> = ({
data-testid="sliderBar-root" data-testid="sliderBar-root"
> >
<StyledSliderBar> <StyledSliderBar>
<StyledSidebarSwitchWrapper> <StyledSidebarHeader>
<RouteNavigation />
<SidebarSwitch <SidebarSwitch
visible={sidebarOpen} visible={sidebarOpen}
tooltipContent={t('Collapse sidebar')} tooltipContent={t('Collapse sidebar')}
testid="sliderBar-arrowButton-collapse" testid="sliderBar-arrowButton-collapse"
/> />
</StyledSidebarSwitchWrapper> </StyledSidebarHeader>
<StyledSliderBarInnerWrapper data-testid="sliderBar-inner"> <StyledSliderBarInnerWrapper data-testid="sliderBar-inner">
<WorkspaceSelector <WorkspaceSelector
@@ -138,7 +140,6 @@ export const WorkSpaceSliderBar: React.FC<WorkSpaceSliderBarProps> = ({
<SearchIcon /> <SearchIcon />
{t('Quick search')} {t('Quick search')}
</StyledListItem> </StyledListItem>
<StyledListItem <StyledListItem
active={ active={
currentPath === currentPath ===
@@ -159,7 +160,6 @@ export const WorkSpaceSliderBar: React.FC<WorkSpaceSliderBarProps> = ({
{t('Workspace Settings')} {t('Workspace Settings')}
</StyledLink> </StyledLink>
</StyledListItem> </StyledListItem>
<StyledListItem <StyledListItem
active={ active={
currentPath === currentPath ===
@@ -175,7 +175,6 @@ export const WorkSpaceSliderBar: React.FC<WorkSpaceSliderBarProps> = ({
<span data-testid="all-pages">{t('All pages')}</span> <span data-testid="all-pages">{t('All pages')}</span>
</StyledLink> </StyledLink>
</StyledListItem> </StyledListItem>
<StyledScrollWrapper <StyledScrollWrapper
showTopBorder={!isScrollAtTop} showTopBorder={!isScrollAtTop}
onScroll={(e: UIEvent<HTMLDivElement>) => { onScroll={(e: UIEvent<HTMLDivElement>) => {
@@ -199,7 +198,7 @@ export const WorkSpaceSliderBar: React.FC<WorkSpaceSliderBarProps> = ({
/> />
)} )}
</StyledScrollWrapper> </StyledScrollWrapper>
<div style={{ height: 16 }}></div>
{currentWorkspace?.flavour === WorkspaceFlavour.AFFINE && {currentWorkspace?.flavour === WorkspaceFlavour.AFFINE &&
currentWorkspace.public ? ( currentWorkspace.public ? (
<StyledListItem> <StyledListItem>
@@ -236,9 +235,6 @@ export const WorkSpaceSliderBar: React.FC<WorkSpaceSliderBarProps> = ({
currentPath === currentPath ===
(currentWorkspaceId && paths.trash(currentWorkspaceId)) (currentWorkspaceId && paths.trash(currentWorkspaceId))
} }
style={{
marginTop: '16px',
}}
> >
<StyledLink <StyledLink
href={{ href={{

View File

@@ -18,6 +18,7 @@ export const StyledListItem = styled('div')<{
cursor: 'pointer', cursor: 'pointer',
marginBottom: '4px', marginBottom: '4px',
position: 'relative', position: 'relative',
flexShrink: 0,
userSelect: 'none', userSelect: 'none',
...displayFlex('flex-start', 'center'), ...displayFlex('flex-start', 'center'),
...(disabled ...(disabled
@@ -44,7 +45,8 @@ export const StyledCollapseButton = styled('button')<{
}>(({ collapse, show = true, theme }) => { }>(({ collapse, show = true, theme }) => {
return { return {
width: '16px', width: '16px',
height: '16px', height: '100%',
...displayFlex('center', 'center'),
fontSize: '16px', fontSize: '16px',
position: 'absolute', position: 'absolute',
left: '0', left: '0',
@@ -53,10 +55,14 @@ export const StyledCollapseButton = styled('button')<{
margin: 'auto', margin: 'auto',
color: theme.colors.iconColor, color: theme.colors.iconColor,
opacity: '.6', opacity: '.6',
transition: 'opacity .15s ease-in-out',
display: show ? 'flex' : 'none', display: show ? 'flex' : 'none',
svg: { svg: {
transform: `rotate(${collapse ? '0' : '-90'}deg)`, transform: `rotate(${collapse ? '0' : '-90'}deg)`,
}, },
':hover': {
opacity: '1',
},
}; };
}); });
@@ -205,3 +211,10 @@ export const StyledChangeLogWrapper = styled('div')<{
overflow: 'hidden', overflow: 'hidden',
}; };
}); });
export const StyledRouteNavigationWrapper = styled('div')({
height: '32px',
width: '80px',
marginRight: '16px',
...displayFlex('space-between', 'center'),
});

View File

@@ -25,7 +25,7 @@ export const StyledSliderBarWrapper = styled('div')<{
}; };
}); });
export const StyledSliderBar = styled('div')(({ theme }) => { export const StyledSliderBar = styled('div')(() => {
return { return {
whiteSpace: 'nowrap', whiteSpace: 'nowrap',
width: '100%', width: '100%',
@@ -34,19 +34,18 @@ export const StyledSliderBar = styled('div')(({ theme }) => {
flexShrink: 0, flexShrink: 0,
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
// overflow: 'hidden',
}; };
}); });
export const StyledSidebarSwitchWrapper = styled('div')(() => { export const StyledSidebarHeader = styled('div')(() => {
return { return {
height: '52px', height: '52px',
flexShrink: 0, flexShrink: 0,
padding: '0 16px', padding: '0 16px 0 10px',
WebkitAppRegion: 'drag', WebkitAppRegion: 'drag',
button: { button: {
WebkitAppRegion: 'no-drag', WebkitAppRegion: 'no-drag',
}, },
...displayFlex(macosElectron ? 'flex-end' : 'flex-start', 'center'), ...displayFlex(macosElectron ? 'flex-end' : 'space-between', 'center'),
}; };
}); });
export const StyledSliderBarInnerWrapper = styled('div')(() => { export const StyledSliderBarInnerWrapper = styled('div')(() => {
@@ -55,6 +54,9 @@ export const StyledSliderBarInnerWrapper = styled('div')(() => {
// overflowX: 'hidden', // overflowX: 'hidden',
// overflowY: 'auto', // overflowY: 'auto',
position: 'relative', position: 'relative',
height: 'calc(100% - 52px * 2)',
display: 'flex',
flexDirection: 'column',
}; };
}); });
@@ -75,7 +77,7 @@ export const StyledNewPageButton = styled('button')(({ theme }) => {
...displayFlex('flex-start', 'center'), ...displayFlex('flex-start', 'center'),
borderTop: '1px solid', borderTop: '1px solid',
borderColor: theme.colors.borderColor, borderColor: theme.colors.borderColor,
padding: '0 8px', padding: '0 8px 0 16px',
svg: { svg: {
fontSize: '20px', fontSize: '20px',
color: theme.colors.iconColor, color: theme.colors.iconColor,
@@ -105,44 +107,11 @@ 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',
};
}
);
export const StyledScrollWrapper = styled('div')<{ export const StyledScrollWrapper = styled('div')<{
showTopBorder: boolean; showTopBorder: boolean;
}>(({ showTopBorder, theme }) => { }>(({ showTopBorder, theme }) => {
return { return {
maxHeight: '360px',
overflowY: 'auto', overflowY: 'auto',
borderTop: '1px solid', borderTop: '1px solid',
borderColor: showTopBorder ? theme.colors.borderColor : 'transparent', borderColor: showTopBorder ? theme.colors.borderColor : 'transparent',

View File

@@ -12,7 +12,7 @@ const SIZE_CONFIG = {
areaSize: 20, areaSize: 20,
}, },
[SIZE_MIDDLE]: { [SIZE_MIDDLE]: {
iconSize: 16, iconSize: 20,
areaSize: 24, areaSize: 24,
}, },
[SIZE_NORMAL]: { [SIZE_NORMAL]: {