From eea38a08c5c6738d5dc24b9e6b0393af84281dbe Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Fri, 15 Sep 2023 16:59:29 +0800 Subject: [PATCH] fix: add platform selector to storybook (#4380) --- .eslintrc.js | 6 ++ .../src/components/affine/auth/send-email.tsx | 3 +- .../core/src/components/pure/header/index.tsx | 3 +- .../src/components/pure/header/top-tip.tsx | 5 +- .../pure/header/windows-app-controls.tsx | 2 +- .../src/components/root-app-sidebar/index.tsx | 7 +-- apps/core/src/providers/session-provider.tsx | 3 +- apps/core/src/utils/cloud-utils.tsx | 5 +- apps/storybook/.storybook/preview.tsx | 59 ++++++++++++++++++- .../components/page-list/operation-cell.tsx | 3 +- .../src/components/theme-provider/index.tsx | 3 +- packages/workspace/src/manager/index.ts | 8 +-- 12 files changed, 81 insertions(+), 26 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index bce0ab722..18e8ecda8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -47,6 +47,12 @@ const createPattern = packageName => [ message: 'Do not use this API because it has a bug', importNames: ['mergeUpdates'], }, + { + group: ['@affine/env/constant'], + message: + 'Do not import from @affine/env/constant. Use `environment.isDesktop` instead', + importNames: ['isDesktop'], + }, ]; const allPackages = [ diff --git a/apps/core/src/components/affine/auth/send-email.tsx b/apps/core/src/components/affine/auth/send-email.tsx index 6b3c32dcf..e2abe99d0 100644 --- a/apps/core/src/components/affine/auth/send-email.tsx +++ b/apps/core/src/components/affine/auth/send-email.tsx @@ -6,7 +6,6 @@ import { ModalHeader, } from '@affine/component/auth-components'; import { pushNotificationAtom } from '@affine/component/notification-center'; -import { isDesktop } from '@affine/env/constant'; import { sendChangeEmailMutation, sendChangePasswordEmailMutation, @@ -118,7 +117,7 @@ const useSendEmail = (emailType: AuthPanelProps['emailType']) => { return trigger({ email, callbackUrl: `/auth/${callbackUrl}?isClient=${ - isDesktop ? 'true' : 'false' + environment.isDesktop ? 'true' : 'false' }`, }); }, diff --git a/apps/core/src/components/pure/header/index.tsx b/apps/core/src/components/pure/header/index.tsx index 394c90db1..3e873d38a 100644 --- a/apps/core/src/components/pure/header/index.tsx +++ b/apps/core/src/components/pure/header/index.tsx @@ -3,7 +3,6 @@ import { appSidebarOpenAtom, SidebarSwitch, } from '@affine/component/app-sidebar'; -import { isDesktop } from '@affine/env/constant'; import { useIsTinyScreen } from '@toeverything/hooks/use-is-tiny-screen'; import clsx from 'clsx'; import { type Atom, useAtomValue } from 'jotai'; @@ -45,7 +44,7 @@ export const Header = forwardRef(function Header( rightStatic: windowControlsRef, }); - const isWindowsDesktop = globalThis.platform === 'win32' && isDesktop; + const isWindowsDesktop = environment.isDesktop && environment.isWindows; const open = useAtomValue(appSidebarOpenAtom); const appSidebarFloating = useAtomValue(appSidebarFloatingAtom); return ( diff --git a/apps/core/src/components/pure/header/top-tip.tsx b/apps/core/src/components/pure/header/top-tip.tsx index aa269d6fb..749019867 100644 --- a/apps/core/src/components/pure/header/top-tip.tsx +++ b/apps/core/src/components/pure/header/top-tip.tsx @@ -1,6 +1,5 @@ import { BrowserWarning } from '@affine/component/affine-banner'; import { DownloadTips } from '@affine/component/affine-banner'; -import { isDesktop } from '@affine/env/constant'; import { Trans } from '@affine/i18n'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAtom } from 'jotai'; @@ -11,7 +10,7 @@ import { guideDownloadClientTipAtom } from '../../../atoms/guide'; const minimumChromeVersion = 102; const shouldShowWarning = () => { - if (isDesktop) { + if (environment.isDesktop) { // even though desktop has compatibility issues, // we don't want to show the warning return false; @@ -64,7 +63,7 @@ export const TopTip = () => { setShowWarning(shouldShowWarning()); }, []); - if (showDownloadTip && isDesktop) { + if (showDownloadTip && environment.isDesktop) { return ( { diff --git a/apps/core/src/components/pure/header/windows-app-controls.tsx b/apps/core/src/components/pure/header/windows-app-controls.tsx index 24c088b27..3e6ecaa4d 100644 --- a/apps/core/src/components/pure/header/windows-app-controls.tsx +++ b/apps/core/src/components/pure/header/windows-app-controls.tsx @@ -8,7 +8,7 @@ import * as style from './style.css'; const maximizedAtom = atomWithObservable(() => { return new Observable(subscriber => { subscriber.next(false); - return window?.events.ui.onMaximized(maximized => { + return window.events?.ui.onMaximized(maximized => { return subscriber.next(maximized); }); }); diff --git a/apps/core/src/components/root-app-sidebar/index.tsx b/apps/core/src/components/root-app-sidebar/index.tsx index a28a9b97b..0eaf6d2b6 100644 --- a/apps/core/src/components/root-app-sidebar/index.tsx +++ b/apps/core/src/components/root-app-sidebar/index.tsx @@ -11,7 +11,6 @@ import { SidebarScrollableContainer, } from '@affine/component/app-sidebar'; import { useCollectionManager } from '@affine/component/page-list'; -import { isDesktop } from '@affine/env/constant'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { DeleteTemporarilyIcon, @@ -117,7 +116,7 @@ export const RootAppSidebar = ({ // Listen to the "New Page" action from the menu useEffect(() => { - if (isDesktop) { + if (environment.isDesktop) { return window.events?.applicationMenu.onNewPageAction(onClickNewPage); } return; @@ -125,7 +124,7 @@ export const RootAppSidebar = ({ const [sidebarOpen, setSidebarOpen] = useAtom(appSidebarOpenAtom); useEffect(() => { - if (isDesktop) { + if (environment.isDesktop) { window.apis?.ui.handleSidebarVisibilityChange(sidebarOpen).catch(err => { console.error(err); }); @@ -252,7 +251,7 @@ export const RootAppSidebar = ({ )} - {isDesktop && } + {environment.isDesktop && }
diff --git a/apps/core/src/providers/session-provider.tsx b/apps/core/src/providers/session-provider.tsx index 3cc82312e..b1ef1b032 100644 --- a/apps/core/src/providers/session-provider.tsx +++ b/apps/core/src/providers/session-provider.tsx @@ -1,7 +1,6 @@ import '@toeverything/hooks/use-affine-ipc-renderer'; import { pushNotificationAtom } from '@affine/component/notification-center'; -import { isDesktop } from '@affine/env/constant'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { refreshRootMetadataAtom } from '@affine/workspace/atom'; import { useAtom, useSetAtom } from 'jotai'; @@ -47,7 +46,7 @@ const SessionDefence = (props: PropsWithChildren) => { type: 'success', }); - if (isDesktop) { + if (environment.isDesktop) { window.affine.ipcRenderer.send('affine:login'); } } diff --git a/apps/core/src/utils/cloud-utils.tsx b/apps/core/src/utils/cloud-utils.tsx index bb8fe43b3..19a0b67f4 100644 --- a/apps/core/src/utils/cloud-utils.tsx +++ b/apps/core/src/utils/cloud-utils.tsx @@ -1,4 +1,3 @@ -import { isDesktop } from '@affine/env/constant'; import { generateRandUTF16Chars, SPAN_ID_BYTES, @@ -48,7 +47,7 @@ function onRejectHandleTrace( export const signInCloud: typeof signIn = async (provider, ...rest) => { const traceParams = genTraceParams(); - if (isDesktop) { + if (environment.isDesktop) { if (provider === 'google') { open( `${ @@ -104,7 +103,7 @@ export const signOutCloud: typeof signOut = async options => { export function buildCallbackUrl(callbackUrl: string) { const params: string[][] = []; - if (isDesktop && window.appInfo.schema) { + if (environment.isDesktop && window.appInfo.schema) { params.push(['schema', window.appInfo.schema]); } const query = diff --git a/apps/storybook/.storybook/preview.tsx b/apps/storybook/.storybook/preview.tsx index 3449ecf49..fc0d9253a 100644 --- a/apps/storybook/.storybook/preview.tsx +++ b/apps/storybook/.storybook/preview.tsx @@ -16,6 +16,9 @@ import { createStore } from 'jotai/vanilla'; import { _setCurrentStore } from '@toeverything/infra/atom'; import { setupGlobal } from '@affine/env/global'; +import type { Preview } from '@storybook/react'; +import { useLayoutEffect, useRef } from 'react'; + setupGlobal(); export const parameters = { backgrounds: { disable: true }, @@ -140,4 +143,58 @@ const withContextDecorator: Decorator = (Story, context) => { ); }; -export const decorators = [withContextDecorator, withI18n, withMockAuth]; +const platforms = ['web', 'desktop-macos', 'desktop-windows'] as const; + +const withPlatformSelectionDecorator: Decorator = (Story, context) => { + const setupCounterRef = useRef(0); + useLayoutEffect(() => { + if (setupCounterRef.current++ === 0) { + return; + } + switch (context.globals.platform) { + case 'desktop-macos': + environment.isDesktop = true; + environment.isMacOs = true; + environment.isWindows = false; + break; + case 'desktop-windows': + environment.isDesktop = true; + environment.isMacOs = false; + environment.isWindows = true; + break; + default: + globalThis.$AFFINE_SETUP = false; + setupGlobal(); + break; + } + }, [context.globals.platform]); + + return ; +}; + +const decorators = [ + withContextDecorator, + withI18n, + withMockAuth, + withPlatformSelectionDecorator, +]; + +const preview: Preview = { + decorators, + globalTypes: { + platform: { + description: 'Rendering platform target', + defaultValue: 'web', + toolbar: { + // The label to show for this toolbar item + title: 'platform', + // Array of plain string values or MenuItem shape (see below) + items: platforms, + // Change title based on selected value + dynamicTitle: true, + }, + }, + }, +}; + +export default preview; diff --git a/packages/component/src/components/page-list/operation-cell.tsx b/packages/component/src/components/page-list/operation-cell.tsx index 8762e3d1e..ff1833b74 100644 --- a/packages/component/src/components/page-list/operation-cell.tsx +++ b/packages/component/src/components/page-list/operation-cell.tsx @@ -1,4 +1,3 @@ -import { isDesktop } from '@affine/env/constant'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { DeletePermanentlyIcon, @@ -66,7 +65,7 @@ export const OperationCell = ({ ? t['com.affine.favoritePageOperation.remove']() : t['com.affine.favoritePageOperation.add']()} - {!isDesktop && ( + {!environment.isDesktop && ( { diff --git a/packages/workspace/src/manager/index.ts b/packages/workspace/src/manager/index.ts index a05e638ca..bf1e99bf9 100644 --- a/packages/workspace/src/manager/index.ts +++ b/packages/workspace/src/manager/index.ts @@ -1,4 +1,4 @@ -import { isBrowser, isDesktop } from '@affine/env/constant'; +import { isBrowser } from '@affine/env/constant'; import type { BlockSuiteFeatureFlags } from '@affine/env/global'; import { WorkspaceFlavour } from '@affine/env/workspace'; import { createAffinePublicProviders } from '@affine/workspace/providers'; @@ -101,7 +101,7 @@ export function getOrCreateWorkspace( if (isBrowser) { blobStorages.push(createIndexeddbStorage); blobStorages.push(createCloudBlobStorage); - if (isDesktop && runtimeConfig.enableSQLiteProvider) { + if (environment.isDesktop && runtimeConfig.enableSQLiteProvider) { blobStorages.push(createSQLiteStorage); } providerCreators.push(...createAffineProviders()); @@ -111,7 +111,7 @@ export function getOrCreateWorkspace( } else if (flavour === WorkspaceFlavour.LOCAL) { if (isBrowser) { blobStorages.push(createIndexeddbStorage); - if (isDesktop && runtimeConfig.enableSQLiteProvider) { + if (environment.isDesktop && runtimeConfig.enableSQLiteProvider) { blobStorages.push(createSQLiteStorage); } } @@ -119,7 +119,7 @@ export function getOrCreateWorkspace( } else if (flavour === WorkspaceFlavour.AFFINE_PUBLIC) { if (isBrowser) { blobStorages.push(createIndexeddbStorage); - if (isDesktop && runtimeConfig.enableSQLiteProvider) { + if (environment.isDesktop && runtimeConfig.enableSQLiteProvider) { blobStorages.push(createSQLiteStorage); } }