refactor(core): clear build config (#8268)

remove build config

allowLocalWorkspace -> FeatureFlag
enablePreloading -> removed
enableNewSettingUnstableApi -> removed
enableExperimentalFeature -> removed
enableThemeEditor -> FeatureFlag

remove some unused code
This commit is contained in:
EYHN
2024-09-18 06:33:24 +00:00
parent 46f8237a46
commit fab23d226d
17 changed files with 91 additions and 611 deletions

View File

@@ -1,5 +1,4 @@
CHANGELOG_URL=
ENABLE_PRELOADING=
ENABLE_NEW_SETTING_UNSTABLE_API=
ENABLE_CAPTCHA=
CAPTCHA_SITE_KEY=

12
nx.json
View File

@@ -81,9 +81,6 @@
"test": {
"outputs": ["{workspaceRoot}/.nyc_output"],
"inputs": [
{
"env": "ENABLE_PRELOADING"
},
{
"env": "COVERAGE"
}
@@ -92,9 +89,6 @@
"test:ui": {
"outputs": ["{workspaceRoot}/.nyc_output"],
"inputs": [
{
"env": "ENABLE_PRELOADING"
},
{
"env": "COVERAGE"
}
@@ -102,11 +96,7 @@
},
"test:coverage": {
"outputs": ["{workspaceRoot}/.nyc_output"],
"inputs": [
{
"env": "ENABLE_PRELOADING"
}
]
"inputs": []
}
}
}

View File

@@ -31,12 +31,6 @@ export type BUILD_CONFIG_TYPE = {
imageProxyUrl: string;
linkPreviewUrl: string;
allowLocalWorkspace: boolean;
enablePreloading: boolean;
enableNewSettingUnstableApi: boolean;
enableExperimentalFeature: boolean;
enableThemeEditor: boolean;
// TODO(@forehalo): remove
isSelfHosted: boolean;
};

View File

@@ -8,20 +8,9 @@ setupGlobal();
const logger = new DebugLogger('affine:settings');
export type DateFormats =
| 'MM/dd/YYYY'
| 'dd/MM/YYYY'
| 'YYYY-MM-dd'
| 'YYYY.MM.dd'
| 'YYYY/MM/dd'
| 'dd-MMM-YYYY'
| 'dd MMMM YYYY';
export type AppSetting = {
clientBorder: boolean;
windowFrameStyle: 'frameless' | 'NativeTitleBar';
dateFormat: DateFormats;
startWeekOnMonday: boolean;
enableBlurBackground: boolean;
enableNoisyBackground: boolean;
autoCheckUpdate: boolean;
@@ -33,21 +22,9 @@ export const windowFrameStyleOptions: AppSetting['windowFrameStyle'][] = [
'NativeTitleBar',
];
export const dateFormatOptions: DateFormats[] = [
'MM/dd/YYYY',
'dd/MM/YYYY',
'YYYY-MM-dd',
'YYYY.MM.dd',
'YYYY/MM/dd',
'dd-MMM-YYYY',
'dd MMMM YYYY',
];
const appSettingBaseAtom = atomWithStorage<AppSetting>('affine-settings', {
clientBorder: BUILD_CONFIG.isElectron && !environment.isWindows,
windowFrameStyle: 'frameless',
dateFormat: dateFormatOptions[0],
startWeekOnMonday: false,
enableBlurBackground: true,
enableNoisyBackground: true,
autoCheckUpdate: true,

View File

@@ -118,6 +118,20 @@ export const AFFINE_FLAGS = {
configurable: isDesktopEnvironment,
defaultState: false,
},
enable_theme_editor: {
category: 'affine',
displayName: 'Theme Editor',
description: 'Enables theme editor.',
configurable: isCanaryBuild,
defaultState: isCanaryBuild,
},
enable_local_workspace: {
category: 'affine',
displayName: 'Allow create local workspace',
description: 'Allow create local workspace.',
configurable: isCanaryBuild,
defaultState: isDesktopEnvironment || isCanaryBuild,
},
} satisfies { [key in string]: FlagInfo };
export type AFFINE_FLAGS = typeof AFFINE_FLAGS;

View File

@@ -1,77 +0,0 @@
import { cssVar } from '@toeverything/theme';
import { style } from '@vanilla-extract/css';
export const header = style({
position: 'relative',
marginTop: '44px',
});
export const subTitle = style({
fontSize: cssVar('fontSm'),
color: cssVar('textPrimaryColor'),
fontWeight: 600,
});
export const avatarWrapper = style({
display: 'flex',
margin: '10px 0',
});
export const workspaceNameWrapper = style({
display: 'flex',
flexDirection: 'column',
gap: '8px',
padding: '12px 0',
});
export const affineCloudWrapper = style({
display: 'flex',
flexDirection: 'column',
gap: '6px',
paddingTop: '10px',
});
export const card = style({
padding: '12px',
display: 'flex',
alignItems: 'center',
borderRadius: '8px',
backgroundColor: cssVar('backgroundSecondaryColor'),
minHeight: '114px',
position: 'relative',
});
export const cardText = style({
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
width: '100%',
gap: '12px',
});
export const cardTitle = style({
fontSize: cssVar('fontBase'),
color: cssVar('textPrimaryColor'),
display: 'flex',
justifyContent: 'space-between',
});
export const cardDescription = style({
fontSize: cssVar('fontXs'),
color: cssVar('textSecondaryColor'),
maxWidth: '288px',
});
export const cloudTips = style({
fontSize: cssVar('fontXs'),
color: cssVar('textSecondaryColor'),
});
export const cloudSvgContainer = style({
width: '146px',
display: 'flex',
justifyContent: 'flex-end',
alignItems: 'center',
position: 'absolute',
bottom: '0',
right: '0',
pointerEvents: 'none',
});

View File

@@ -1,290 +0,0 @@
import { Avatar, Input, Switch, toast } from '@affine/component';
import type { ConfirmModalProps } from '@affine/component/ui/modal';
import { ConfirmModal, Modal } from '@affine/component/ui/modal';
import { authAtom } from '@affine/core/components/atoms';
import { useAsyncCallback } from '@affine/core/components/hooks/affine-async-hooks';
import { DebugLogger } from '@affine/debug';
import { apis } from '@affine/electron-api';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { useI18n } from '@affine/i18n';
import { track } from '@affine/track';
import {
DocsService,
useLiveData,
useService,
WorkspacesService,
} from '@toeverything/infra';
import { useSetAtom } from 'jotai';
import type { KeyboardEvent } from 'react';
import { useCallback, useLayoutEffect, useState } from 'react';
import { buildShowcaseWorkspace } from '../../../bootstrap/first-app-data';
import { AuthService } from '../../../modules/cloud';
import { _addLocalWorkspace } from '../../../modules/workspace-engine';
import { CloudSvg } from '../share-page-modal/cloud-svg';
import * as styles from './index.css';
type CreateWorkspaceStep =
| 'set-db-location'
| 'name-workspace'
| 'set-syncing-mode';
export type CreateWorkspaceMode = 'add' | 'new' | false;
const logger = new DebugLogger('CreateWorkspaceModal');
interface ModalProps {
mode: CreateWorkspaceMode; // false means not open
onClose: () => void;
onCreate: (id: string, defaultDocId?: string) => void;
}
interface NameWorkspaceContentProps extends ConfirmModalProps {
loading: boolean;
onConfirmName: (
name: string,
workspaceFlavour: WorkspaceFlavour,
avatar?: File
) => void;
}
const shouldEnableCloud = !BUILD_CONFIG.allowLocalWorkspace;
const NameWorkspaceContent = ({
loading,
onConfirmName,
...props
}: NameWorkspaceContentProps) => {
const t = useI18n();
const [workspaceName, setWorkspaceName] = useState('');
const [enable, setEnable] = useState(shouldEnableCloud);
const session = useService(AuthService).session;
const loginStatus = useLiveData(session.status$);
const setOpenSignIn = useSetAtom(authAtom);
const openSignInModal = useCallback(() => {
setOpenSignIn(state => ({
...state,
openModal: true,
}));
}, [setOpenSignIn]);
const onSwitchChange = useCallback(
(checked: boolean) => {
if (loginStatus !== 'authenticated') {
return openSignInModal();
}
return setEnable(checked);
},
[loginStatus, openSignInModal]
);
const handleCreateWorkspace = useCallback(() => {
onConfirmName(
workspaceName,
enable ? WorkspaceFlavour.AFFINE_CLOUD : WorkspaceFlavour.LOCAL
);
}, [enable, onConfirmName, workspaceName]);
const handleKeyDown = useCallback(
(event: KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Enter' && workspaceName) {
handleCreateWorkspace();
}
},
[handleCreateWorkspace, workspaceName]
);
// Currently, when we create a new workspace and upload an avatar at the same time,
// an error occurs after the creation is successful: get blob 404 not found
return (
<ConfirmModal
defaultOpen={true}
title={t['com.affine.nameWorkspace.title']()}
description={t['com.affine.nameWorkspace.description']()}
cancelText={t['com.affine.nameWorkspace.button.cancel']()}
confirmText={t['com.affine.nameWorkspace.button.create']()}
confirmButtonOptions={{
variant: 'primary',
loading,
disabled: !workspaceName,
['data-testid' as string]: 'create-workspace-create-button',
}}
closeButtonOptions={{
['data-testid' as string]: 'create-workspace-close-button',
}}
onConfirm={handleCreateWorkspace}
{...props}
>
<div className={styles.avatarWrapper}>
<Avatar size={56} name={workspaceName} colorfulFallback />
</div>
<div className={styles.workspaceNameWrapper}>
<div className={styles.subTitle}>
{t['com.affine.nameWorkspace.subtitle.workspace-name']()}
</div>
<Input
autoFocus
data-testid="create-workspace-input"
onKeyDown={handleKeyDown}
placeholder={t['com.affine.nameWorkspace.placeholder']()}
maxLength={64}
minLength={0}
onChange={setWorkspaceName}
size="large"
/>
</div>
<div className={styles.affineCloudWrapper}>
<div className={styles.subTitle}>{t['AFFiNE Cloud']()}</div>
<div className={styles.card}>
<div className={styles.cardText}>
<div className={styles.cardTitle}>
<span>{t['com.affine.nameWorkspace.affine-cloud.title']()}</span>
<Switch
checked={enable}
onChange={onSwitchChange}
disabled={shouldEnableCloud}
/>
</div>
<div className={styles.cardDescription}>
{t['com.affine.nameWorkspace.affine-cloud.description']()}
</div>
</div>
<div className={styles.cloudSvgContainer}>
<CloudSvg />
</div>
</div>
{shouldEnableCloud ? (
<a
className={styles.cloudTips}
href={BUILD_CONFIG.downloadUrl}
target="_blank"
rel="noreferrer"
>
{t['com.affine.nameWorkspace.affine-cloud.web-tips']()}
</a>
) : null}
</div>
</ConfirmModal>
);
};
export const CreateWorkspaceModal = ({
mode,
onClose,
onCreate,
}: ModalProps) => {
const [step, setStep] = useState<CreateWorkspaceStep>();
const t = useI18n();
const workspacesService = useService(WorkspacesService);
const docsService = useService(DocsService);
const [loading, setLoading] = useState(false);
// TODO(@Peng): maybe refactor using xstate?
useLayoutEffect(() => {
let canceled = false;
// if mode changed, reset step
if (mode === 'add') {
// a hack for now
// when adding a workspace, we will immediately let user select a db file
// after it is done, it will effectively add a new workspace to app-data folder
// so after that, we will be able to load it via importLocalWorkspace
(async () => {
if (!apis) {
return;
}
logger.info('load db file');
setStep(undefined);
const result = await apis.dialog.loadDBFile();
if (result.workspaceId && !canceled) {
_addLocalWorkspace(result.workspaceId);
workspacesService.list.revalidate();
onCreate(result.workspaceId);
} else if (result.error || result.canceled) {
if (result.error) {
toast(t[result.error]());
}
onClose();
}
})().catch(err => {
console.error(err);
});
} else if (mode === 'new') {
setStep('name-workspace');
} else {
setStep(undefined);
}
return () => {
canceled = true;
};
}, [mode, onClose, onCreate, t, workspacesService]);
const onConfirmName = useAsyncCallback(
async (name: string, workspaceFlavour: WorkspaceFlavour) => {
track.$.$.$.createWorkspace({ flavour: workspaceFlavour });
if (loading) return;
setLoading(true);
// this will be the last step for web for now
// fix me later
if (BUILD_CONFIG.enablePreloading) {
const { meta, defaultDocId } = await buildShowcaseWorkspace(
workspacesService,
workspaceFlavour,
name
);
onCreate(meta.id, defaultDocId);
} else {
let defaultDocId: string | undefined = undefined;
const { id } = await workspacesService.create(
workspaceFlavour,
async workspace => {
workspace.meta.initialize();
workspace.meta.setName(name);
const page = docsService.createDoc();
defaultDocId = page.id;
}
);
onCreate(id, defaultDocId);
}
setLoading(false);
},
[docsService, loading, onCreate, workspacesService]
);
const onOpenChange = useCallback(
(open: boolean) => {
if (!open) {
onClose();
}
},
[onClose]
);
if (step === 'name-workspace') {
return (
<NameWorkspaceContent
loading={loading}
open={mode !== false && !!step}
onOpenChange={onOpenChange}
onConfirmName={onConfirmName}
/>
);
}
return (
<Modal
open={mode !== false && !!step}
width={560}
onOpenChange={onOpenChange}
contentOptions={{
style: { padding: '10px' },
}}
>
<div className={styles.header}></div>
</Modal>
);
};

View File

@@ -1,58 +0,0 @@
import { Menu, MenuItem, MenuTrigger } from '@affine/component/ui/menu';
import type { DateFormats } from '@toeverything/infra';
import { dateFormatOptions } from '@toeverything/infra';
import dayjs from 'dayjs';
import { useCallback } from 'react';
import { useAppSettingHelper } from '../../../../../components/hooks/affine/use-app-setting-helper';
interface DateFormatMenuContentProps {
currentOption: DateFormats;
onSelect: (option: DateFormats) => void;
}
const DateFormatMenuContent = ({
onSelect,
currentOption,
}: DateFormatMenuContentProps) => {
return (
<>
{dateFormatOptions.map(option => {
return (
<MenuItem
key={option}
selected={currentOption === option}
onSelect={() => onSelect(option)}
>
{dayjs(new Date()).format(option)}
</MenuItem>
);
})}
</>
);
};
export const DateFormatSetting = () => {
const { appSettings, updateSettings } = useAppSettingHelper();
const handleSelect = useCallback(
(option: DateFormats) => {
updateSettings('dateFormat', option);
},
[updateSettings]
);
return (
<Menu
items={
<DateFormatMenuContent
onSelect={handleSelect}
currentOption={appSettings.dateFormat}
/>
}
>
<MenuTrigger data-testid="date-format-menu-trigger" block>
{dayjs(new Date()).format(appSettings.dateFormat)}
</MenuTrigger>
</Menu>
);
};

View File

@@ -6,15 +6,17 @@ import {
SettingWrapper,
} from '@affine/component/setting-components';
import { useI18n } from '@affine/i18n';
import type { AppSetting } from '@toeverything/infra';
import { windowFrameStyleOptions } from '@toeverything/infra';
import {
FeatureFlagService,
useLiveData,
useService,
} from '@toeverything/infra';
import { useTheme } from 'next-themes';
import { useCallback, useMemo } from 'react';
import { useAppSettingHelper } from '../../../../../components/hooks/affine/use-app-setting-helper';
import { LanguageMenu } from '../../../language-menu';
import { Page } from '../editor/page';
import { DateFormatSetting } from './date-format-setting';
import { settingWrapper } from './style.css';
import { ThemeEditorSetting } from './theme-editor-setting';
@@ -62,6 +64,10 @@ export const ThemeSettings = () => {
export const AppearanceSettings = () => {
const t = useI18n();
const featureFlagService = useService(FeatureFlagService);
const enableThemeEditor = useLiveData(
featureFlagService.flags.enable_theme_editor.$
);
const { appSettings, updateSettings } = useAppSettingHelper();
return (
@@ -98,51 +104,10 @@ export const AppearanceSettings = () => {
/>
</SettingRow>
) : null}
{BUILD_CONFIG.enableNewSettingUnstableApi && BUILD_CONFIG.isElectron ? (
<SettingRow
name={t['com.affine.appearanceSettings.windowFrame.title']()}
desc={t['com.affine.appearanceSettings.windowFrame.description']()}
>
<RadioGroup
items={windowFrameStyleOptions.map(option => ({
value: option,
label:
t[`com.affine.appearanceSettings.windowFrame.${option}`](),
}))}
value={appSettings.windowFrameStyle}
className={settingWrapper}
width={250}
onChange={(value: AppSetting['windowFrameStyle']) => {
updateSettings('windowFrameStyle', value);
}}
/>
</SettingRow>
) : null}
{BUILD_CONFIG.enableThemeEditor ? <ThemeEditorSetting /> : null}
{enableThemeEditor ? <ThemeEditorSetting /> : null}
</SettingWrapper>
{/* // TODO(@JimmFly): remove Page component when stable release */}
<Page />
{BUILD_CONFIG.enableNewSettingUnstableApi ? (
<SettingWrapper title={t['com.affine.appearanceSettings.date.title']()}>
<SettingRow
name={t['com.affine.appearanceSettings.dateFormat.title']()}
desc={t['com.affine.appearanceSettings.dateFormat.description']()}
>
<div className={settingWrapper}>
<DateFormatSetting />
</div>
</SettingRow>
<SettingRow
name={t['com.affine.appearanceSettings.startWeek.title']()}
desc={t['com.affine.appearanceSettings.startWeek.description']()}
>
<Switch
checked={appSettings.startWeekOnMonday}
onChange={checked => updateSettings('startWeekOnMonday', checked)}
/>
</SettingRow>
</SettingWrapper>
) : null}
{BUILD_CONFIG.isElectron ? (
<SettingWrapper

View File

@@ -107,14 +107,12 @@ export const useGeneralSettingList = (): GeneralSettingList => {
}
}
if (BUILD_CONFIG.enableExperimentalFeature) {
settings.push({
key: 'experimental-features',
title: t['com.affine.settings.workspace.experimental-features'](),
icon: ExperimentIcon,
testId: 'experimental-features-trigger',
});
}
settings.push({
key: 'experimental-features',
title: t['com.affine.settings.workspace.experimental-features'](),
icon: ExperimentIcon,
testId: 'experimental-features-trigger',
});
return settings;
};

View File

@@ -1,6 +1,11 @@
import { MenuItem } from '@affine/component/ui/menu';
import { useI18n } from '@affine/i18n';
import { ImportIcon, PlusIcon } from '@blocksuite/icons/rc';
import {
FeatureFlagService,
useLiveData,
useService,
} from '@toeverything/infra';
import * as styles from './index.css';
@@ -12,6 +17,10 @@ export const AddWorkspace = ({
onNewWorkspace?: () => void;
}) => {
const t = useI18n();
const featureFlagService = useService(FeatureFlagService);
const enableLocalWorkspace = useLiveData(
featureFlagService.flags.enable_local_workspace.$
);
return (
<div>
@@ -36,7 +45,7 @@ export const AddWorkspace = ({
className={styles.ItemContainer}
>
<div className={styles.ItemText}>
{BUILD_CONFIG.allowLocalWorkspace
{enableLocalWorkspace
? t['com.affine.workspaceList.addWorkspace.create']()
: t['com.affine.workspaceList.addWorkspace.create-cloud']()}
</div>

View File

@@ -8,6 +8,7 @@ import { useI18n } from '@affine/i18n';
import { track } from '@affine/track';
import { Logo1Icon } from '@blocksuite/icons/rc';
import {
FeatureFlagService,
useLiveData,
useService,
type WorkspaceMetadata,
@@ -75,6 +76,7 @@ const UserWithWorkspaceListInner = ({
}: UserWithWorkspaceListProps) => {
const createWorkspaceDialogService = useService(CreateWorkspaceDialogService);
const session = useLiveData(useService(AuthService).session.session$);
const featureFlagService = useService(FeatureFlagService);
const isAuthenticated = session.status === 'authenticated';
@@ -88,7 +90,10 @@ const UserWithWorkspaceListInner = ({
}, [setOpenSignIn]);
const onNewWorkspace = useCallback(() => {
if (!isAuthenticated && !BUILD_CONFIG.allowLocalWorkspace) {
if (
!isAuthenticated &&
!featureFlagService.flags.enable_local_workspace.value
) {
return openSignInModal();
}
track.$.navigationPanel.workspaceList.createWorkspace();
@@ -99,7 +104,8 @@ const UserWithWorkspaceListInner = ({
});
onEventEnd?.();
}, [
createWorkspaceDialogService.dialog,
createWorkspaceDialogService,
featureFlagService,
isAuthenticated,
onCreatedWorkspace,
onEventEnd,

View File

@@ -14,14 +14,14 @@ import {
} from 'react';
import { type LoaderFunction, useSearchParams } from 'react-router-dom';
import {
buildShowcaseWorkspace,
createFirstAppData,
} from '../../bootstrap/first-app-data';
import { AppFallback } from '../../components/affine/app-container';
import { useNavigateHelper } from '../../components/hooks/use-navigate-helper';
import { WorkspaceNavigator } from '../../components/workspace-selector';
import { AuthService } from '../../modules/cloud';
import {
buildShowcaseWorkspace,
createFirstAppData,
} from '../../utils/first-app-data';
export const loader: LoaderFunction = async () => {
return null;

View File

@@ -9,7 +9,7 @@ import { WorkspaceFlavour } from '@affine/env/workspace';
import { useI18n } from '@affine/i18n';
import { track } from '@affine/track';
import {
initEmptyPage,
FeatureFlagService,
useLiveData,
useService,
WorkspacesService,
@@ -18,9 +18,9 @@ import { useSetAtom } from 'jotai';
import type { KeyboardEvent } from 'react';
import { useCallback, useLayoutEffect, useState } from 'react';
import { buildShowcaseWorkspace } from '../../../bootstrap/first-app-data';
import { AuthService } from '../../../modules/cloud';
import { _addLocalWorkspace } from '../../../modules/workspace-engine';
import { buildShowcaseWorkspace } from '../../../utils/first-app-data';
import { CreateWorkspaceDialogService } from '../services/dialog';
import * as styles from './dialog.css';
@@ -35,8 +35,6 @@ interface NameWorkspaceContentProps extends ConfirmModalProps {
) => void;
}
const shouldEnableCloud = !BUILD_CONFIG.allowLocalWorkspace;
const NameWorkspaceContent = ({
loading,
onConfirmName,
@@ -44,7 +42,11 @@ const NameWorkspaceContent = ({
}: NameWorkspaceContentProps) => {
const t = useI18n();
const [workspaceName, setWorkspaceName] = useState('');
const [enable, setEnable] = useState(shouldEnableCloud);
const featureFlagService = useService(FeatureFlagService);
const enableLocalWorkspace = useLiveData(
featureFlagService.flags.enable_local_workspace.$
);
const [enable, setEnable] = useState(!enableLocalWorkspace);
const session = useService(AuthService).session;
const loginStatus = useLiveData(session.status$);
@@ -132,7 +134,7 @@ const NameWorkspaceContent = ({
<Switch
checked={enable}
onChange={onSwitchChange}
disabled={shouldEnableCloud}
disabled={!enableLocalWorkspace}
/>
</div>
<div className={styles.cardDescription}>
@@ -143,7 +145,7 @@ const NameWorkspaceContent = ({
<CloudSvg />
</div>
</div>
{shouldEnableCloud ? (
{!enableLocalWorkspace ? (
<a
className={styles.cloudTips}
href={BUILD_CONFIG.downloadUrl}
@@ -213,27 +215,12 @@ const CreateWorkspaceDialog = () => {
// this will be the last step for web for now
// fix me later
if (BUILD_CONFIG.enablePreloading) {
const { meta, defaultDocId } = await buildShowcaseWorkspace(
workspacesService,
workspaceFlavour,
name
);
createWorkspaceDialogService.dialog.callback({ meta, defaultDocId });
} else {
let defaultDocId: string | undefined = undefined;
const meta = await workspacesService.create(
workspaceFlavour,
async workspace => {
workspace.meta.initialize();
workspace.meta.setName(name);
const page = workspace.createDoc();
defaultDocId = page.id;
initEmptyPage(page);
}
);
createWorkspaceDialogService.dialog.callback({ meta, defaultDocId });
}
const { meta, defaultDocId } = await buildShowcaseWorkspace(
workspacesService,
workspaceFlavour,
name
);
createWorkspaceDialogService.dialog.callback({ meta, defaultDocId });
createWorkspaceDialogService.dialog.close();
setLoading(false);

View File

@@ -1,4 +1,8 @@
import { useService } from '@toeverything/infra';
import {
FeatureFlagService,
useLiveData,
useServices,
} from '@toeverything/infra';
import { useTheme } from 'next-themes';
import { useEffect } from 'react';
@@ -7,16 +11,22 @@ import { ThemeEditorService } from '../services/theme-editor';
let _provided = false;
export const useCustomTheme = (target: HTMLElement) => {
const themeEditor = useService(ThemeEditorService);
const { themeEditorService, featureFlagService } = useServices({
ThemeEditorService,
FeatureFlagService,
});
const enableThemeEditor = useLiveData(
featureFlagService.flags.enable_theme_editor.$
);
const { resolvedTheme } = useTheme();
useEffect(() => {
if (!BUILD_CONFIG.enableThemeEditor) return;
if (!enableThemeEditor) return;
if (_provided) return;
_provided = true;
const sub = themeEditor.customTheme$.subscribe(themeObj => {
const sub = themeEditorService.customTheme$.subscribe(themeObj => {
if (!themeObj) return;
const mode = resolvedTheme === 'dark' ? 'dark' : 'light';
@@ -37,7 +47,7 @@ export const useCustomTheme = (target: HTMLElement) => {
_provided = false;
sub.unsubscribe();
};
}, [resolvedTheme, target.style, themeEditor.customTheme$]);
}, [resolvedTheme, target.style, enableThemeEditor, themeEditorService]);
};
export const CustomThemeModifier = () => {

View File

@@ -4,7 +4,7 @@ import { WorkspaceFlavour } from '@affine/env/workspace';
import onboardingUrl from '@affine/templates/onboarding.zip';
import { ZipTransformer } from '@blocksuite/blocks';
import type { WorkspacesService } from '@toeverything/infra';
import { DocsService, initEmptyPage } from '@toeverything/infra';
import { DocsService } from '@toeverything/infra';
export async function buildShowcaseWorkspace(
workspacesService: WorkspacesService,
@@ -46,27 +46,11 @@ export async function createFirstAppData(workspacesService: WorkspacesService) {
return;
}
localStorage.setItem('is-first-open', 'false');
if (BUILD_CONFIG.enablePreloading) {
const { meta, defaultDocId } = await buildShowcaseWorkspace(
workspacesService,
WorkspaceFlavour.LOCAL,
DEFAULT_WORKSPACE_NAME
);
logger.info('create first workspace', defaultDocId);
return { meta, defaultPageId: defaultDocId };
} else {
let defaultPageId: string | undefined = undefined;
const workspaceMetadata = await workspacesService.create(
WorkspaceFlavour.LOCAL,
async workspace => {
workspace.meta.initialize();
workspace.meta.setName(DEFAULT_WORKSPACE_NAME);
const page = workspace.createDoc();
defaultPageId = page.id;
initEmptyPage(page);
}
);
logger.info('create first workspace', workspaceMetadata);
return { meta: workspaceMetadata, defaultPageId };
}
const { meta, defaultDocId } = await buildShowcaseWorkspace(
workspacesService,
WorkspaceFlavour.LOCAL,
DEFAULT_WORKSPACE_NAME
);
logger.info('create first workspace', defaultDocId);
return { meta, defaultPageId: defaultDocId };
}

View File

@@ -29,14 +29,6 @@ export function getBuildConfig(buildFlags: BuildFlags): BUILD_CONFIG_TYPE {
downloadUrl: 'https://affine.pro/download',
imageProxyUrl: '/api/worker/image-proxy',
linkPreviewUrl: '/api/worker/link-preview',
enablePreloading: true,
enableExperimentalFeature: true,
allowLocalWorkspace:
buildFlags.distribution === 'desktop' ? true : false,
enableThemeEditor: false,
// CAUTION(@forehalo): product not ready, do not enable it
enableNewSettingUnstableApi: false,
};
},
get beta() {
@@ -62,7 +54,6 @@ export function getBuildConfig(buildFlags: BuildFlags): BUILD_CONFIG_TYPE {
appBuildType: 'canary' as const,
serverUrlPrefix: 'https://affine.fail',
changelogUrl: 'https://github.com/toeverything/AFFiNE/releases',
enableThemeEditor: true,
};
},
};
@@ -77,21 +68,6 @@ export function getBuildConfig(buildFlags: BuildFlags): BUILD_CONFIG_TYPE {
const environmentPreset = {
changelogUrl: process.env.CHANGELOG_URL ?? currentBuildPreset.changelogUrl,
enablePreloading: process.env.ENABLE_PRELOADING
? process.env.ENABLE_PRELOADING === 'true'
: currentBuildPreset.enablePreloading,
enableNewSettingUnstableApi: process.env.ENABLE_NEW_SETTING_UNSTABLE_API
? process.env.ENABLE_NEW_SETTING_UNSTABLE_API === 'true'
: currentBuildPreset.enableNewSettingUnstableApi,
allowLocalWorkspace: process.env.ALLOW_LOCAL_WORKSPACE
? process.env.ALLOW_LOCAL_WORKSPACE === 'true'
: buildFlags.mode === 'development'
? true
: currentBuildPreset.allowLocalWorkspace,
};
const testEnvironmentPreset = {
allowLocalWorkspace: true,
};
if (buildFlags.mode === 'development') {
@@ -104,9 +80,5 @@ export function getBuildConfig(buildFlags: BuildFlags): BUILD_CONFIG_TYPE {
// this environment variable is for debug proposes only
// do not put them into CI
...(process.env.CI ? {} : environmentPreset),
// test environment preset will overwrite current build preset
// this environment variable is for github workflow e2e-test only
...(process.env.IN_CI_TEST ? testEnvironmentPreset : {}),
};
}