From d089470bbfe4d2b5e691a774e137f9fee3cdc883 Mon Sep 17 00:00:00 2001 From: pengx17 Date: Fri, 6 Sep 2024 09:25:20 +0000 Subject: [PATCH] feat(electron): electron shell skeleton (#8127) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix AF-1331
🎥 Video uploaded on Graphite:
missing - per split view skeleton - per route skeleton --- .../component/src/ui/skeleton/index.css.ts | 3 +- .../component/src/ui/skeleton/skeleton.tsx | 2 + .../component/src/ui/skeleton/types.ts | 5 + .../src/components/affine/app-container.tsx | 15 ++- .../components/app-sidebar/fallback.css.ts | 32 ++++- .../core/src/components/app-sidebar/index.tsx | 119 +++++++++++++----- .../src/components/root-app-sidebar/index.tsx | 7 +- .../src/components/workspace/index.css.ts | 9 ++ .../core/src/components/workspace/index.tsx | 9 +- .../workbench/view/split-view/panel.tsx | 16 ++- .../workbench/view/split-view/split-view.tsx | 21 +++- .../core/src/pages/workspace/index.tsx | 4 +- packages/frontend/electron/renderer/app.tsx | 2 +- .../electron/renderer/shell/shell.css.ts | 27 +++- .../electron/renderer/shell/shell.tsx | 7 +- packages/frontend/mobile/src/app.tsx | 2 +- .../mobile/src/pages/workspace/layout.tsx | 2 +- 17 files changed, 223 insertions(+), 59 deletions(-) diff --git a/packages/frontend/component/src/ui/skeleton/index.css.ts b/packages/frontend/component/src/ui/skeleton/index.css.ts index 8d46768464..84d7670d86 100644 --- a/packages/frontend/component/src/ui/skeleton/index.css.ts +++ b/packages/frontend/component/src/ui/skeleton/index.css.ts @@ -29,6 +29,7 @@ const waveKeyframes = keyframes({ export const root = style({ display: 'block', width: '100%', + maxWidth: '100%', height: defaultHeight, flexShrink: 0, /** @@ -51,7 +52,7 @@ export const variant = { borderRadius: '50%', }), rectangular: style({ - borderRadius: '0px', + borderRadius: '4px', }), rounded: style({ borderRadius: '8px', diff --git a/packages/frontend/component/src/ui/skeleton/skeleton.tsx b/packages/frontend/component/src/ui/skeleton/skeleton.tsx index 404e9817a7..624a56df3f 100644 --- a/packages/frontend/component/src/ui/skeleton/skeleton.tsx +++ b/packages/frontend/component/src/ui/skeleton/skeleton.tsx @@ -16,6 +16,7 @@ export const Skeleton = ({ variant = 'text', children, + flex, width: _width, height: _height, style: _style, @@ -29,6 +30,7 @@ export const Skeleton = ({ const style = { width, height, + flex, ..._style, }; diff --git a/packages/frontend/component/src/ui/skeleton/types.ts b/packages/frontend/component/src/ui/skeleton/types.ts index bda6b78418..643cee5724 100644 --- a/packages/frontend/component/src/ui/skeleton/types.ts +++ b/packages/frontend/component/src/ui/skeleton/types.ts @@ -28,6 +28,11 @@ export interface SkeletonProps * Number values are treated as pixels. */ height?: number | string; + + /** + * Flex of the skeleton. + */ + flex?: number | string; } export type PickStringFromUnion = T extends string ? T : never; diff --git a/packages/frontend/core/src/components/affine/app-container.tsx b/packages/frontend/core/src/components/affine/app-container.tsx index fbac733a2d..3d4bc9386c 100644 --- a/packages/frontend/core/src/components/affine/app-container.tsx +++ b/packages/frontend/core/src/components/affine/app-container.tsx @@ -1,11 +1,11 @@ -import type { ReactElement } from 'react'; +import type { PropsWithChildren, ReactElement } from 'react'; import { useAppSettingHelper } from '../../hooks/affine/use-app-setting-helper'; import { AppSidebarFallback } from '../app-sidebar'; import type { WorkspaceRootProps } from '../workspace'; import { AppContainer as AppContainerWithoutSettings, - MainContainer, + MainContainerFallback, } from '../workspace'; export const AppContainer = (props: WorkspaceRootProps) => { @@ -24,11 +24,16 @@ export const AppContainer = (props: WorkspaceRootProps) => { ); }; -export const AppFallback = (): ReactElement => { +export const AppFallback = ({ + className, + children, +}: PropsWithChildren<{ + className?: string; +}>): ReactElement => { return ( - + - + {children} ); }; diff --git a/packages/frontend/core/src/components/app-sidebar/fallback.css.ts b/packages/frontend/core/src/components/app-sidebar/fallback.css.ts index 046413fa68..87c48fbcc3 100644 --- a/packages/frontend/core/src/components/app-sidebar/fallback.css.ts +++ b/packages/frontend/core/src/components/app-sidebar/fallback.css.ts @@ -1,12 +1,38 @@ import { style } from '@vanilla-extract/css'; -export const fallbackStyle = style({ - margin: '4px 16px', + +export const fallback = style({ + padding: '4px 20px', height: '100%', + overflow: 'clip', }); -export const fallbackHeaderStyle = style({ + +export const fallbackHeader = style({ width: '100%', display: 'flex', alignItems: 'center', flexDirection: 'row', gap: '8px', + overflow: 'hidden', + height: '52px', +}); + +export const spacer = style({ + flex: 1, +}); + +export const fallbackBody = style({ + display: 'flex', + flexDirection: 'column', + gap: '42px', + marginTop: '42px', +}); + +export const fallbackGroupItems = style({ + display: 'flex', + flexDirection: 'column', + gap: '16px', +}); + +export const fallbackItemHeader = style({ + transform: 'translateX(-10px)', }); diff --git a/packages/frontend/core/src/components/app-sidebar/index.tsx b/packages/frontend/core/src/components/app-sidebar/index.tsx index cf544aeeda..31f5c46e7b 100644 --- a/packages/frontend/core/src/components/app-sidebar/index.tsx +++ b/packages/frontend/core/src/components/app-sidebar/index.tsx @@ -1,13 +1,15 @@ import { Skeleton } from '@affine/component'; import { ResizePanel } from '@affine/component/resize-panel'; +import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper'; +import { NavigateContext } from '@affine/core/hooks/use-navigate-helper'; import { useServiceOptional, WorkspaceService } from '@toeverything/infra'; import { useAtom, useAtomValue } from 'jotai'; import { debounce } from 'lodash-es'; import type { PropsWithChildren, ReactElement } from 'react'; -import { useEffect } from 'react'; +import { useContext, useEffect, useMemo } from 'react'; import { WorkspaceNavigator } from '../workspace-selector'; -import { fallbackHeaderStyle, fallbackStyle } from './fallback.css'; +import * as styles from './fallback.css'; import { floatingMaxWidth, navBodyStyle, @@ -25,11 +27,6 @@ import { } from './index.jotai'; import { SidebarHeader } from './sidebar-header'; -export type AppSidebarProps = PropsWithChildren<{ - clientBorder?: boolean; - translucentUI?: boolean; -}>; - export type History = { stack: string[]; current: number; @@ -38,10 +35,11 @@ export type History = { const MAX_WIDTH = 480; const MIN_WIDTH = 248; -export function AppSidebar({ - children, - clientBorder, -}: AppSidebarProps): ReactElement { +export function AppSidebar({ children }: PropsWithChildren) { + const { appSettings } = useAppSettingHelper(); + + const clientBorder = appSettings.clientBorder; + const [open, setOpen] = useAtom(appSidebarOpenAtom); const [width, setWidth] = useAtom(appSidebarWidthAtom); const [floating, setFloating] = useAtom(appSidebarFloatingAtom); @@ -122,35 +120,96 @@ export function AppSidebar({ ); } -export const AppSidebarFallback = (): ReactElement | null => { - const width = useAtomValue(appSidebarWidthAtom); +const FallbackHeader = () => { + // if navigate is not defined, it is rendered outside of router + // WorkspaceNavigator requires navigate context + // todo: refactor + const navigate = useContext(NavigateContext); const currentWorkspace = useServiceOptional(WorkspaceService); + return ( +
+ {!currentWorkspace && navigate ? ( + + ) : ( + <> + + + + + )} +
+ ); +}; + +const randomWidth = () => { + return Math.floor(Math.random() * 200) + 100; +}; + +const RandomBar = ({ className }: { className?: string }) => { + const width = useMemo(() => randomWidth(), []); + return ( + + ); +}; + +const RandomBars = ({ count, header }: { count: number; header?: boolean }) => { + return ( +
+ {header ? ( + + ) : null} + {Array.from({ length: count }).map((_, index) => ( + + ))} +
+ ); +}; + +const FallbackBody = () => { + return ( +
+ + + + +
+ ); +}; + +export const AppSidebarFallback = (): ReactElement | null => { + const width = useAtomValue(appSidebarWidthAtom); + const { appSettings } = useAppSettingHelper(); + const clientBorder = appSettings.clientBorder; + const hasRightBorder = !environment.isElectron && !clientBorder; + return (
diff --git a/packages/frontend/core/src/components/root-app-sidebar/index.tsx b/packages/frontend/core/src/components/root-app-sidebar/index.tsx index ca10e2ef94..cedc6e6d52 100644 --- a/packages/frontend/core/src/components/root-app-sidebar/index.tsx +++ b/packages/frontend/core/src/components/root-app-sidebar/index.tsx @@ -29,7 +29,6 @@ import { useSetAtom } from 'jotai'; import type { MouseEvent, ReactElement } from 'react'; import { useCallback, useEffect } from 'react'; -import { useAppSettingHelper } from '../../hooks/affine/use-app-setting-helper'; import { WorkbenchService } from '../../modules/workbench'; import { AddPageButton, @@ -84,7 +83,6 @@ export const RootAppSidebar = (): ReactElement => { CMDKQuickSearchService, }); const currentWorkspace = workspaceService.workspace; - const { appSettings } = useAppSettingHelper(); const docCollection = currentWorkspace.docCollection; const t = useI18n(); const workbench = workbenchService.workbench; @@ -141,10 +139,7 @@ export const RootAppSidebar = (): ReactElement => { }, [setOpenSettingModalAtom]); return ( - +
diff --git a/packages/frontend/core/src/components/workspace/index.css.ts b/packages/frontend/core/src/components/workspace/index.css.ts index 721bffcd56..c789518b04 100644 --- a/packages/frontend/core/src/components/workspace/index.css.ts +++ b/packages/frontend/core/src/components/workspace/index.css.ts @@ -1,5 +1,6 @@ import { cssVar, lightCssVariables } from '@toeverything/theme'; import { globalStyle, style } from '@vanilla-extract/css'; + export const appStyle = style({ width: '100%', position: 'relative', @@ -98,3 +99,11 @@ export const toolStyle = style({ }, }, }); + +export const fallbackRootStyle = style({ + paddingTop: 52, + display: 'flex', + flex: 1, + width: '100%', + height: '100%', +}); diff --git a/packages/frontend/core/src/components/workspace/index.tsx b/packages/frontend/core/src/components/workspace/index.tsx index de6aa8517d..c71602176b 100644 --- a/packages/frontend/core/src/components/workspace/index.tsx +++ b/packages/frontend/core/src/components/workspace/index.tsx @@ -15,6 +15,7 @@ import { appStyle, mainContainerStyle, toolStyle } from './index.css'; export type WorkspaceRootProps = PropsWithChildren<{ resizing?: boolean; + className?: string; useNoisyBackground?: boolean; useBlurBackground?: boolean; }>; @@ -24,6 +25,7 @@ export const AppContainer = ({ useNoisyBackground, useBlurBackground, children, + className, ...rest }: WorkspaceRootProps) => { const noisyBackground = useNoisyBackground && environment.isElectron; @@ -31,7 +33,7 @@ export const AppContainer = ({ return (
{ + // todo: default app fallback? + return {children}; +}; + export const ToolContainer = ( props: PropsWithChildren<{ className?: string }> ): ReactElement => { diff --git a/packages/frontend/core/src/modules/workbench/view/split-view/panel.tsx b/packages/frontend/core/src/modules/workbench/view/split-view/panel.tsx index 3760686108..8a8390f015 100644 --- a/packages/frontend/core/src/modules/workbench/view/split-view/panel.tsx +++ b/packages/frontend/core/src/modules/workbench/view/split-view/panel.tsx @@ -39,6 +39,17 @@ export interface SplitViewPanelProps >; } +export const SplitViewPanelContainer = ({ + children, + ...props +}: HTMLAttributes) => { + return ( +
+ {children} +
+ ); +}; + export const SplitViewPanel = memo(function SplitViewPanel({ children, view, @@ -85,9 +96,8 @@ export const SplitViewPanel = memo(function SplitViewPanel({ ); return ( -
1} data-is-last={isLast} @@ -110,7 +120,7 @@ export const SplitViewPanel = memo(function SplitViewPanel({ ) : null}
{children} -
+ ); }); diff --git a/packages/frontend/core/src/modules/workbench/view/split-view/split-view.tsx b/packages/frontend/core/src/modules/workbench/view/split-view/split-view.tsx index 4239907f70..9c41763bad 100644 --- a/packages/frontend/core/src/modules/workbench/view/split-view/split-view.tsx +++ b/packages/frontend/core/src/modules/workbench/view/split-view/split-view.tsx @@ -13,13 +13,13 @@ import { } from '@dnd-kit/sortable'; import { useService } from '@toeverything/infra'; import clsx from 'clsx'; -import type { HTMLAttributes, RefObject } from 'react'; +import type { HTMLAttributes, PropsWithChildren, RefObject } from 'react'; import { useCallback, useMemo, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; import type { View } from '../../entities/view'; import { WorkbenchService } from '../../services/workbench'; -import { SplitViewPanel } from './panel'; +import { SplitViewPanel, SplitViewPanelContainer } from './panel'; import { ResizeHandle } from './resize-handle'; import * as styles from './split-view.css'; @@ -141,3 +141,20 @@ export const SplitView = ({
); }; + +export const SplitViewFallback = ({ + children, + className, +}: PropsWithChildren<{ className?: string }>) => { + const { appSettings } = useAppSettingHelper(); + + return ( +
+ {/* todo: support multiple split views */} + {children} +
+ ); +}; diff --git a/packages/frontend/core/src/pages/workspace/index.tsx b/packages/frontend/core/src/pages/workspace/index.tsx index 845a90697e..b26fa3738d 100644 --- a/packages/frontend/core/src/pages/workspace/index.tsx +++ b/packages/frontend/core/src/pages/workspace/index.tsx @@ -111,7 +111,7 @@ export const Component = (): ReactElement => { return ; } if (!meta) { - return ; + return ; } return ; @@ -204,7 +204,7 @@ const WorkspacePage = ({ meta }: { meta: WorkspaceMetadata }) => { if (!isRootDocReady) { return ( - + ); } diff --git a/packages/frontend/electron/renderer/app.tsx b/packages/frontend/electron/renderer/app.tsx index 64d770fbfa..59d1f1c27e 100644 --- a/packages/frontend/electron/renderer/app.tsx +++ b/packages/frontend/electron/renderer/app.tsx @@ -115,7 +115,7 @@ export function App() { } + fallbackElement={} router={router} future={future} /> diff --git a/packages/frontend/electron/renderer/shell/shell.css.ts b/packages/frontend/electron/renderer/shell/shell.css.ts index 44a8872602..f128873abd 100644 --- a/packages/frontend/electron/renderer/shell/shell.css.ts +++ b/packages/frontend/electron/renderer/shell/shell.css.ts @@ -1,4 +1,4 @@ -import { cssVar } from '@toeverything/theme'; +import { cssVarV2 } from '@toeverything/theme/v2'; import { createVar, style } from '@vanilla-extract/css'; export const sidebarOffsetVar = createVar(); @@ -7,10 +7,33 @@ export const root = style({ width: '100vw', height: '100vh', display: 'flex', - background: cssVar('backgroundPrimaryColor'), + flexDirection: 'column', + background: cssVarV2('layer/background/primary'), selectors: { '&[data-translucent="true"]': { background: 'transparent', }, }, }); + +export const appTabsHeader = style({ + zIndex: 1, +}); + +export const fallbackRoot = style({ + position: 'absolute', + paddingTop: 52, + width: '100%', + height: '100%', + zIndex: 0, +}); + +export const splitViewFallback = style({ + width: '100%', + height: '100%', + position: 'absolute', + bottom: 0, + right: 0, + zIndex: 0, + background: cssVarV2('layer/background/primary'), +}); diff --git a/packages/frontend/electron/renderer/shell/shell.tsx b/packages/frontend/electron/renderer/shell/shell.tsx index 0bc3357e8e..88470d7129 100644 --- a/packages/frontend/electron/renderer/shell/shell.tsx +++ b/packages/frontend/electron/renderer/shell/shell.tsx @@ -1,5 +1,7 @@ +import { AppFallback } from '@affine/core/components/affine/app-container'; import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper'; import { AppTabsHeader } from '@affine/core/modules/app-tabs-header'; +import { SplitViewFallback } from '@affine/core/modules/workbench/view/split-view/split-view'; import * as styles from './shell.css'; @@ -11,7 +13,10 @@ export function ShellRoot() { appSettings.enableBlurBackground; return (
- + + + +
); } diff --git a/packages/frontend/mobile/src/app.tsx b/packages/frontend/mobile/src/app.tsx index edebbbb540..e4aa05c018 100644 --- a/packages/frontend/mobile/src/app.tsx +++ b/packages/frontend/mobile/src/app.tsx @@ -81,7 +81,7 @@ export function App() { } + fallbackElement={} router={router} future={future} /> diff --git a/packages/frontend/mobile/src/pages/workspace/layout.tsx b/packages/frontend/mobile/src/pages/workspace/layout.tsx index 5725752c98..5f79fd9809 100644 --- a/packages/frontend/mobile/src/pages/workspace/layout.tsx +++ b/packages/frontend/mobile/src/pages/workspace/layout.tsx @@ -70,7 +70,7 @@ export const WorkspaceLayout = ({ if (!isRootDocReady) { return ( - + ); }