refactor: environment setup (#2898)

Co-authored-by: Simon He <57086651+Simon-He95@users.noreply.github.com>
This commit is contained in:
Alex Yang
2023-06-28 19:19:19 +08:00
committed by GitHub
parent 80c2a78273
commit 5496969e58
72 changed files with 255 additions and 242 deletions
+3 -4
View File
@@ -2,9 +2,8 @@
* This file has deprecated because we do not maintain legacy affine cloud, * This file has deprecated because we do not maintain legacy affine cloud,
* please use new affine cloud instead. * please use new affine cloud instead.
*/ */
import { AFFINE_STORAGE_KEY, config } from '@affine/env';
import { initEmptyPage } from '@affine/env/blocksuite'; import { initEmptyPage } from '@affine/env/blocksuite';
import { PageNotFoundError } from '@affine/env/constant'; import { AFFINE_STORAGE_KEY, PageNotFoundError } from '@affine/env/constant';
import type { import type {
AffineDownloadProvider, AffineDownloadProvider,
AffineLegacyCloudWorkspace, AffineLegacyCloudWorkspace,
@@ -109,7 +108,7 @@ export const AffineAdapter: WorkspaceAdapter<WorkspaceFlavour.AFFINE> = {
loadPriority: LoadPriority.HIGH, loadPriority: LoadPriority.HIGH,
Events: { Events: {
'workspace:access': async () => { 'workspace:access': async () => {
if (!config.enableLegacyCloud) { if (!runtimeConfig.enableLegacyCloud) {
console.warn('Legacy cloud is disabled'); console.warn('Legacy cloud is disabled');
return; return;
} }
@@ -123,7 +122,7 @@ export const AffineAdapter: WorkspaceAdapter<WorkspaceFlavour.AFFINE> = {
} }
}, },
'workspace:revoke': async () => { 'workspace:revoke': async () => {
if (!config.enableLegacyCloud) { if (!runtimeConfig.enableLegacyCloud) {
console.warn('Legacy cloud is disabled'); console.warn('Legacy cloud is disabled');
return; return;
} }
+4 -5
View File
@@ -1,11 +1,10 @@
import { DebugLogger } from '@affine/debug'; import { DebugLogger } from '@affine/debug';
import { initEmptyPage, initPageWithPreloading } from '@affine/env/blocksuite';
import { import {
config,
DEFAULT_HELLO_WORLD_PAGE_ID, DEFAULT_HELLO_WORLD_PAGE_ID,
DEFAULT_WORKSPACE_NAME, DEFAULT_WORKSPACE_NAME,
} from '@affine/env'; PageNotFoundError,
import { initEmptyPage, initPageWithPreloading } from '@affine/env/blocksuite'; } from '@affine/env/constant';
import { PageNotFoundError } from '@affine/env/constant';
import type { LocalIndexedDBDownloadProvider } from '@affine/env/workspace'; import type { LocalIndexedDBDownloadProvider } from '@affine/env/workspace';
import { import {
LoadPriority, LoadPriority,
@@ -45,7 +44,7 @@ export const LocalAdapter: WorkspaceAdapter<WorkspaceFlavour.LOCAL> = {
const page = blockSuiteWorkspace.createPage({ const page = blockSuiteWorkspace.createPage({
id: DEFAULT_HELLO_WORLD_PAGE_ID, id: DEFAULT_HELLO_WORLD_PAGE_ID,
}); });
if (config.enablePreloading) { if (runtimeConfig.enablePreloading) {
initPageWithPreloading(page).catch(err => { initPageWithPreloading(page).catch(err => {
logger.error('init page with preloading failed', err); logger.error('init page with preloading failed', err);
}); });
+1 -1
View File
@@ -1,4 +1,4 @@
import { Unreachable } from '@affine/env'; import { Unreachable } from '@affine/env/constant';
import type { AppEvents, WorkspaceUISchema } from '@affine/env/workspace'; import type { AppEvents, WorkspaceUISchema } from '@affine/env/workspace';
import { import {
LoadPriority, LoadPriority,
+1 -2
View File
@@ -1,5 +1,4 @@
import { DebugLogger } from '@affine/debug'; import { DebugLogger } from '@affine/debug';
import { config } from '@affine/env';
import { WorkspaceFlavour, WorkspaceVersion } from '@affine/env/workspace'; import { WorkspaceFlavour, WorkspaceVersion } from '@affine/env/workspace';
import type { RootWorkspaceMetadataV2 } from '@affine/workspace/atom'; import type { RootWorkspaceMetadataV2 } from '@affine/workspace/atom';
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom'; import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
@@ -53,7 +52,7 @@ rootWorkspacesMetadataAtom.onMount = setAtom => {
}, 0); }, 0);
} }
if (environment.isDesktop && config.enableSQLiteProvider) { if (environment.isDesktop && runtimeConfig.enableSQLiteProvider) {
window.apis?.workspace window.apis?.workspace
.list() .list()
.then(workspaceIDs => { .then(workspaceIDs => {
+2 -3
View File
@@ -1,5 +1,4 @@
import type { BlockSuiteFeatureFlags } from '@affine/env'; import type { BlockSuiteFeatureFlags } from '@affine/env/global';
import { config } from '@affine/env';
import type { AffinePublicWorkspace } from '@affine/env/workspace'; import type { AffinePublicWorkspace } from '@affine/env/workspace';
import { WorkspaceFlavour } from '@affine/env/workspace'; import { WorkspaceFlavour } from '@affine/env/workspace';
import { affineApis } from '@affine/workspace/affine/shared'; import { affineApis } from '@affine/workspace/affine/shared';
@@ -25,7 +24,7 @@ function createPublicWorkspace(
blockSuiteWorkspace.doc, blockSuiteWorkspace.doc,
new Uint8Array(binary) new Uint8Array(binary)
); );
Object.entries(config.editorFlags).forEach(([key, value]) => { Object.entries(runtimeConfig.editorFlags).forEach(([key, value]) => {
blockSuiteWorkspace.awarenessStore.setFlag( blockSuiteWorkspace.awarenessStore.setFlag(
key as keyof BlockSuiteFeatureFlags, key as keyof BlockSuiteFeatureFlags,
value value
+1 -2
View File
@@ -1,6 +1,5 @@
//#region async atoms that to load the real workspace data //#region async atoms that to load the real workspace data
import { DebugLogger } from '@affine/debug'; import { DebugLogger } from '@affine/debug';
import { config } from '@affine/env';
import type { WorkspaceRegistry } from '@affine/env/workspace'; import type { WorkspaceRegistry } from '@affine/env/workspace';
import { WorkspaceFlavour } from '@affine/env/workspace'; import { WorkspaceFlavour } from '@affine/env/workspace';
import { import {
@@ -30,7 +29,7 @@ export const workspacesAtom = atom<Promise<AllWorkspace[]>>(
// TODO: remove this when we remove the legacy cloud // TODO: remove this when we remove the legacy cloud
) )
.filter(workspace => .filter(workspace =>
!config.enableLegacyCloud !runtimeConfig.enableLegacyCloud
? workspace.flavour !== WorkspaceFlavour.AFFINE ? workspace.flavour !== WorkspaceFlavour.AFFINE
: true : true
); );
+9 -4
View File
@@ -1,5 +1,6 @@
import { migrateToSubdoc } from '@affine/env/blocksuite'; import { migrateToSubdoc } from '@affine/env/blocksuite';
import { config, setupGlobal } from '@affine/env/config'; import { isDesktop, isServer } from '@affine/env/constant';
import { setupGlobal } from '@affine/env/global';
import type { LocalIndexedDBDownloadProvider } from '@affine/env/workspace'; import type { LocalIndexedDBDownloadProvider } from '@affine/env/workspace';
import { WorkspaceFlavour, WorkspaceVersion } from '@affine/env/workspace'; import { WorkspaceFlavour, WorkspaceVersion } from '@affine/env/workspace';
import type { RootWorkspaceMetadata } from '@affine/workspace/atom'; import type { RootWorkspaceMetadata } from '@affine/workspace/atom';
@@ -16,15 +17,19 @@ import { WorkspaceAdapters } from '../adapters/workspace';
setupGlobal(); setupGlobal();
if (config.enablePlugin && !environment.isServer) { if (process.env.NODE_ENV === 'development') {
console.log('Runtime Preset', runtimeConfig);
}
if (runtimeConfig.enablePlugin && !isServer) {
import('@affine/copilot'); import('@affine/copilot');
} }
if (!environment.isServer) { if (!isServer) {
import('@affine/bookmark-block'); import('@affine/bookmark-block');
} }
if (!environment.isDesktop && !environment.isServer) { if (!isDesktop && !isServer) {
// Polyfill Electron // Polyfill Electron
const unimplemented = () => { const unimplemented = () => {
throw new Error('AFFiNE Plugin Web will be supported in the future'); throw new Error('AFFiNE Plugin Web will be supported in the future');
@@ -8,7 +8,6 @@ import {
Tooltip, Tooltip,
} from '@affine/component'; } from '@affine/component';
import { DebugLogger } from '@affine/debug'; import { DebugLogger } from '@affine/debug';
import { config } from '@affine/env';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { HelpIcon } from '@blocksuite/icons'; import { HelpIcon } from '@blocksuite/icons';
import { useSetAtom } from 'jotai'; import { useSetAtom } from 'jotai';
@@ -291,7 +290,7 @@ export const CreateWorkspaceModal = ({
}); });
} else if (mode === 'new') { } else if (mode === 'new') {
setStep( setStep(
environment.isDesktop && config.enableSQLiteProvider environment.isDesktop && runtimeConfig.enableSQLiteProvider
? 'set-db-location' ? 'set-db-location'
: 'name-workspace' : 'name-workspace'
); );
@@ -306,7 +305,7 @@ export const CreateWorkspaceModal = ({
const onConfirmEnableCloudSyncing = useCallback( const onConfirmEnableCloudSyncing = useCallback(
(enableCloudSyncing: boolean) => { (enableCloudSyncing: boolean) => {
(async function () { (async function () {
if (!config.enableLegacyCloud && enableCloudSyncing) { if (!runtimeConfig.enableLegacyCloud && enableCloudSyncing) {
setOpenDisableCloudAlertModal(true); setOpenDisableCloudAlertModal(true);
} else { } else {
let id = addedId; let id = addedId;
@@ -346,7 +345,7 @@ export const CreateWorkspaceModal = ({
const onConfirmName = useCallback( const onConfirmName = useCallback(
(name: string) => { (name: string) => {
setWorkspaceName(name); setWorkspaceName(name);
if (environment.isDesktop && config.enableSQLiteProvider) { if (environment.isDesktop && runtimeConfig.enableSQLiteProvider) {
setStep('set-syncing-mode'); setStep('set-syncing-mode');
} else { } else {
// this will be the last step for web for now // this will be the last step for web for now
@@ -1,6 +1,6 @@
import { Switch } from '@affine/component'; import { Switch } from '@affine/component';
import { relatedLinks } from '@affine/component/contact-modal'; import { relatedLinks } from '@affine/component/contact-modal';
import { env } from '@affine/env'; import { isDesktop } from '@affine/env/constant';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { ArrowRightSmallIcon, OpenInNewIcon } from '@blocksuite/icons'; import { ArrowRightSmallIcon, OpenInNewIcon } from '@blocksuite/icons';
import { useCallback } from 'react'; import { useCallback } from 'react';
@@ -24,7 +24,7 @@ export const AboutAffine = () => {
return ( return (
<> <>
<SettingHeader title={t['About AFFiNE']()} subtitle={t['None yet']()} /> <SettingHeader title={t['About AFFiNE']()} subtitle={t['None yet']()} />
{IS_EXHIBITION && env.isDesktop ? ( {IS_EXHIBITION && isDesktop ? (
<Wrapper title={t['Version']()}> <Wrapper title={t['Version']()}>
<SettingRow <SettingRow
name={t['Check for updates']()} name={t['Check for updates']()}
@@ -1,5 +1,5 @@
import { RadioButton, RadioButtonGroup, Switch } from '@affine/component'; import { RadioButton, RadioButtonGroup, Switch } from '@affine/component';
import { env } from '@affine/env'; import { isDesktop } from '@affine/env/constant';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useTheme } from 'next-themes'; import { useTheme } from 'next-themes';
import { useCallback } from 'react'; import { useCallback } from 'react';
@@ -71,7 +71,7 @@ export const AppearanceSettings = () => {
<LanguageMenu /> <LanguageMenu />
</div> </div>
</SettingRow> </SettingRow>
{IS_EXHIBITION && env.isDesktop ? ( {IS_EXHIBITION && isDesktop ? (
<SettingRow <SettingRow
name={t['Client Border Style']()} name={t['Client Border Style']()}
desc={t['Customize the appearance of the client.']()} desc={t['Customize the appearance of the client.']()}
@@ -92,7 +92,7 @@ export const AppearanceSettings = () => {
onChange={checked => changeSwitch('fullWidthLayout', checked)} onChange={checked => changeSwitch('fullWidthLayout', checked)}
/> />
</SettingRow> </SettingRow>
{IS_EXHIBITION && env.isDesktop ? ( {IS_EXHIBITION && isDesktop ? (
<SettingRow <SettingRow
name={t['Window frame style']()} name={t['Window frame style']()}
desc={t['Customize appearance of Windows Client.']()} desc={t['Customize appearance of Windows Client.']()}
@@ -137,7 +137,7 @@ export const AppearanceSettings = () => {
</Wrapper> </Wrapper>
) : null} ) : null}
{env.isDesktop ? ( {isDesktop ? (
<Wrapper title={t['Sidebar']()}> <Wrapper title={t['Sidebar']()}>
<SettingRow <SettingRow
name={t['Disable the noise background on the sidebar']()} name={t['Disable the noise background on the sidebar']()}
@@ -1,5 +1,4 @@
import { Button, IconButton, Menu, MenuItem, Wrapper } from '@affine/component'; import { Button, IconButton, Menu, MenuItem, Wrapper } from '@affine/component';
import { config } from '@affine/env';
import { Unreachable } from '@affine/env/constant'; import { Unreachable } from '@affine/env/constant';
import type { import type {
AffineLegacyCloudWorkspace, AffineLegacyCloudWorkspace,
@@ -186,7 +185,7 @@ const LocalCollaborationPanel: React.FC<
> >
{t['Enable AFFiNE Cloud']()} {t['Enable AFFiNE Cloud']()}
</Button> </Button>
{config.enableLegacyCloud ? ( {runtimeConfig.enableLegacyCloud ? (
<TransformWorkspaceToAffineModal <TransformWorkspaceToAffineModal
open={open} open={open}
onClose={() => { onClose={() => {
@@ -1,5 +1,4 @@
import { Button, toast, Wrapper } from '@affine/component'; import { Button, toast, Wrapper } from '@affine/component';
import { config } from '@affine/env';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { rootCurrentWorkspaceIdAtom } from '@affine/workspace/atom'; import { rootCurrentWorkspaceIdAtom } from '@affine/workspace/atom';
import { useAtomValue } from 'jotai'; import { useAtomValue } from 'jotai';
@@ -13,7 +12,9 @@ export const ExportPanel = () => {
<Button <Button
type="light" type="light"
shape="circle" shape="circle"
disabled={!environment.isDesktop || !id || !config.enableSQLiteProvider} disabled={
!environment.isDesktop || !id || !runtimeConfig.enableSQLiteProvider
}
data-testid="export-affine-backup" data-testid="export-affine-backup"
onClick={async () => { onClick={async () => {
if (id) { if (id) {
@@ -1,6 +1,5 @@
import { Button, toast } from '@affine/component'; import { Button, toast } from '@affine/component';
import { WorkspaceAvatar } from '@affine/component/workspace-avatar'; import { WorkspaceAvatar } from '@affine/component/workspace-avatar';
import { config } from '@affine/env';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { import {
ArrowRightSmallIcon, ArrowRightSmallIcon,
@@ -31,7 +30,7 @@ const useShowOpenDBFile = (workspaceId: string) => {
window.apis && window.apis &&
window.events && window.events &&
environment.isDesktop && environment.isDesktop &&
config.enableSQLiteProvider runtimeConfig.enableSQLiteProvider
) { ) {
window.apis.workspace window.apis.workspace
.getMeta(workspaceId) .getMeta(workspaceId)
@@ -143,7 +142,7 @@ export const GeneralPanel: React.FC<PanelProps> = ({
</Button> </Button>
</div> </div>
</div> </div>
{environment.isDesktop && config.enableSQLiteProvider ? ( {environment.isDesktop && runtimeConfig.enableSQLiteProvider ? (
<DesktopClientOnly workspaceId={workspace.id} /> <DesktopClientOnly workspaceId={workspace.id} />
) : null} ) : null}
<div className={style.row}> <div className={style.row}>
@@ -209,7 +208,7 @@ function DesktopClientOnly({ workspaceId }: { workspaceId: string }) {
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const showOpenFolder = useShowOpenDBFile(workspaceId); const showOpenFolder = useShowOpenDBFile(workspaceId);
const onRevealDBFile = useCallback(() => { const onRevealDBFile = useCallback(() => {
if (environment.isDesktop && config.enableSQLiteProvider) { if (environment.isDesktop && runtimeConfig.enableSQLiteProvider) {
window.apis?.dialog.revealDBFile(workspaceId).catch(err => { window.apis?.dialog.revealDBFile(workspaceId).catch(err => {
console.error(err); console.error(err);
}); });
@@ -5,8 +5,7 @@ import {
Input, Input,
Wrapper, Wrapper,
} from '@affine/component'; } from '@affine/component';
import { config } from '@affine/env'; import { isBrowser, Unreachable } from '@affine/env/constant';
import { Unreachable } from '@affine/env/constant';
import type { import type {
AffineLegacyCloudWorkspace, AffineLegacyCloudWorkspace,
LocalWorkspace, LocalWorkspace,
@@ -38,9 +37,7 @@ const PublishPanelAffine: React.FC<PublishPanelAffineProps> = ({
const [origin, setOrigin] = useState(''); const [origin, setOrigin] = useState('');
useEffect(() => { useEffect(() => {
setOrigin( setOrigin(
typeof window !== 'undefined' && window.location.origin isBrowser && window.location.origin ? window.location.origin : ''
? window.location.origin
: ''
); );
}, []); }, []);
const shareUrl = origin + '/public-workspace/' + workspace.id; const shareUrl = origin + '/public-workspace/' + workspace.id;
@@ -137,7 +134,7 @@ const PublishPanelLocal: React.FC<PublishPanelLocalProps> = ({
> >
{t['Enable AFFiNE Cloud']()} {t['Enable AFFiNE Cloud']()}
</Button> </Button>
{config.enableLegacyCloud ? ( {runtimeConfig.enableLegacyCloud ? (
<EnableAffineCloudModal <EnableAffineCloudModal
open={open} open={open}
onClose={() => { onClose={() => {
@@ -5,7 +5,6 @@ import {
PageList, PageList,
PageListTrashView, PageListTrashView,
} from '@affine/component/page-list'; } from '@affine/component/page-list';
import { env } from '@affine/env';
import type { View } from '@affine/env/filter'; import type { View } from '@affine/env/filter';
import { Trans } from '@affine/i18n'; import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
@@ -56,8 +55,8 @@ const PageListEmpty = (props: {
New Page New Page
</button> </button>
); );
if (env.isDesktop) { if (environment.isDesktop) {
const shortcut = env.isMacOs ? '⌘ + N' : 'Ctrl + N'; const shortcut = environment.isMacOs ? '⌘ + N' : 'Ctrl + N';
return ( return (
<Trans i18nKey="emptyAllPagesClient"> <Trans i18nKey="emptyAllPagesClient">
Click on the <CreateNewPageButton /> button Or press Click on the <CreateNewPageButton /> button Or press
@@ -1,5 +1,5 @@
import { DownloadTips } from '@affine/component/affine-banner'; import { DownloadTips } from '@affine/component/affine-banner';
import { env } from '@affine/env'; import { isDesktop } from '@affine/env/constant';
import { useAtom } from 'jotai'; import { useAtom } from 'jotai';
import { useCallback } from 'react'; import { useCallback } from 'react';
@@ -13,7 +13,7 @@ export const DownloadClientTip = () => {
setShowDownloadClientTips(false); setShowDownloadClientTips(false);
}, [setShowDownloadClientTips]); }, [setShowDownloadClientTips]);
if (!showDownloadClientTips || env.isDesktop) { if (!showDownloadClientTips || isDesktop) {
return <></>; return <></>;
} }
return <DownloadTips onClose={onCloseDownloadClient} />; return <DownloadTips onClose={onCloseDownloadClient} />;
@@ -1,5 +1,4 @@
import { ShareMenu } from '@affine/component/share-menu'; import { ShareMenu } from '@affine/component/share-menu';
import { config } from '@affine/env';
import { Unreachable } from '@affine/env/constant'; import { Unreachable } from '@affine/env/constant';
import type { import type {
AffineLegacyCloudWorkspace, AffineLegacyCloudWorkspace,
@@ -110,7 +109,7 @@ const LocalHeaderShareMenu: React.FC<BaseHeaderProps> = props => {
}; };
export const HeaderShareMenu: React.FC<BaseHeaderProps> = props => { export const HeaderShareMenu: React.FC<BaseHeaderProps> = props => {
if (!config.enableLegacyCloud) { if (!runtimeConfig.enableLegacyCloud) {
return null; return null;
} }
if (props.workspace.flavour === WorkspaceFlavour.AFFINE) { if (props.workspace.flavour === WorkspaceFlavour.AFFINE) {
@@ -1,5 +1,4 @@
import { displayFlex, IconButton, styled, Tooltip } from '@affine/component'; import { displayFlex, IconButton, styled, Tooltip } from '@affine/component';
import { config } from '@affine/env';
import type { LocalWorkspace } from '@affine/env/workspace'; import type { LocalWorkspace } from '@affine/env/workspace';
import { WorkspaceFlavour } from '@affine/env/workspace'; import { WorkspaceFlavour } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
@@ -82,7 +81,7 @@ export const SyncUser = () => {
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const transformWorkspace = useTransformWorkspace(); const transformWorkspace = useTransformWorkspace();
if (!config.enableLegacyCloud) { if (!runtimeConfig.enableLegacyCloud) {
return null; return null;
} }
@@ -4,6 +4,7 @@ import {
appSidebarOpenAtom, appSidebarOpenAtom,
} from '@affine/component/app-sidebar'; } from '@affine/component/app-sidebar';
import { SidebarSwitch } from '@affine/component/app-sidebar/sidebar-header'; import { SidebarSwitch } from '@affine/component/app-sidebar/sidebar-header';
import { isBrowser, isDesktop } from '@affine/env/constant';
import { WorkspaceFlavour } from '@affine/env/workspace'; import { WorkspaceFlavour } from '@affine/env/workspace';
import { CloseIcon, MinusIcon, RoundedRectangleIcon } from '@blocksuite/icons'; import { CloseIcon, MinusIcon, RoundedRectangleIcon } from '@blocksuite/icons';
import type { Page } from '@blocksuite/store'; import type { Page } from '@blocksuite/store';
@@ -148,7 +149,7 @@ const HeaderRightItems: Record<HeaderRightItemName, HeaderItem> = {
); );
}, },
availableWhen: () => { availableWhen: () => {
return environment.isDesktop && environment.isWindows; return isDesktop && isBrowser;
}, },
}, },
}; };
@@ -1,4 +1,4 @@
import { env } from '@affine/env'; import { isDesktop } from '@affine/env/constant';
import { Trans } from '@affine/i18n'; import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import type React from 'react'; import type React from 'react';
@@ -7,18 +7,18 @@ import { useEffect, useState } from 'react';
const minimumChromeVersion = 102; const minimumChromeVersion = 102;
export const shouldShowWarning = () => { export const shouldShowWarning = () => {
if (env.isDesktop) { if (isDesktop) {
// even though desktop have compatibility issues, we don't want to show the warning // even though desktop have compatibility issues, we don't want to show the warning
return false; return false;
} }
if (!env.isBrowser) { if (!environment.isBrowser) {
// disable in SSR // disable in SSR
return false; return false;
} }
if (env.isChrome) { if (environment.isChrome) {
return env.chromeVersion < minimumChromeVersion; return environment.chromeVersion < minimumChromeVersion;
} else { } else {
return !env.isMobile; return !environment.isMobile;
} }
}; };
@@ -27,9 +27,11 @@ export const OSWarningMessage: React.FC = () => {
const [notChrome, setNotChrome] = useState(false); const [notChrome, setNotChrome] = useState(false);
const [notGoodVersion, setNotGoodVersion] = useState(false); const [notGoodVersion, setNotGoodVersion] = useState(false);
useEffect(() => { useEffect(() => {
setNotChrome(env.isBrowser && !env.isChrome); setNotChrome(environment.isBrowser && !environment.isChrome);
setNotGoodVersion( setNotGoodVersion(
env.isBrowser && env.isChrome && env.chromeVersion < minimumChromeVersion environment.isBrowser &&
environment.isChrome &&
environment.chromeVersion < minimumChromeVersion
); );
}, []); }, []);
@@ -1,7 +1,6 @@
import { FlexWrapper } from '@affine/component'; import { FlexWrapper } from '@affine/component';
import { IconButton } from '@affine/component'; import { IconButton } from '@affine/component';
import { Tooltip } from '@affine/component'; import { Tooltip } from '@affine/component';
import { config } from '@affine/env';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { AccessTokenMessage } from '@affine/workspace/affine/login'; import type { AccessTokenMessage } from '@affine/workspace/affine/login';
import { CloudWorkspaceIcon, SignOutIcon } from '@blocksuite/icons'; import { CloudWorkspaceIcon, SignOutIcon } from '@blocksuite/icons';
@@ -62,7 +61,7 @@ export const Footer: React.FC<FooterProps> = ({ user, onLogin, onLogout }) => {
</div> </div>
} }
onClick={async () => { onClick={async () => {
if (!config.enableLegacyCloud) { if (!runtimeConfig.enableLegacyCloud) {
setOpen(true); setOpen(true);
} else { } else {
onLogin(); onLogin();
@@ -1,5 +1,4 @@
import { MuiFade, Tooltip } from '@affine/component'; import { MuiFade, Tooltip } from '@affine/component';
import { config, env } from '@affine/env';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { CloseIcon, NewIcon, UserGuideIcon } from '@blocksuite/icons'; import { CloseIcon, NewIcon, UserGuideIcon } from '@blocksuite/icons';
import { useAtom } from 'jotai'; import { useAtom } from 'jotai';
@@ -28,7 +27,7 @@ const DEFAULT_SHOW_LIST: IslandItemNames[] = [
const DESKTOP_SHOW_LIST: IslandItemNames[] = [...DEFAULT_SHOW_LIST, 'guide']; const DESKTOP_SHOW_LIST: IslandItemNames[] = [...DEFAULT_SHOW_LIST, 'guide'];
export type IslandItemNames = 'whatNew' | 'contact' | 'shortcuts' | 'guide'; export type IslandItemNames = 'whatNew' | 'contact' | 'shortcuts' | 'guide';
export const HelpIsland = ({ export const HelpIsland = ({
showList = env.isDesktop ? DESKTOP_SHOW_LIST : DEFAULT_SHOW_LIST, showList = environment.isDesktop ? DESKTOP_SHOW_LIST : DEFAULT_SHOW_LIST,
}: { }: {
showList?: IslandItemNames[]; showList?: IslandItemNames[];
}) => { }) => {
@@ -73,7 +72,7 @@ export const HelpIsland = ({
<StyledIconWrapper <StyledIconWrapper
data-testid="right-bottom-change-log-icon" data-testid="right-bottom-change-log-icon"
onClick={() => { onClick={() => {
window.open(config.changelogUrl, '_blank'); window.open(runtimeConfig.changelogUrl, '_blank');
}} }}
> >
<NewIcon /> <NewIcon />
@@ -1,5 +1,4 @@
import { Modal, ModalWrapper } from '@affine/component'; import { Modal, ModalWrapper } from '@affine/component';
import { env } from '@affine/env';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Command } from 'cmdk'; import { Command } from 'cmdk';
import type { NextRouter } from 'next/router'; import type { NextRouter } from 'next/router';
@@ -26,10 +25,6 @@ import {
StyledShortcut, StyledShortcut,
} from './style'; } from './style';
const isMac = () => {
return env.isBrowser && env.isMacOs;
};
export type QuickSearchModalProps = { export type QuickSearchModalProps = {
blockSuiteWorkspace: BlockSuiteWorkspace; blockSuiteWorkspace: BlockSuiteWorkspace;
open: boolean; open: boolean;
@@ -149,7 +144,11 @@ export const QuickSearchModal: React.FC<QuickSearchModalProps> = ({
: t['Quick search placeholder']() : t['Quick search placeholder']()
} }
/> />
<StyledShortcut>{isMac() ? '⌘ + K' : 'Ctrl + K'}</StyledShortcut> <StyledShortcut>
{environment.isBrowser && environment.isMacOs
? '⌘ + K'
: 'Ctrl + K'}
</StyledShortcut>
</StyledModalHeader> </StyledModalHeader>
<StyledModalDivider <StyledModalDivider
style={{ display: isPublicAndNoQuery() ? 'none' : '' }} style={{ display: isPublicAndNoQuery() ? 'none' : '' }}
@@ -1,4 +1,4 @@
import { UNTITLED_WORKSPACE_NAME } from '@affine/env'; import { UNTITLED_WORKSPACE_NAME } from '@affine/env/constant';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { EdgelessIcon, PageIcon } from '@blocksuite/icons'; import { EdgelessIcon, PageIcon } from '@blocksuite/icons';
import { assertExists } from '@blocksuite/store'; import { assertExists } from '@blocksuite/store';
@@ -8,7 +8,6 @@ import {
} from '@affine/component'; } from '@affine/component';
import { ScrollableContainer } from '@affine/component'; import { ScrollableContainer } from '@affine/component';
import { WorkspaceList } from '@affine/component/workspace-list'; import { WorkspaceList } from '@affine/component/workspace-list';
import { config } from '@affine/env/config';
import type { import type {
AffineLegacyCloudWorkspace, AffineLegacyCloudWorkspace,
LocalWorkspace, LocalWorkspace,
@@ -66,7 +65,7 @@ const CreateWorkspaceCard = ({
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const anchorEL = useRef<HTMLDivElement>(null); const anchorEL = useRef<HTMLDivElement>(null);
if (config.enableSQLiteProvider && environment.isDesktop) { if (runtimeConfig.enableSQLiteProvider && environment.isDesktop) {
return ( return (
<Menu <Menu
placement="auto" placement="auto"
@@ -10,7 +10,7 @@ import {
SidebarContainer, SidebarContainer,
SidebarScrollableContainer, SidebarScrollableContainer,
} from '@affine/component/app-sidebar'; } from '@affine/component/app-sidebar';
import { config } from '@affine/env'; import { isDesktop } from '@affine/env/constant';
import { WorkspaceFlavour } from '@affine/env/workspace'; import { WorkspaceFlavour } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { import {
@@ -105,14 +105,14 @@ export const RootAppSidebar = ({
// Listen to the "New Page" action from the menu // Listen to the "New Page" action from the menu
useEffect(() => { useEffect(() => {
if (environment.isDesktop) { if (isDesktop) {
return window.events?.applicationMenu.onNewPageAction(onClickNewPage); return window.events?.applicationMenu.onNewPageAction(onClickNewPage);
} }
}, [onClickNewPage]); }, [onClickNewPage]);
const [sidebarOpen, setSidebarOpen] = useAtom(appSidebarOpenAtom); const [sidebarOpen, setSidebarOpen] = useAtom(appSidebarOpenAtom);
useEffect(() => { useEffect(() => {
if (environment.isDesktop && typeof sidebarOpen === 'boolean') { if (isDesktop && typeof sidebarOpen === 'boolean') {
window.apis?.ui.handleSidebarVisibilityChange(sidebarOpen).catch(err => { window.apis?.ui.handleSidebarVisibilityChange(sidebarOpen).catch(err => {
console.error(err); console.error(err);
}); });
@@ -177,7 +177,7 @@ export const RootAppSidebar = ({
> >
<span data-testid="settings">{t['Settings']()}</span> <span data-testid="settings">{t['Settings']()}</span>
</RouteMenuLinkItem> </RouteMenuLinkItem>
{config.enableNewSettingModal ? ( {runtimeConfig.enableNewSettingModal ? (
<MenuItem icon={<SettingsIcon />} onClick={onOpenSettingModal}> <MenuItem icon={<SettingsIcon />} onClick={onOpenSettingModal}>
<span data-testid="new-settings"> <span data-testid="new-settings">
{t['Settings']()} {t['Settings']()}
@@ -203,7 +203,7 @@ export const RootAppSidebar = ({
{blockSuiteWorkspace && ( {blockSuiteWorkspace && (
<FavoriteList currentWorkspace={currentWorkspace} /> <FavoriteList currentWorkspace={currentWorkspace} />
)} )}
{config.enableLegacyCloud && {runtimeConfig.enableLegacyCloud &&
(currentWorkspace?.flavour === WorkspaceFlavour.AFFINE && (currentWorkspace?.flavour === WorkspaceFlavour.AFFINE &&
currentWorkspace.public ? ( currentWorkspace.public ? (
<RouteMenuLinkItem <RouteMenuLinkItem
@@ -235,7 +235,7 @@ export const RootAppSidebar = ({
</RouteMenuLinkItem> </RouteMenuLinkItem>
</SidebarScrollableContainer> </SidebarScrollableContainer>
<SidebarContainer> <SidebarContainer>
{environment.isDesktop && <AppUpdaterButton />} {isDesktop && <AppUpdaterButton />}
<div /> <div />
<AddPageButton onClick={onClickNewPage} /> <AddPageButton onClick={onClickNewPage} />
</SidebarContainer> </SidebarContainer>
+1 -2
View File
@@ -5,7 +5,6 @@ import {
useAllPageSetting, useAllPageSetting,
ViewList, ViewList,
} from '@affine/component/page-list'; } from '@affine/component/page-list';
import { config } from '@affine/env';
import type { WorkspaceHeaderProps } from '@affine/env/workspace'; import type { WorkspaceHeaderProps } from '@affine/env/workspace';
import { WorkspaceFlavour, WorkspaceSubPath } from '@affine/env/workspace'; import { WorkspaceFlavour, WorkspaceSubPath } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
@@ -40,7 +39,7 @@ export function WorkspaceHeader({
}} }}
/> />
</div> </div>
{config.enableAllPageFilter && ( {runtimeConfig.enableAllPageFilter && (
<div> <div>
{setting.currentView.id !== NIL || {setting.currentView.id !== NIL ||
(setting.currentView.id === NIL && (setting.currentView.id === NIL &&
+4 -5
View File
@@ -1,4 +1,3 @@
import { env } from '@affine/env';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useMemo } from 'react'; import { useMemo } from 'react';
@@ -209,21 +208,21 @@ export const useWinMarkdownShortcuts = (): ShortcutTip => {
export const useMarkdownShortcuts = (): ShortcutTip => { export const useMarkdownShortcuts = (): ShortcutTip => {
const macMarkdownShortcuts = useMacMarkdownShortcuts(); const macMarkdownShortcuts = useMacMarkdownShortcuts();
const winMarkdownShortcuts = useWinMarkdownShortcuts(); const winMarkdownShortcuts = useWinMarkdownShortcuts();
const isMac = env.isBrowser && env.isMacOs; const isMac = environment.isBrowser && environment.isMacOs;
return isMac ? macMarkdownShortcuts : winMarkdownShortcuts; return isMac ? macMarkdownShortcuts : winMarkdownShortcuts;
}; };
export const usePageShortcuts = (): ShortcutTip => { export const usePageShortcuts = (): ShortcutTip => {
const macPageShortcuts = useMacPageKeyboardShortcuts(); const macPageShortcuts = useMacPageKeyboardShortcuts();
const winPageShortcuts = useWinPageKeyboardShortcuts(); const winPageShortcuts = useWinPageKeyboardShortcuts();
const isMac = env.isBrowser && env.isMacOs; const isMac = environment.isBrowser && environment.isMacOs;
return isMac ? macPageShortcuts : winPageShortcuts; return isMac ? macPageShortcuts : winPageShortcuts;
}; };
export const useEdgelessShortcuts = (): ShortcutTip => { export const useEdgelessShortcuts = (): ShortcutTip => {
const macEdgelessShortcuts = useMacEdgelessKeyboardShortcuts(); const macEdgelessShortcuts = useMacEdgelessKeyboardShortcuts();
const winEdgelessShortcuts = useWinEdgelessKeyboardShortcuts(); const winEdgelessShortcuts = useWinEdgelessKeyboardShortcuts();
const isMac = env.isBrowser && env.isMacOs; const isMac = environment.isBrowser && environment.isMacOs;
return isMac ? macEdgelessShortcuts : winEdgelessShortcuts; return isMac ? macEdgelessShortcuts : winEdgelessShortcuts;
}; };
@@ -231,7 +230,7 @@ export const useEdgelessShortcuts = (): ShortcutTip => {
export const useGeneralShortcuts = (): ShortcutTip => { export const useGeneralShortcuts = (): ShortcutTip => {
const macGeneralShortcuts = useMacGeneralKeyboardShortcuts(); const macGeneralShortcuts = useMacGeneralKeyboardShortcuts();
const winGeneralShortcuts = useWinGeneralKeyboardShortcuts(); const winGeneralShortcuts = useWinGeneralKeyboardShortcuts();
const isMac = env.isBrowser && env.isMacOs; const isMac = environment.isBrowser && environment.isMacOs;
return isMac ? macGeneralShortcuts : winGeneralShortcuts; return isMac ? macGeneralShortcuts : winGeneralShortcuts;
}; };
@@ -1,3 +1,4 @@
import { isBrowser } from '@affine/env/constant';
import { import {
rootCurrentPageIdAtom, rootCurrentPageIdAtom,
rootCurrentWorkspaceIdAtom, rootCurrentWorkspaceIdAtom,
@@ -19,7 +20,7 @@ export function useCurrentWorkspace(): [
currentWorkspace, currentWorkspace,
useCallback( useCallback(
(id: string | null) => { (id: string | null) => {
if (typeof window !== 'undefined' && id) { if (isBrowser && id) {
localStorage.setItem('last_workspace_id', id); localStorage.setItem('last_workspace_id', id);
} }
setPageId(null); setPageId(null);
+3 -3
View File
@@ -9,8 +9,8 @@ import {
WorkspaceFallback, WorkspaceFallback,
} from '@affine/component/workspace'; } from '@affine/component/workspace';
import { DebugLogger } from '@affine/debug'; import { DebugLogger } from '@affine/debug';
import { config, DEFAULT_HELLO_WORLD_PAGE_ID, env } from '@affine/env';
import { initEmptyPage, initPageWithPreloading } from '@affine/env/blocksuite'; import { initEmptyPage, initPageWithPreloading } from '@affine/env/blocksuite';
import { DEFAULT_HELLO_WORLD_PAGE_ID, isDesktop } from '@affine/env/constant';
import { WorkspaceFlavour } from '@affine/env/workspace'; import { WorkspaceFlavour } from '@affine/env/workspace';
import { setUpLanguage, useI18N } from '@affine/i18n'; import { setUpLanguage, useI18N } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
@@ -350,7 +350,7 @@ export const WorkspaceLayoutInner: FC<PropsWithChildren> = ({ children }) => {
id: pageId, id: pageId,
}); });
assertEquals(page.id, pageId); assertEquals(page.id, pageId);
if (config.enablePreloading) { if (runtimeConfig.enablePreloading) {
initPageWithPreloading(page).catch(error => { initPageWithPreloading(page).catch(error => {
console.error('import error:', error); console.error('import error:', error);
}); });
@@ -455,7 +455,7 @@ export const WorkspaceLayoutInner: FC<PropsWithChildren> = ({ children }) => {
); );
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const showList: IslandItemNames[] = env.isDesktop const showList: IslandItemNames[] = isDesktop
? ['whatNew', 'contact', 'guide'] ? ['whatNew', 'contact', 'guide']
: ['whatNew', 'contact']; : ['whatNew', 'contact'];
-4
View File
@@ -5,7 +5,6 @@ import '../bootstrap';
import { AffineContext } from '@affine/component/context'; import { AffineContext } from '@affine/component/context';
import { WorkspaceFallback } from '@affine/component/workspace'; import { WorkspaceFallback } from '@affine/component/workspace';
import { config } from '@affine/env';
import { createI18n, I18nextProvider } from '@affine/i18n'; import { createI18n, I18nextProvider } from '@affine/i18n';
import type { EmotionCache } from '@emotion/cache'; import type { EmotionCache } from '@emotion/cache';
import { CacheProvider } from '@emotion/react'; import { CacheProvider } from '@emotion/react';
@@ -42,9 +41,6 @@ const DebugProvider = ({ children }: PropsWithChildren): ReactElement => {
}; };
const i18n = createI18n(); const i18n = createI18n();
if (process.env.NODE_ENV === 'development') {
console.log('Runtime Preset', config);
}
const App = function App({ const App = function App({
Component, Component,
+1 -2
View File
@@ -1,5 +1,4 @@
import { MainContainer } from '@affine/component/workspace'; import { MainContainer } from '@affine/component/workspace';
import { config } from '@affine/env';
import { NoSsr } from '@mui/material'; import { NoSsr } from '@mui/material';
import { affinePluginsAtom } from '@toeverything/plugin-infra/manager'; import { affinePluginsAtom } from '@toeverything/plugin-infra/manager';
import { useAtomValue } from 'jotai'; import { useAtomValue } from 'jotai';
@@ -29,7 +28,7 @@ const Plugins = () => {
}; };
export default function PluginPage(): ReactElement { export default function PluginPage(): ReactElement {
if (!config.enablePlugin) { if (!runtimeConfig.enablePlugin) {
return <></>; return <></>;
} }
return ( return (
+1 -2
View File
@@ -1,4 +1,3 @@
import { env } from '@affine/env';
import { WorkspaceSubPath } from '@affine/env/workspace'; import { WorkspaceSubPath } from '@affine/env/workspace';
import { import {
rootCurrentWorkspaceIdAtom, rootCurrentWorkspaceIdAtom,
@@ -69,7 +68,7 @@ export function CurrentWorkspaceModals() {
}, [setOpenDisableCloudAlertModal])} }, [setOpenDisableCloudAlertModal])}
/> />
</Suspense> </Suspense>
{env.isDesktop && ( {environment.isDesktop && (
<Suspense> <Suspense>
<OnboardingModal <OnboardingModal
open={openOnboardingModal} open={openOnboardingModal}
-1
View File
@@ -1,4 +1,3 @@
import { prefixUrl } from '@affine/env';
import type { import type {
GraphQLQuery, GraphQLQuery,
MutationOptions, MutationOptions,
+1 -3
View File
@@ -1,8 +1,6 @@
import { env } from '@affine/env'; import { isBrowser } from '@affine/env/constant';
import createCache from '@emotion/cache'; import createCache from '@emotion/cache';
const isBrowser = env.isBrowser;
export default function createEmotionCache() { export default function createEmotionCache() {
let insertionPoint; let insertionPoint;
@@ -1,4 +1,4 @@
import { env } from '@affine/env/config'; import { isBrowser } from '@affine/env/constant';
import { atomWithObservable, atomWithStorage } from 'jotai/utils'; import { atomWithObservable, atomWithStorage } from 'jotai/utils';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
@@ -22,7 +22,7 @@ function rpcToObservable<
return new Observable<T>(subscriber => { return new Observable<T>(subscriber => {
subscriber.next(initialValue); subscriber.next(initialValue);
onSubscribe?.(); onSubscribe?.();
if (typeof window === 'undefined' || !env.isDesktop || !event) { if (!isBrowser || !environment.isDesktop || !event) {
subscriber.complete(); subscriber.complete();
return; return;
} }
@@ -1,5 +1,4 @@
import { config } from '@affine/env/config'; import { isBrowser, Unreachable } from '@affine/env/constant';
import { Unreachable } from '@affine/env/constant';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { CloseIcon, NewIcon, ResetIcon } from '@blocksuite/icons'; import { CloseIcon, NewIcon, ResetIcon } from '@blocksuite/icons';
import clsx from 'clsx'; import clsx from 'clsx';
@@ -20,7 +19,7 @@ interface AddPageButtonProps {
} }
const currentVersionAtom = atom(async () => { const currentVersionAtom = atom(async () => {
if (typeof window === 'undefined') { if (!isBrowser) {
return null; return null;
} }
const currentVersion = await window.apis?.updater.currentVersion(); const currentVersion = await window.apis?.updater.currentVersion();
@@ -28,7 +27,7 @@ const currentVersionAtom = atom(async () => {
}); });
const currentChangelogUnreadAtom = atom(async get => { const currentChangelogUnreadAtom = atom(async get => {
if (typeof window === 'undefined') { if (!isBrowser) {
return false; return false;
} }
const mapping = get(changelogCheckedAtom); const mapping = get(changelogCheckedAtom);
@@ -79,7 +78,7 @@ export function AppUpdaterButton({ className, style }: AddPageButtonProps) {
); );
} }
} else if (currentChangelogUnread) { } else if (currentChangelogUnread) {
window.open(config.changelogUrl, '_blank'); window.open(runtimeConfig.changelogUrl, '_blank');
onDismissCurrentChangelog(); onDismissCurrentChangelog();
} else { } else {
throw new Unreachable(); throw new Unreachable();
@@ -1,4 +1,3 @@
import { env } from '@affine/env';
import { Skeleton } from '@mui/material'; import { Skeleton } from '@mui/material';
import { assignInlineVars } from '@vanilla-extract/dynamic'; import { assignInlineVars } from '@vanilla-extract/dynamic';
import clsx from 'clsx'; import clsx from 'clsx';
@@ -84,7 +83,7 @@ export function AppSidebar(props: AppSidebarProps): ReactElement {
// disable animation to avoid UI flash // disable animation to avoid UI flash
const enableAnimation = useEnableAnimation(); const enableAnimation = useEnableAnimation();
const isMacosDesktop = env.isDesktop && env.isMacOs; const isMacosDesktop = environment.isDesktop && environment.isMacOs;
if (initialRender) { if (initialRender) {
// avoid the UI flash // avoid the UI flash
return <div />; return <div />;
@@ -97,7 +96,7 @@ export function AppSidebar(props: AppSidebarProps): ReactElement {
[navWidthVar]: `${appSidebarWidth}px`, [navWidthVar]: `${appSidebarWidth}px`,
})} })}
className={clsx(navWrapperStyle, { className={clsx(navWrapperStyle, {
'has-background': env.isDesktop && props.hasBackground, 'has-background': environment.isDesktop && props.hasBackground,
})} })}
data-open={open} data-open={open}
data-is-macos-electron={isMacosDesktop} data-is-macos-electron={isMacosDesktop}
@@ -1,19 +1,19 @@
import { env } from '@affine/env/config';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { SearchIcon } from '@blocksuite/icons'; import { SearchIcon } from '@blocksuite/icons';
import clsx from 'clsx'; import clsx from 'clsx';
import type { HTMLAttributes } from 'react';
import { Spotlight } from '../spolight'; import { Spotlight } from '../spolight';
import * as styles from './index.css'; import * as styles from './index.css';
interface QuickSearchInputProps extends React.HTMLAttributes<HTMLDivElement> { interface QuickSearchInputProps extends HTMLAttributes<HTMLDivElement> {
onClick?: () => void; onClick?: () => void;
} }
// Although it is called an input, it is actually a button. // Although it is called an input, it is actually a button.
export function QuickSearchInput({ onClick, ...props }: QuickSearchInputProps) { export function QuickSearchInput({ onClick, ...props }: QuickSearchInputProps) {
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const isMac = env.isBrowser && env.isMacOs; const isMac = environment.isBrowser && environment.isMacOs;
return ( return (
<div <div
@@ -1,4 +1,3 @@
import { env } from '@affine/env/config';
import { ArrowLeftSmallIcon, ArrowRightSmallIcon } from '@blocksuite/icons'; import { ArrowLeftSmallIcon, ArrowRightSmallIcon } from '@blocksuite/icons';
import { useAtomValue } from 'jotai'; import { useAtomValue } from 'jotai';
@@ -20,9 +19,9 @@ export const SidebarHeader = (props: SidebarHeaderProps) => {
const open = useAtomValue(appSidebarOpenAtom); const open = useAtomValue(appSidebarOpenAtom);
return ( return (
<div className={navHeaderStyle} data-open={open}> <div className={navHeaderStyle} data-open={open}>
{env.isDesktop && ( {environment.isDesktop && (
<> <>
{env.isMacOs && <div style={{ flex: 1 }} />} {environment.isMacOs && <div style={{ flex: 1 }} />}
<IconButton <IconButton
size="middle" size="middle"
data-testid="app-sidebar-arrow-button-back" data-testid="app-sidebar-arrow-button-back"
@@ -50,7 +49,7 @@ export const SidebarHeader = (props: SidebarHeaderProps) => {
<ArrowRightSmallIcon /> <ArrowRightSmallIcon />
</IconButton> </IconButton>
{!env.isMacOs && <div style={{ flex: 1 }} />} {!environment.isMacOs && <div style={{ flex: 1 }} />}
</> </>
)} )}
{open && <SidebarSwitch />} {open && <SidebarSwitch />}
@@ -1,3 +1,4 @@
import { isBrowser } from '@affine/env/constant';
import type { EmbedBlockDoubleClickData } from '@blocksuite/blocks'; import type { EmbedBlockDoubleClickData } from '@blocksuite/blocks';
import { atom } from 'jotai'; import { atom } from 'jotai';
@@ -5,7 +6,7 @@ export const previewBlockIdAtom = atom<string | null>(null);
export const hasAnimationPlayedAtom = atom<boolean | null>(true); export const hasAnimationPlayedAtom = atom<boolean | null>(true);
previewBlockIdAtom.onMount = set => { previewBlockIdAtom.onMount = set => {
if (typeof window !== 'undefined') { if (isBrowser) {
const callback = (event: CustomEvent<EmbedBlockDoubleClickData>) => { const callback = (event: CustomEvent<EmbedBlockDoubleClickData>) => {
set(event.detail.blockId); set(event.detail.blockId);
}; };
@@ -1,3 +1,4 @@
import { isDesktop } from '@affine/env/constant';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { import {
DeletePermanentlyIcon, DeletePermanentlyIcon,
@@ -65,7 +66,7 @@ export const OperationCell: React.FC<OperationCellProps> = ({
> >
{favorite ? t['Remove from favorites']() : t['Add to Favorites']()} {favorite ? t['Remove from favorites']() : t['Add to Favorites']()}
</MenuItem> </MenuItem>
{!environment.isDesktop && ( {!isDesktop && (
<MenuItem onClick={onOpenPageInNewTab} icon={<OpenInNewIcon />}> <MenuItem onClick={onOpenPageInNewTab} icon={<OpenInNewIcon />}>
{t['Open in new tab']()} {t['Open in new tab']()}
</MenuItem> </MenuItem>
@@ -1,4 +1,3 @@
import { prefixUrl } from '@affine/env';
import type { LocalWorkspace } from '@affine/env/workspace'; import type { LocalWorkspace } from '@affine/env/workspace';
import { WorkspaceFlavour } from '@affine/env/workspace'; import { WorkspaceFlavour } from '@affine/env/workspace';
import { Trans } from '@affine/i18n'; import { Trans } from '@affine/i18n';
@@ -1,3 +1,4 @@
import { isDesktop } from '@affine/env/constant';
import { ThemeProvider as NextThemeProvider, useTheme } from 'next-themes'; import { ThemeProvider as NextThemeProvider, useTheme } from 'next-themes';
import type { PropsWithChildren } from 'react'; import type { PropsWithChildren } from 'react';
import { memo, useRef } from 'react'; import { memo, useRef } from 'react';
@@ -9,7 +10,7 @@ const DesktopThemeSync = memo(function DesktopThemeSync() {
const lastThemeRef = useRef(theme); const lastThemeRef = useRef(theme);
const onceRef = useRef(false); const onceRef = useRef(false);
if (lastThemeRef.current !== theme || !onceRef.current) { if (lastThemeRef.current !== theme || !onceRef.current) {
if (environment.isDesktop && theme) { if (isDesktop && theme) {
window.apis?.ui window.apis?.ui
.handleThemeChange(theme as 'dark' | 'light' | 'system') .handleThemeChange(theme as 'dark' | 'light' | 'system')
.catch(err => { .catch(err => {
@@ -1,3 +1,4 @@
import { isDesktop } from '@affine/env/constant';
import { clsx } from 'clsx'; import { clsx } from 'clsx';
import type { FC, PropsWithChildren, ReactElement } from 'react'; import type { FC, PropsWithChildren, ReactElement } from 'react';
@@ -22,7 +23,7 @@ export const AppContainer: FC<WorkspaceRootProps> = ({
<div <div
className={clsx(appStyle, { className={clsx(appStyle, {
'noisy-background': noisyBackground, 'noisy-background': noisyBackground,
'blur-background': environment.isDesktop && useBlurBackground, 'blur-background': isDesktop && useBlurBackground,
})} })}
data-noise-background={noisyBackground} data-noise-background={noisyBackground}
data-is-resizing={resizing} data-is-resizing={resizing}
@@ -40,7 +41,7 @@ export const MainContainer = (props: MainContainerProps): ReactElement => {
return ( return (
<div <div
className={clsx(mainContainerStyle, 'main-container', props.className)} className={clsx(mainContainerStyle, 'main-container', props.className)}
data-is-desktop={environment.isDesktop} data-is-desktop={isDesktop}
> >
{props.children} {props.children}
</div> </div>
+2 -1
View File
@@ -5,7 +5,8 @@
"compilerOptions": { "compilerOptions": {
"composite": true, "composite": true,
"noEmit": false, "noEmit": false,
"outDir": "lib" "outDir": "lib",
"types": ["@affine/env"]
}, },
"references": [ "references": [
{ {
+2 -3
View File
@@ -3,6 +3,7 @@
"private": true, "private": true,
"main": "./src/index.ts", "main": "./src/index.ts",
"module": "./src/index.ts", "module": "./src/index.ts",
"types": "./src/global.ts",
"devDependencies": { "devDependencies": {
"@blocksuite/global": "0.0.0-20230627165830-836e6fd1-nightly", "@blocksuite/global": "0.0.0-20230627165830-836e6fd1-nightly",
"next": "=13.4.2", "next": "=13.4.2",
@@ -11,9 +12,7 @@
"zod": "^3.21.4" "zod": "^3.21.4"
}, },
"exports": { "exports": {
".": "./src/index.ts", "./global": "./src/global.ts",
"./api": "./src/api.ts",
"./config": "./src/config.ts",
"./constant": "./src/constant.ts", "./constant": "./src/constant.ts",
"./workspace": "./src/workspace.ts", "./workspace": "./src/workspace.ts",
"./workspace/legacy-cloud": "./src/workspace/legacy-cloud/index.ts", "./workspace/legacy-cloud": "./src/workspace/legacy-cloud/index.ts",
+4 -2
View File
@@ -38,9 +38,11 @@ describe('subdoc', () => {
if (id === 'xyWNqindHH') { if (id === 'xyWNqindHH') {
return; return;
} }
if (blocks[id]['sys:flavour'] === 'affine:surface' && !blocks[id]['prop:elements']) { if (
blocks[id]['sys:flavour'] === 'affine:surface' &&
!blocks[id]['prop:elements']
) {
blocks[id]['prop:elements'] = data[id]['prop:elements']; blocks[id]['prop:elements'] = data[id]['prop:elements'];
} }
expect(data[id]).toEqual(blocks[id]); expect(data[id]).toEqual(blocks[id]);
}); });
-28
View File
@@ -1,28 +0,0 @@
import { config, env } from './config';
import { isValidIPAddress } from './is-valid-ip-address';
let prefixUrl = '/';
if (typeof window === 'undefined' || env.isDesktop) {
// SSR or Desktop
const serverAPI = config.serverAPI;
if (isValidIPAddress(serverAPI.split(':')[0])) {
// This is for Server side rendering support
prefixUrl = new URL('http://' + config.serverAPI + '/').origin;
} else {
prefixUrl = serverAPI;
}
prefixUrl = prefixUrl.endsWith('/') ? prefixUrl : prefixUrl + '/';
} else {
const params = new URLSearchParams(window.location.search);
if (params.get('prefixUrl')) {
prefixUrl = params.get('prefixUrl') as string;
} else {
prefixUrl = window.location.origin + '/';
}
}
const apiUrl = new URL(prefixUrl);
const wsProtocol = apiUrl.protocol === 'https:' ? 'wss' : 'ws';
const websocketPrefixUrl = `${wsProtocol}://${apiUrl.host}`;
export { prefixUrl, websocketPrefixUrl };
+2 -2
View File
@@ -91,12 +91,12 @@ function runBlockMigration(
return; return;
} }
if (flavour === 'affine:surface' && version <= 3) { if (flavour === 'affine:surface' && version <= 3) {
if(data.has('elements')){ if (data.has('elements')) {
const elements = data.get('elements') as Y.Map<unknown>; const elements = data.get('elements') as Y.Map<unknown>;
data.set('prop:elements', elements.clone()); data.set('prop:elements', elements.clone());
data.delete('elements'); data.delete('elements');
} else { } else {
data.set('prop:elements', new Y.Map()) data.set('prop:elements', new Y.Map());
} }
} }
if (flavour === 'affine:embed') { if (flavour === 'affine:embed') {
+14
View File
@@ -1,5 +1,19 @@
// This file should has not side effect
import type { Workspace } from '@blocksuite/store'; import type { Workspace } from '@blocksuite/store';
declare global {
interface Window {
appInfo: {
electron: boolean;
};
}
}
//#region runtime variables
export const isBrowser = typeof window !== 'undefined';
export const isServer = !isBrowser && typeof navigator === 'undefined';
export const isDesktop = isBrowser && !!window.appInfo?.electron;
//#endregion
export const AFFINE_STORAGE_KEY = 'affine-local-storage-v2'; export const AFFINE_STORAGE_KEY = 'affine-local-storage-v2';
export const DEFAULT_WORKSPACE_NAME = 'Demo Workspace'; export const DEFAULT_WORKSPACE_NAME = 'Demo Workspace';
export const UNTITLED_WORKSPACE_NAME = 'Untitled'; export const UNTITLED_WORKSPACE_NAME = 'Untitled';
-2
View File
@@ -1,2 +0,0 @@
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
import '../hooks/src/use-block-suite-page-meta.ts';
+70 -41
View File
@@ -10,9 +10,12 @@ import type {
UpdaterHandlerManager, UpdaterHandlerManager,
WorkspaceHandlerManager, WorkspaceHandlerManager,
} from '@toeverything/infra'; } from '@toeverything/infra';
// fixme(himself65): remove `next/config` dependency
import getConfig from 'next/config'; import getConfig from 'next/config';
import { z } from 'zod'; import { z } from 'zod';
import { isBrowser, isDesktop, isServer } from './constant';
import { isValidIPAddress } from './is-valid-ip-address';
import { UaHelper } from './ua-helper'; import { UaHelper } from './ua-helper';
declare global { declare global {
@@ -31,6 +34,19 @@ declare global {
}; };
events: any; events: any;
} }
// eslint-disable-next-line no-var
var environment: Environment;
// eslint-disable-next-line no-var
var runtimeConfig: PublicRuntimeConfig;
// eslint-disable-next-line no-var
var $AFFINE_SETUP: boolean | undefined;
// eslint-disable-next-line no-var
var editorVersion: string | undefined;
// eslint-disable-next-line no-var
var prefixUrl: string;
// eslint-disable-next-line no-var
var websocketPrefixUrl: string;
} }
export const buildFlagsSchema = z.object({ export const buildFlagsSchema = z.object({
@@ -135,10 +151,31 @@ interface Desktop extends ChromeBrowser {
export type Environment = Browser | Server | Desktop; export type Environment = Browser | Server | Desktop;
export const env: Environment = (() => { function printBuildInfo() {
let environment = null; console.group('Build info');
console.log('Project:', config.PROJECT_NAME);
console.log(
'Build date:',
config.BUILD_DATE ? new Date(config.BUILD_DATE).toLocaleString() : 'Unknown'
);
console.log('Editor Version:', config.editorVersion);
console.log('Version:', config.gitVersion);
console.log(
'AFFiNE is an open source project, you can view its source code on GitHub!'
);
console.log(`https://github.com/toeverything/AFFiNE/tree/${config.hash}`);
console.groupEnd();
}
export function setupGlobal() {
if (globalThis.$AFFINE_SETUP) {
return;
}
globalThis.runtimeConfig = config;
let environment: Environment;
const isDebug = process.env.NODE_ENV === 'development'; const isDebug = process.env.NODE_ENV === 'development';
if (typeof window === 'undefined' || typeof navigator === 'undefined') { if (isServer) {
environment = { environment = {
isDesktop: false, isDesktop: false,
isBrowser: false, isBrowser: false,
@@ -150,7 +187,7 @@ export const env: Environment = (() => {
environment = { environment = {
origin: window.location.origin, origin: window.location.origin,
isDesktop: !!window.appInfo?.electron, isDesktop,
isBrowser: true, isBrowser: true,
isServer: false, isServer: false,
isDebug, isDebug,
@@ -177,45 +214,37 @@ export const env: Environment = (() => {
} }
} }
globalThis.environment = environment; globalThis.environment = environment;
return environment;
})();
function printBuildInfo() { if (environment.isBrowser) {
console.group('Build info');
console.log('Project:', config.PROJECT_NAME);
console.log(
'Build date:',
config.BUILD_DATE ? new Date(config.BUILD_DATE).toLocaleString() : 'Unknown'
);
console.log('Editor Version:', config.editorVersion);
console.log('Version:', config.gitVersion);
console.log(
'AFFiNE is an open source project, you can view its source code on GitHub!'
);
console.log(`https://github.com/toeverything/AFFiNE/tree/${config.hash}`);
console.groupEnd();
}
declare global {
// eslint-disable-next-line no-var
var environment: Environment;
// eslint-disable-next-line no-var
var $AFFINE_SETUP: boolean | undefined;
// eslint-disable-next-line no-var
var editorVersion: string | undefined;
}
export function setupGlobal() {
if (globalThis.$AFFINE_SETUP) {
return;
}
globalThis.environment = env;
if (env.isBrowser) {
printBuildInfo(); printBuildInfo();
globalThis.editorVersion = config.editorVersion; globalThis.editorVersion = global.editorVersion;
} }
let prefixUrl: string;
if (!isBrowser || isDesktop) {
// SSR or Desktop
const serverAPI = runtimeConfig.serverAPI;
if (isValidIPAddress(serverAPI.split(':')[0])) {
// This is for Server side rendering support
prefixUrl = new URL('http://' + runtimeConfig.serverAPI + '/').origin;
} else {
prefixUrl = serverAPI;
}
prefixUrl = prefixUrl.endsWith('/') ? prefixUrl : prefixUrl + '/';
} else {
const params = new URLSearchParams(window.location.search);
if (params.get('prefixUrl')) {
prefixUrl = params.get('prefixUrl') as string;
} else {
prefixUrl = window.location.origin + '/';
}
}
const apiUrl = new URL(prefixUrl);
const wsProtocol = apiUrl.protocol === 'https:' ? 'wss' : 'ws';
const websocketPrefixUrl = `${wsProtocol}://${apiUrl.host}`;
globalThis.prefixUrl = prefixUrl;
globalThis.websocketPrefixUrl = websocketPrefixUrl;
globalThis.$AFFINE_SETUP = true; globalThis.$AFFINE_SETUP = true;
} }
export { config };
-3
View File
@@ -1,3 +0,0 @@
export * from './api';
export * from './config';
export * from './constant';
+1 -1
View File
@@ -3,7 +3,7 @@
*/ */
import 'fake-indexeddb/auto'; import 'fake-indexeddb/auto';
import { UNTITLED_WORKSPACE_NAME } from '@affine/env'; import { UNTITLED_WORKSPACE_NAME } from '@affine/env/constant';
import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models'; import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models';
import type { Page } from '@blocksuite/store'; import type { Page } from '@blocksuite/store';
import { assertExists } from '@blocksuite/store'; import { assertExists } from '@blocksuite/store';
@@ -1,4 +1,4 @@
import { UNTITLED_WORKSPACE_NAME } from '@affine/env'; import { UNTITLED_WORKSPACE_NAME } from '@affine/env/constant';
import type { Workspace } from '@blocksuite/store'; import type { Workspace } from '@blocksuite/store';
import { assertExists } from '@blocksuite/store'; import { assertExists } from '@blocksuite/store';
import type { Atom, WritableAtom } from 'jotai'; import type { Atom, WritableAtom } from 'jotai';
-1
View File
@@ -26,7 +26,6 @@
"url": "git+https://github.com/toeverything/AFFiNE.git" "url": "git+https://github.com/toeverything/AFFiNE.git"
}, },
"dependencies": { "dependencies": {
"@affine/debug": "workspace:*",
"i18next": "^23.2.3", "i18next": "^23.2.3",
"react-i18next": "^13.0.0" "react-i18next": "^13.0.0"
}, },
+5 -1
View File
@@ -2,9 +2,13 @@ import '@affine/component/theme/global.css';
import '@affine/component/theme/theme.css'; import '@affine/component/theme/theme.css';
import { LOCALES, createI18n } from '@affine/i18n'; import { LOCALES, createI18n } from '@affine/i18n';
import { ThemeProvider, useTheme } from 'next-themes'; import { ThemeProvider, useTheme } from 'next-themes';
import { ComponentType, useEffect } from 'react'; import { setupGlobal } from '@affine/env/global';
import type { ComponentType } from 'react';
import { useEffect } from 'react';
import { useDarkMode } from 'storybook-dark-mode'; import { useDarkMode } from 'storybook-dark-mode';
setupGlobal();
export const parameters = { export const parameters = {
backgrounds: { disable: true }, backgrounds: { disable: true },
actions: { argTypesRegex: '^on[A-Z].*' }, actions: { argTypesRegex: '^on[A-Z].*' },
+6 -1
View File
@@ -12,5 +12,10 @@
}, },
"include": [".storybook/**/*"], "include": [".storybook/**/*"],
"exclude": ["lib"], "exclude": ["lib"],
"references": [{ "path": "../i18n" }] "references": [
{ "path": "../i18n" },
{
"path": "../env"
}
]
} }
+1 -1
View File
@@ -1,4 +1,4 @@
import { MessageCode, Messages } from '@affine/env'; import { MessageCode, Messages } from '@affine/env/constant';
import type { import type {
AcceptInvitingParams, AcceptInvitingParams,
DeleteWorkspaceParams, DeleteWorkspaceParams,
+3 -2
View File
@@ -1,3 +1,4 @@
import { isBrowser } from '@affine/env/constant';
import * as encoding from 'lib0/encoding'; import * as encoding from 'lib0/encoding';
import * as math from 'lib0/math'; import * as math from 'lib0/math';
import { Observable } from 'lib0/observable'; import { Observable } from 'lib0/observable';
@@ -217,7 +218,7 @@ export class KeckProvider extends Observable<string> {
'window unload' 'window unload'
); );
}; };
if (typeof window !== 'undefined') { if (isBrowser) {
window.addEventListener('unload', this._unloadHandler); window.addEventListener('unload', this._unloadHandler);
} else if (typeof process !== 'undefined') { } else if (typeof process !== 'undefined') {
process.on('exit', this._unloadHandler); process.on('exit', this._unloadHandler);
@@ -259,7 +260,7 @@ export class KeckProvider extends Observable<string> {
} }
clearInterval(this._checkInterval); clearInterval(this._checkInterval);
this.disconnect(); this.disconnect();
if (typeof window !== 'undefined') { if (isBrowser) {
window.removeEventListener('unload', this._unloadHandler); window.removeEventListener('unload', this._unloadHandler);
} else if (typeof process !== 'undefined') { } else if (typeof process !== 'undefined') {
process.off('exit', this._unloadHandler); process.off('exit', this._unloadHandler);
+1 -2
View File
@@ -1,5 +1,4 @@
import { DebugLogger } from '@affine/debug'; import { DebugLogger } from '@affine/debug';
import { env } from '@affine/env';
import { assertExists } from '@blocksuite/global/utils'; import { assertExists } from '@blocksuite/global/utils';
import { Slot } from '@blocksuite/store'; import { Slot } from '@blocksuite/store';
import { initializeApp } from 'firebase/app'; import { initializeApp } from 'firebase/app';
@@ -189,7 +188,7 @@ export function createAffineAuth(prefix = '/') {
} }
try { try {
let idToken: string | undefined; let idToken: string | undefined;
if (env.isDesktop) { if (environment.isDesktop) {
idToken = await signInWithElectron(auth); idToken = await signInWithElectron(auth);
} else { } else {
const response = await signInWithPopup(auth, provider); const response = await signInWithPopup(auth, provider);
+4 -1
View File
@@ -1,4 +1,4 @@
import { prefixUrl } from '@affine/env'; import { setupGlobal } from '@affine/env/global';
import { rootStore } from '@toeverything/plugin-infra/manager'; import { rootStore } from '@toeverything/plugin-infra/manager';
import { createUserApis, createWorkspaceApis } from './api/index'; import { createUserApis, createWorkspaceApis } from './api/index';
@@ -6,9 +6,12 @@ import { currentAffineUserAtom } from './atom';
import type { LoginResponse } from './login'; import type { LoginResponse } from './login';
import { createAffineAuth, parseIdToken, setLoginStorage } from './login'; import { createAffineAuth, parseIdToken, setLoginStorage } from './login';
setupGlobal();
export const affineAuth = createAffineAuth(prefixUrl); export const affineAuth = createAffineAuth(prefixUrl);
const affineApis = {} as ReturnType<typeof createUserApis> & const affineApis = {} as ReturnType<typeof createUserApis> &
ReturnType<typeof createWorkspaceApis>; ReturnType<typeof createWorkspaceApis>;
Object.assign(affineApis, createUserApis(prefixUrl)); Object.assign(affineApis, createUserApis(prefixUrl));
Object.assign(affineApis, createWorkspaceApis(prefixUrl)); Object.assign(affineApis, createWorkspaceApis(prefixUrl));
-1
View File
@@ -1,5 +1,4 @@
import { DebugLogger } from '@affine/debug'; import { DebugLogger } from '@affine/debug';
import { websocketPrefixUrl } from '@affine/env/api';
import type { WorkspaceCRUD } from '@affine/env/workspace'; import type { WorkspaceCRUD } from '@affine/env/workspace';
import type { WorkspaceFlavour } from '@affine/env/workspace'; import type { WorkspaceFlavour } from '@affine/env/workspace';
import { import {
+4 -5
View File
@@ -1,3 +1,4 @@
import { isBrowser } from '@affine/env/constant';
import type { WorkspaceFlavour } from '@affine/env/workspace'; import type { WorkspaceFlavour } from '@affine/env/workspace';
import type { WorkspaceVersion } from '@affine/env/workspace'; import type { WorkspaceVersion } from '@affine/env/workspace';
import type { EditorContainer } from '@blocksuite/editor'; import type { EditorContainer } from '@blocksuite/editor';
@@ -44,14 +45,12 @@ export const rootWorkspacesMetadataAtom = atomWithStorage<
export const rootCurrentWorkspaceIdAtom = atom<string | null>(null); export const rootCurrentWorkspaceIdAtom = atom<string | null>(null);
rootCurrentWorkspaceIdAtom.onMount = set => { rootCurrentWorkspaceIdAtom.onMount = set => {
if (typeof window !== 'undefined') { if (isBrowser) {
const callback = (url: string) => { const callback = (url: string) => {
const value = url.split('/')[2]; const value = url.split('/')[2];
if (value) { if (value) {
set(value); set(value);
if (typeof window !== 'undefined') { localStorage.setItem('last_workspace_id', value);
localStorage.setItem('last_workspace_id', value);
}
} else { } else {
set(null); set(null);
} }
@@ -68,7 +67,7 @@ rootCurrentWorkspaceIdAtom.onMount = set => {
export const rootCurrentPageIdAtom = atom<string | null>(null); export const rootCurrentPageIdAtom = atom<string | null>(null);
rootCurrentPageIdAtom.onMount = set => { rootCurrentPageIdAtom.onMount = set => {
if (typeof window !== 'undefined') { if (isBrowser) {
const callback = (url: string) => { const callback = (url: string) => {
const value = url.split('/')[3]; const value = url.split('/')[3];
if (value) { if (value) {
+5 -2
View File
@@ -1,5 +1,4 @@
import { DebugLogger } from '@affine/debug'; import { DebugLogger } from '@affine/debug';
import { config } from '@affine/env';
import type { LocalWorkspace, WorkspaceCRUD } from '@affine/env/workspace'; import type { LocalWorkspace, WorkspaceCRUD } from '@affine/env/workspace';
import { WorkspaceFlavour } from '@affine/env/workspace'; import { WorkspaceFlavour } from '@affine/env/workspace';
import { nanoid, Workspace as BlockSuiteWorkspace } from '@blocksuite/store'; import { nanoid, Workspace as BlockSuiteWorkspace } from '@blocksuite/store';
@@ -112,7 +111,11 @@ export const CRUD: WorkspaceCRUD<WorkspaceFlavour.LOCAL> = {
: []; : [];
// workspaces in desktop // workspaces in desktop
if (window.apis && environment.isDesktop && config.enableSQLiteProvider) { if (
window.apis &&
environment.isDesktop &&
runtimeConfig.enableSQLiteProvider
) {
const desktopIds = (await window.apis.workspace.list()).map(([id]) => id); const desktopIds = (await window.apis.workspace.list()).map(([id]) => id);
// the ids maybe a subset of the local storage // the ids maybe a subset of the local storage
const moreWorkspaces = desktopIds.filter( const moreWorkspaces = desktopIds.filter(
+4 -4
View File
@@ -1,4 +1,3 @@
import { config, websocketPrefixUrl } from '@affine/env';
import type { import type {
AffineWebSocketProvider, AffineWebSocketProvider,
LocalIndexedDBBackgroundProvider, LocalIndexedDBBackgroundProvider,
@@ -169,11 +168,11 @@ export const createLocalProviders = (): DocProviderCreator[] => {
createIndexedDBDownloadProvider, createIndexedDBDownloadProvider,
] as DocProviderCreator[]; ] as DocProviderCreator[];
if (config.enableBroadcastChannelProvider) { if (runtimeConfig.enableBroadcastChannelProvider) {
providers.push(createBroadcastChannelProvider); providers.push(createBroadcastChannelProvider);
} }
if (environment.isDesktop && config.enableSQLiteProvider) { if (environment.isDesktop && runtimeConfig.enableSQLiteProvider) {
providers.push(createSQLiteProvider, createSQLiteDBDownloadProvider); providers.push(createSQLiteProvider, createSQLiteDBDownloadProvider);
} }
@@ -185,7 +184,8 @@ export const createAffineProviders = (): DocProviderCreator[] => {
[ [
createAffineDownloadProvider, createAffineDownloadProvider,
createAffineWebSocketProvider, createAffineWebSocketProvider,
config.enableBroadcastChannelProvider && createBroadcastChannelProvider, runtimeConfig.enableBroadcastChannelProvider &&
createBroadcastChannelProvider,
createIndexedDBDownloadProvider, createIndexedDBDownloadProvider,
] as DocProviderCreator[] ] as DocProviderCreator[]
).filter(v => Boolean(v)); ).filter(v => Boolean(v));
+6 -6
View File
@@ -1,5 +1,5 @@
import type { BlockSuiteFeatureFlags } from '@affine/env'; import { isBrowser, isDesktop } from '@affine/env/constant';
import { config } from '@affine/env'; import type { BlockSuiteFeatureFlags } from '@affine/env/global';
import { WorkspaceFlavour } from '@affine/env/workspace'; import { WorkspaceFlavour } from '@affine/env/workspace';
import { import {
createAffineProviders, createAffineProviders,
@@ -26,7 +26,7 @@ export function cleanupWorkspace(flavour: WorkspaceFlavour) {
} }
function setEditorFlags(workspace: Workspace) { function setEditorFlags(workspace: Workspace) {
Object.entries(config.editorFlags).forEach(([key, value]) => { Object.entries(runtimeConfig.editorFlags).forEach(([key, value]) => {
workspace.awarenessStore.setFlag( workspace.awarenessStore.setFlag(
key as keyof BlockSuiteFeatureFlags, key as keyof BlockSuiteFeatureFlags,
value value
@@ -96,9 +96,9 @@ export function createEmptyBlockSuiteWorkspace(
} }
providerCreators.push(...createAffineProviders()); providerCreators.push(...createAffineProviders());
} else { } else {
if (typeof window !== 'undefined') { if (isBrowser) {
blobStorages.push(createIndexeddbStorage); blobStorages.push(createIndexeddbStorage);
if (environment.isDesktop) { if (isDesktop) {
blobStorages.push(createSQLiteStorage); blobStorages.push(createSQLiteStorage);
} }
} }
@@ -107,7 +107,7 @@ export function createEmptyBlockSuiteWorkspace(
const workspace = new Workspace({ const workspace = new Workspace({
id, id,
isSSR: typeof window === 'undefined', isSSR: !isBrowser,
providerCreators: typeof window === 'undefined' ? [] : providerCreators, providerCreators: typeof window === 'undefined' ? [] : providerCreators,
blobStorages: blobStorages, blobStorages: blobStorages,
idGenerator, idGenerator,
+3
View File
@@ -0,0 +1,3 @@
import { setupGlobal } from '@affine/env/global';
setupGlobal();
+6 -1
View File
@@ -7,5 +7,10 @@
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"outDir": "lib" "outDir": "lib"
}, },
"include": ["vitest.config.ts", "scripts"] "include": ["vitest.config.ts", "scripts"],
"references": [
{
"path": "./packages/env"
}
]
} }
+1
View File
@@ -26,6 +26,7 @@ export default defineConfig({
resolve(rootDir, './scripts/setup/i18n.ts'), resolve(rootDir, './scripts/setup/i18n.ts'),
resolve(rootDir, './scripts/setup/search.ts'), resolve(rootDir, './scripts/setup/search.ts'),
resolve(rootDir, './scripts/setup/lottie-web.ts'), resolve(rootDir, './scripts/setup/lottie-web.ts'),
resolve(rootDir, './scripts/setup/global.ts'),
], ],
// split tests that include native addons or not // split tests that include native addons or not
include: process.env.NATIVE_TEST include: process.env.NATIVE_TEST
-1
View File
@@ -277,7 +277,6 @@ __metadata:
version: 0.0.0-use.local version: 0.0.0-use.local
resolution: "@affine/i18n@workspace:packages/i18n" resolution: "@affine/i18n@workspace:packages/i18n"
dependencies: dependencies:
"@affine/debug": "workspace:*"
"@types/node": ^18.16.18 "@types/node": ^18.16.18
"@types/prettier": ^2.7.3 "@types/prettier": ^2.7.3
i18next: ^23.2.3 i18next: ^23.2.3