mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 12:55:00 +00:00
feat(core): persist right-sidebar open state and resize width (#10120)
This commit is contained in:
@@ -6,6 +6,7 @@ import { type To } from 'history';
|
||||
import { omit } from 'lodash-es';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
import type { GlobalState } from '../../storage';
|
||||
import type { WorkbenchNewTabHandler } from '../services/workbench-new-tab-handler';
|
||||
import type { WorkbenchDefaultState } from '../services/workbench-view-state';
|
||||
import { View } from './view';
|
||||
@@ -18,10 +19,14 @@ export type WorkbenchOpenOptions = {
|
||||
show?: boolean; // only for new tab
|
||||
};
|
||||
|
||||
const sidebarOpenKey = 'workbenchSidebarOpen';
|
||||
const sidebarWidthKey = 'workbenchSidebarWidth';
|
||||
|
||||
export class Workbench extends Entity {
|
||||
constructor(
|
||||
private readonly defaultState: WorkbenchDefaultState,
|
||||
private readonly newTabHandler: WorkbenchNewTabHandler
|
||||
private readonly newTabHandler: WorkbenchNewTabHandler,
|
||||
private readonly globalState: GlobalState
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -50,7 +55,20 @@ export class Workbench extends Entity {
|
||||
location$ = LiveData.computed(get => {
|
||||
return get(get(this.activeView$).location$);
|
||||
});
|
||||
sidebarOpen$ = new LiveData(false);
|
||||
sidebarOpen$ = LiveData.from(
|
||||
this.globalState.watch<boolean>(sidebarOpenKey),
|
||||
false
|
||||
);
|
||||
setSidebarOpen(open: boolean) {
|
||||
this.globalState.set(sidebarOpenKey, open);
|
||||
}
|
||||
sidebarWidth$ = LiveData.from(
|
||||
this.globalState.watch<number>(sidebarWidthKey),
|
||||
320
|
||||
);
|
||||
setSidebarWidth(width: number) {
|
||||
this.globalState.set(sidebarWidthKey, width);
|
||||
}
|
||||
|
||||
active(index: number | View) {
|
||||
if (typeof index === 'number') {
|
||||
@@ -85,15 +103,15 @@ export class Workbench extends Entity {
|
||||
}
|
||||
|
||||
openSidebar() {
|
||||
this.sidebarOpen$.next(true);
|
||||
this.setSidebarOpen(true);
|
||||
}
|
||||
|
||||
closeSidebar() {
|
||||
this.sidebarOpen$.next(false);
|
||||
this.setSidebarOpen(false);
|
||||
}
|
||||
|
||||
toggleSidebar() {
|
||||
this.sidebarOpen$.next(!this.sidebarOpen$.value);
|
||||
this.setSidebarOpen(!this.sidebarOpen$.value);
|
||||
}
|
||||
|
||||
open(to: To, option: WorkbenchOpenOptions = {}) {
|
||||
|
||||
@@ -15,7 +15,7 @@ import { type Framework } from '@toeverything/infra';
|
||||
|
||||
import { DesktopApiService } from '../desktop-api';
|
||||
import { PeekViewService } from '../peek-view';
|
||||
import { GlobalStateService } from '../storage';
|
||||
import { GlobalState, GlobalStateService } from '../storage';
|
||||
import { WorkspaceScope } from '../workspace';
|
||||
import { SidebarTab } from './entities/sidebar-tab';
|
||||
import { View } from './entities/view';
|
||||
@@ -39,7 +39,11 @@ export function configureWorkbenchCommonModule(services: Framework) {
|
||||
services
|
||||
.scope(WorkspaceScope)
|
||||
.service(WorkbenchService)
|
||||
.entity(Workbench, [WorkbenchDefaultState, WorkbenchNewTabHandler])
|
||||
.entity(Workbench, [
|
||||
WorkbenchDefaultState,
|
||||
WorkbenchNewTabHandler,
|
||||
GlobalState,
|
||||
])
|
||||
.entity(View)
|
||||
.scope(ViewScope)
|
||||
.service(ViewService, [ViewScope])
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ResizePanel } from '@affine/component/resize-panel';
|
||||
import { AffineErrorComponent } from '@affine/core/components/affine/affine-error-boundary/affine-error-fallback';
|
||||
import { rightSidebarWidthAtom } from '@affine/core/components/atoms';
|
||||
import { workbenchRoutes } from '@affine/core/desktop/workbench-router';
|
||||
import {
|
||||
appSettingAtom,
|
||||
@@ -8,7 +7,7 @@ import {
|
||||
useLiveData,
|
||||
useService,
|
||||
} from '@toeverything/infra';
|
||||
import { useAtom, useAtomValue } from 'jotai';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { type RouteObject, useLocation } from 'react-router-dom';
|
||||
|
||||
@@ -115,16 +114,24 @@ const MAX_SIDEBAR_WIDTH = 800;
|
||||
const WorkbenchSidebar = () => {
|
||||
const { clientBorder } = useAtomValue(appSettingAtom);
|
||||
|
||||
const [width, setWidth] = useAtom(rightSidebarWidthAtom);
|
||||
const [resizing, setResizing] = useState(false);
|
||||
|
||||
const workbench = useService(WorkbenchService).workbench;
|
||||
const [width, setWidth] = useState(workbench.sidebarWidth$.value ?? 0);
|
||||
|
||||
const views = useLiveData(workbench.views$);
|
||||
const activeView = useLiveData(workbench.activeView$);
|
||||
const sidebarOpen = useLiveData(workbench.sidebarOpen$);
|
||||
const [floating, setFloating] = useState(false);
|
||||
|
||||
const onWidthChanged = useCallback(
|
||||
(width: number) => {
|
||||
workbench.setSidebarWidth(width);
|
||||
setWidth(width);
|
||||
},
|
||||
[workbench]
|
||||
);
|
||||
|
||||
const handleOpenChange = useCallback(
|
||||
(open: boolean) => {
|
||||
if (open) {
|
||||
@@ -155,9 +162,10 @@ const WorkbenchSidebar = () => {
|
||||
onResizing={setResizing}
|
||||
className={styles.workbenchSidebar}
|
||||
data-client-border={clientBorder && sidebarOpen}
|
||||
open={sidebarOpen}
|
||||
open={sidebarOpen ?? false}
|
||||
onOpen={handleOpenChange}
|
||||
onWidthChange={setWidth}
|
||||
onWidthChanged={onWidthChanged}
|
||||
minWidth={MIN_SIDEBAR_WIDTH}
|
||||
maxWidth={MAX_SIDEBAR_WIDTH}
|
||||
unmountOnExit={false}
|
||||
|
||||
Reference in New Issue
Block a user