mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 04:18:54 +00:00
feat: add history back & forward for desktop app (#1926)
This commit is contained in:
@@ -14,7 +14,7 @@ async function createWindow() {
|
||||
|
||||
const browserWindow = new BrowserWindow({
|
||||
titleBarStyle: isMacOS() ? 'hiddenInset' : 'default',
|
||||
trafficLightPosition: { x: 20, y: 18 },
|
||||
trafficLightPosition: { x: 24, y: 18 },
|
||||
x: mainWindowState.x,
|
||||
y: mainWindowState.y,
|
||||
width: mainWindowState.width,
|
||||
|
||||
@@ -12,7 +12,8 @@ export const StyledCollapsedButton = styled('button')<{
|
||||
}>(({ collapse, show = true, theme }) => {
|
||||
return {
|
||||
width: '16px',
|
||||
height: '16px',
|
||||
height: '100%',
|
||||
...displayFlex('center', 'center'),
|
||||
fontSize: '16px',
|
||||
position: 'absolute',
|
||||
left: '0',
|
||||
@@ -21,9 +22,13 @@ export const StyledCollapsedButton = styled('button')<{
|
||||
margin: 'auto',
|
||||
color: theme.colors.iconColor,
|
||||
opacity: '.6',
|
||||
transition: 'opacity .15s ease-in-out',
|
||||
display: show ? 'flex' : 'none',
|
||||
svg: {
|
||||
transform: `rotate(${collapse ? '0' : '-90'}deg)`,
|
||||
transform: `rotate(${collapse ? '-90' : '0'}deg)`,
|
||||
},
|
||||
':hover': {
|
||||
opacity: '1',
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
@@ -103,7 +103,7 @@ export const NavigationPath = ({
|
||||
>
|
||||
<IconButton
|
||||
data-testid="navigation-path-expand-btn"
|
||||
size="middle"
|
||||
size="small"
|
||||
className="collapse-btn"
|
||||
onClick={() => {
|
||||
setOpenExtend(!openExtend);
|
||||
@@ -158,9 +158,7 @@ const NavigationPathExtendPanel = ({
|
||||
show={open}
|
||||
data-testid="navigation-path-expand-panel"
|
||||
>
|
||||
<div className="tree-container">
|
||||
<TreeView data={data} indent={10} disableCollapse={true} />
|
||||
</div>
|
||||
</StyledNavPathExtendContainer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -55,12 +55,7 @@ export const StyledNavPathExtendContainer = styled('div')<{ show: boolean }>(
|
||||
transition: 'top .15s',
|
||||
fontSize: theme.font.sm,
|
||||
color: theme.colors.secondaryTextColor,
|
||||
paddingTop: '46px',
|
||||
paddingRight: '12px',
|
||||
|
||||
'.tree-container': {
|
||||
padding: '0 12px 0 15px',
|
||||
},
|
||||
padding: '46px 12px 0 15px',
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { PageMeta } from '@blocksuite/store';
|
||||
export function findPath(metas: PageMeta[], meta: PageMeta): PageMeta[] {
|
||||
function helper(group: PageMeta[]): PageMeta[] {
|
||||
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) {
|
||||
return helper([...group, parent]);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
@@ -26,12 +26,13 @@ import { SidebarSwitch } from '../../affine/sidebar-switch';
|
||||
import { ChangeLog } from './changeLog';
|
||||
import Favorite from './favorite';
|
||||
import { Pinboard } from './Pinboard';
|
||||
import { RouteNavigation } from './RouteNavigation';
|
||||
import { StyledListItem } from './shared-styles';
|
||||
import {
|
||||
StyledLink,
|
||||
StyledNewPageButton,
|
||||
StyledScrollWrapper,
|
||||
StyledSidebarSwitchWrapper,
|
||||
StyledSidebarHeader,
|
||||
StyledSliderBar,
|
||||
StyledSliderBarInnerWrapper,
|
||||
StyledSliderBarWrapper,
|
||||
@@ -115,13 +116,14 @@ export const WorkSpaceSliderBar: React.FC<WorkSpaceSliderBarProps> = ({
|
||||
data-testid="sliderBar-root"
|
||||
>
|
||||
<StyledSliderBar>
|
||||
<StyledSidebarSwitchWrapper>
|
||||
<StyledSidebarHeader>
|
||||
<RouteNavigation />
|
||||
<SidebarSwitch
|
||||
visible={sidebarOpen}
|
||||
tooltipContent={t('Collapse sidebar')}
|
||||
testid="sliderBar-arrowButton-collapse"
|
||||
/>
|
||||
</StyledSidebarSwitchWrapper>
|
||||
</StyledSidebarHeader>
|
||||
|
||||
<StyledSliderBarInnerWrapper data-testid="sliderBar-inner">
|
||||
<WorkspaceSelector
|
||||
@@ -138,7 +140,6 @@ export const WorkSpaceSliderBar: React.FC<WorkSpaceSliderBarProps> = ({
|
||||
<SearchIcon />
|
||||
{t('Quick search')}
|
||||
</StyledListItem>
|
||||
|
||||
<StyledListItem
|
||||
active={
|
||||
currentPath ===
|
||||
@@ -159,7 +160,6 @@ export const WorkSpaceSliderBar: React.FC<WorkSpaceSliderBarProps> = ({
|
||||
{t('Workspace Settings')}
|
||||
</StyledLink>
|
||||
</StyledListItem>
|
||||
|
||||
<StyledListItem
|
||||
active={
|
||||
currentPath ===
|
||||
@@ -175,7 +175,6 @@ export const WorkSpaceSliderBar: React.FC<WorkSpaceSliderBarProps> = ({
|
||||
<span data-testid="all-pages">{t('All pages')}</span>
|
||||
</StyledLink>
|
||||
</StyledListItem>
|
||||
|
||||
<StyledScrollWrapper
|
||||
showTopBorder={!isScrollAtTop}
|
||||
onScroll={(e: UIEvent<HTMLDivElement>) => {
|
||||
@@ -199,7 +198,7 @@ export const WorkSpaceSliderBar: React.FC<WorkSpaceSliderBarProps> = ({
|
||||
/>
|
||||
)}
|
||||
</StyledScrollWrapper>
|
||||
|
||||
<div style={{ height: 16 }}></div>
|
||||
{currentWorkspace?.flavour === WorkspaceFlavour.AFFINE &&
|
||||
currentWorkspace.public ? (
|
||||
<StyledListItem>
|
||||
@@ -236,9 +235,6 @@ export const WorkSpaceSliderBar: React.FC<WorkSpaceSliderBarProps> = ({
|
||||
currentPath ===
|
||||
(currentWorkspaceId && paths.trash(currentWorkspaceId))
|
||||
}
|
||||
style={{
|
||||
marginTop: '16px',
|
||||
}}
|
||||
>
|
||||
<StyledLink
|
||||
href={{
|
||||
|
||||
@@ -18,6 +18,7 @@ export const StyledListItem = styled('div')<{
|
||||
cursor: 'pointer',
|
||||
marginBottom: '4px',
|
||||
position: 'relative',
|
||||
flexShrink: 0,
|
||||
userSelect: 'none',
|
||||
...displayFlex('flex-start', 'center'),
|
||||
...(disabled
|
||||
@@ -44,7 +45,8 @@ export const StyledCollapseButton = styled('button')<{
|
||||
}>(({ collapse, show = true, theme }) => {
|
||||
return {
|
||||
width: '16px',
|
||||
height: '16px',
|
||||
height: '100%',
|
||||
...displayFlex('center', 'center'),
|
||||
fontSize: '16px',
|
||||
position: 'absolute',
|
||||
left: '0',
|
||||
@@ -53,10 +55,14 @@ export const StyledCollapseButton = styled('button')<{
|
||||
margin: 'auto',
|
||||
color: theme.colors.iconColor,
|
||||
opacity: '.6',
|
||||
transition: 'opacity .15s ease-in-out',
|
||||
display: show ? 'flex' : 'none',
|
||||
svg: {
|
||||
transform: `rotate(${collapse ? '0' : '-90'}deg)`,
|
||||
},
|
||||
':hover': {
|
||||
opacity: '1',
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
@@ -205,3 +211,10 @@ export const StyledChangeLogWrapper = styled('div')<{
|
||||
overflow: 'hidden',
|
||||
};
|
||||
});
|
||||
|
||||
export const StyledRouteNavigationWrapper = styled('div')({
|
||||
height: '32px',
|
||||
width: '80px',
|
||||
marginRight: '16px',
|
||||
...displayFlex('space-between', 'center'),
|
||||
});
|
||||
|
||||
@@ -25,7 +25,7 @@ export const StyledSliderBarWrapper = styled('div')<{
|
||||
};
|
||||
});
|
||||
|
||||
export const StyledSliderBar = styled('div')(({ theme }) => {
|
||||
export const StyledSliderBar = styled('div')(() => {
|
||||
return {
|
||||
whiteSpace: 'nowrap',
|
||||
width: '100%',
|
||||
@@ -34,19 +34,18 @@ export const StyledSliderBar = styled('div')(({ theme }) => {
|
||||
flexShrink: 0,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
// overflow: 'hidden',
|
||||
};
|
||||
});
|
||||
export const StyledSidebarSwitchWrapper = styled('div')(() => {
|
||||
export const StyledSidebarHeader = styled('div')(() => {
|
||||
return {
|
||||
height: '52px',
|
||||
flexShrink: 0,
|
||||
padding: '0 16px',
|
||||
padding: '0 16px 0 10px',
|
||||
WebkitAppRegion: 'drag',
|
||||
button: {
|
||||
WebkitAppRegion: 'no-drag',
|
||||
},
|
||||
...displayFlex(macosElectron ? 'flex-end' : 'flex-start', 'center'),
|
||||
...displayFlex(macosElectron ? 'flex-end' : 'space-between', 'center'),
|
||||
};
|
||||
});
|
||||
export const StyledSliderBarInnerWrapper = styled('div')(() => {
|
||||
@@ -55,6 +54,9 @@ export const StyledSliderBarInnerWrapper = styled('div')(() => {
|
||||
// overflowX: 'hidden',
|
||||
// overflowY: 'auto',
|
||||
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'),
|
||||
borderTop: '1px solid',
|
||||
borderColor: theme.colors.borderColor,
|
||||
padding: '0 8px',
|
||||
padding: '0 8px 0 16px',
|
||||
svg: {
|
||||
fontSize: '20px',
|
||||
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')<{
|
||||
showTopBorder: boolean;
|
||||
}>(({ showTopBorder, theme }) => {
|
||||
return {
|
||||
maxHeight: '360px',
|
||||
overflowY: 'auto',
|
||||
borderTop: '1px solid',
|
||||
borderColor: showTopBorder ? theme.colors.borderColor : 'transparent',
|
||||
|
||||
@@ -12,7 +12,7 @@ const SIZE_CONFIG = {
|
||||
areaSize: 20,
|
||||
},
|
||||
[SIZE_MIDDLE]: {
|
||||
iconSize: 16,
|
||||
iconSize: 20,
|
||||
areaSize: 24,
|
||||
},
|
||||
[SIZE_NORMAL]: {
|
||||
|
||||
Reference in New Issue
Block a user