mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-23 21:06:22 +08:00
feat(core): init feature flag service (#7856)
This commit is contained in:
-4
@@ -56,10 +56,6 @@ export const switchRow = style({
|
||||
justifyContent: 'space-between',
|
||||
width: '100%',
|
||||
});
|
||||
export const switchDisabled = style({
|
||||
opacity: 0.5,
|
||||
pointerEvents: 'none',
|
||||
});
|
||||
export const subHeader = style({
|
||||
fontWeight: '600',
|
||||
color: cssVar('textSecondaryColor'),
|
||||
|
||||
+34
-104
@@ -1,6 +1,5 @@
|
||||
import { Button, Checkbox, Loading, Switch, Tooltip } from '@affine/component';
|
||||
import { SettingHeader } from '@affine/component/setting-components';
|
||||
import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper';
|
||||
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import {
|
||||
@@ -10,9 +9,11 @@ import {
|
||||
GithubIcon,
|
||||
} from '@blocksuite/icons/rc';
|
||||
import {
|
||||
affineFeatureFlags,
|
||||
blocksuiteFeatureFlags,
|
||||
type FeedbackType,
|
||||
AFFINE_FLAGS,
|
||||
FeatureFlagService,
|
||||
type Flag,
|
||||
useLiveData,
|
||||
useServices,
|
||||
} from '@toeverything/infra';
|
||||
import { useAtom } from 'jotai';
|
||||
import { atomWithStorage } from 'jotai/utils';
|
||||
@@ -86,7 +87,7 @@ const ExperimentalFeaturesPrompt = ({
|
||||
);
|
||||
};
|
||||
|
||||
const FeedbackIcon = ({ type }: { type: FeedbackType }) => {
|
||||
const FeedbackIcon = ({ type }: { type: Flag['feedbackType'] }) => {
|
||||
switch (type) {
|
||||
case 'discord':
|
||||
return <DiscordIcon fontSize={16} />;
|
||||
@@ -99,55 +100,45 @@ const FeedbackIcon = ({ type }: { type: FeedbackType }) => {
|
||||
}
|
||||
};
|
||||
|
||||
const feedbackLink: Record<FeedbackType, string> = {
|
||||
const feedbackLink: Record<NonNullable<Flag['feedbackType']>, string> = {
|
||||
discord: 'https://discord.gg/whd5mjYqVw',
|
||||
email: 'mailto:support@toeverything.info',
|
||||
github: 'https://github.com/toeverything/AFFiNE/issues',
|
||||
};
|
||||
|
||||
const ExperimentalFeaturesItem = ({
|
||||
title,
|
||||
description,
|
||||
feedbackType,
|
||||
isMutating,
|
||||
checked,
|
||||
onChange,
|
||||
testId,
|
||||
}: {
|
||||
title: React.ReactNode;
|
||||
description?: React.ReactNode;
|
||||
feedbackType?: FeedbackType;
|
||||
isMutating?: boolean;
|
||||
checked: boolean;
|
||||
onChange: (checked: boolean) => void;
|
||||
testId?: string;
|
||||
}) => {
|
||||
const link = feedbackType ? feedbackLink[feedbackType] : undefined;
|
||||
const ExperimentalFeaturesItem = ({ flag }: { flag: Flag }) => {
|
||||
const value = useLiveData(flag.$);
|
||||
const onChange = useCallback(
|
||||
(checked: boolean) => {
|
||||
flag.set(checked);
|
||||
},
|
||||
[flag]
|
||||
);
|
||||
const link = flag.feedbackType ? feedbackLink[flag.feedbackType] : undefined;
|
||||
|
||||
if (flag.configurable === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.rowContainer}>
|
||||
<div className={styles.switchRow}>
|
||||
{title}
|
||||
<Switch
|
||||
checked={checked}
|
||||
onChange={onChange}
|
||||
className={isMutating ? styles.switchDisabled : ''}
|
||||
data-testid={testId}
|
||||
/>
|
||||
{flag.displayName}
|
||||
<Switch checked={value} onChange={onChange} />
|
||||
</div>
|
||||
{!!description && (
|
||||
<Tooltip content={description}>
|
||||
<div className={styles.description}>{description}</div>
|
||||
{!!flag.description && (
|
||||
<Tooltip content={flag.description}>
|
||||
<div className={styles.description}>{flag.description}</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
{!!feedbackType && (
|
||||
{!!flag.feedbackType && (
|
||||
<a
|
||||
className={styles.feedback}
|
||||
href={link}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<FeedbackIcon type={feedbackType} />
|
||||
<FeedbackIcon type={flag.feedbackType} />
|
||||
<span>Discussion about this feature</span>
|
||||
<ArrowRightSmallIcon
|
||||
fontSize={20}
|
||||
@@ -159,74 +150,9 @@ const ExperimentalFeaturesItem = ({
|
||||
);
|
||||
};
|
||||
|
||||
const SplitViewSettingRow = () => {
|
||||
const { appSettings, updateSettings } = useAppSettingHelper();
|
||||
|
||||
const onToggle = useCallback(
|
||||
(checked: boolean) => {
|
||||
updateSettings('enableMultiView', checked);
|
||||
},
|
||||
[updateSettings]
|
||||
);
|
||||
const multiViewFlagConfig = affineFeatureFlags['enableMultiView'];
|
||||
const shouldShow = multiViewFlagConfig?.precondition?.();
|
||||
|
||||
if (!multiViewFlagConfig || !shouldShow) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ExperimentalFeaturesItem
|
||||
title={multiViewFlagConfig.displayName}
|
||||
description={multiViewFlagConfig.description}
|
||||
feedbackType={multiViewFlagConfig.feedbackType}
|
||||
checked={appSettings.enableMultiView}
|
||||
onChange={onToggle}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const BlocksuiteFeatureFlagSettings = () => {
|
||||
const { appSettings, updateSettings } = useAppSettingHelper();
|
||||
const toggleSetting = useCallback(
|
||||
(flag: keyof BlockSuiteFlags, checked: boolean) => {
|
||||
updateSettings('editorFlags', {
|
||||
...appSettings.editorFlags,
|
||||
[flag]: checked,
|
||||
});
|
||||
},
|
||||
[appSettings.editorFlags, updateSettings]
|
||||
);
|
||||
|
||||
type EditorFlag = keyof typeof appSettings.editorFlags;
|
||||
|
||||
return (
|
||||
<>
|
||||
{Object.entries(blocksuiteFeatureFlags).map(([key, value]) => {
|
||||
const hidden = value.precondition && !value.precondition();
|
||||
|
||||
if (hidden) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<ExperimentalFeaturesItem
|
||||
key={key}
|
||||
title={'Block Suite: ' + value.displayName}
|
||||
description={value.description}
|
||||
feedbackType={value.feedbackType}
|
||||
checked={!!appSettings.editorFlags?.[key as EditorFlag]}
|
||||
onChange={checked =>
|
||||
toggleSetting(key as keyof BlockSuiteFlags, checked)
|
||||
}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const ExperimentalFeaturesMain = () => {
|
||||
const t = useI18n();
|
||||
const { featureFlagService } = useServices({ FeatureFlagService });
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -242,8 +168,12 @@ const ExperimentalFeaturesMain = () => {
|
||||
className={styles.settingsContainer}
|
||||
data-testid="experimental-settings"
|
||||
>
|
||||
<SplitViewSettingRow />
|
||||
<BlocksuiteFeatureFlagSettings />
|
||||
{Object.keys(AFFINE_FLAGS).map(key => (
|
||||
<ExperimentalFeaturesItem
|
||||
key={key}
|
||||
flag={featureFlagService.flags[key as keyof AFFINE_FLAGS]}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
toast,
|
||||
useConfirmModal,
|
||||
} from '@affine/component';
|
||||
import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper';
|
||||
import { useBlockSuiteMetaHelper } from '@affine/core/hooks/affine/use-block-suite-meta-helper';
|
||||
import { useTrashModalHelper } from '@affine/core/hooks/affine/use-trash-modal-helper';
|
||||
import { useCatchEventCallback } from '@affine/core/hooks/use-catch-event-hook';
|
||||
@@ -34,6 +33,7 @@ import {
|
||||
} from '@blocksuite/icons/rc';
|
||||
import type { DocMeta } from '@blocksuite/store';
|
||||
import {
|
||||
FeatureFlagService,
|
||||
useLiveData,
|
||||
useService,
|
||||
useServices,
|
||||
@@ -67,13 +67,25 @@ export const PageOperationCell = ({
|
||||
onRemoveFromAllowList,
|
||||
}: PageOperationCellProps) => {
|
||||
const t = useI18n();
|
||||
const currentWorkspace = useService(WorkspaceService).workspace;
|
||||
const { appSettings } = useAppSettingHelper();
|
||||
const {
|
||||
featureFlagService,
|
||||
workspaceService,
|
||||
compatibleFavoriteItemsAdapter: favAdapter,
|
||||
workbenchService,
|
||||
} = useServices({
|
||||
FeatureFlagService,
|
||||
WorkspaceService,
|
||||
CompatibleFavoriteItemsAdapter,
|
||||
WorkbenchService,
|
||||
});
|
||||
const enableSplitView = useLiveData(
|
||||
featureFlagService.flags.enable_multi_view.$
|
||||
);
|
||||
const currentWorkspace = workspaceService.workspace;
|
||||
const { setTrashModal } = useTrashModalHelper(currentWorkspace.docCollection);
|
||||
const [openDisableShared, setOpenDisableShared] = useState(false);
|
||||
const favAdapter = useService(CompatibleFavoriteItemsAdapter);
|
||||
const favourite = useLiveData(favAdapter.isFavorite$(page.id, 'doc'));
|
||||
const workbench = useService(WorkbenchService).workbench;
|
||||
const workbench = workbenchService.workbench;
|
||||
const { duplicate } = useBlockSuiteMetaHelper(currentWorkspace.docCollection);
|
||||
const blocksuiteDoc = currentWorkspace.docCollection.getDoc(page.id);
|
||||
|
||||
@@ -201,7 +213,7 @@ export const PageOperationCell = ({
|
||||
{t['com.affine.workbench.tab.page-menu-open']()}
|
||||
</MenuItem>
|
||||
|
||||
{environment.isDesktop && appSettings.enableMultiView ? (
|
||||
{environment.isDesktop && enableSplitView ? (
|
||||
<MenuItem
|
||||
onClick={onOpenInSplitView}
|
||||
preFix={
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { MenuItemProps } from '@affine/component';
|
||||
import { Menu, MenuIcon, MenuItem } from '@affine/component';
|
||||
import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper';
|
||||
import { useDeleteCollectionInfo } from '@affine/core/hooks/affine/use-delete-collection-info';
|
||||
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/properties';
|
||||
import { WorkbenchService } from '@affine/core/modules/workbench';
|
||||
@@ -16,7 +15,12 @@ import {
|
||||
PlusIcon,
|
||||
SplitViewIcon,
|
||||
} from '@blocksuite/icons/rc';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
import {
|
||||
FeatureFlagService,
|
||||
useLiveData,
|
||||
useService,
|
||||
useServices,
|
||||
} from '@toeverything/infra';
|
||||
import type { PropsWithChildren, ReactElement } from 'react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
@@ -37,10 +41,17 @@ export const CollectionOperations = ({
|
||||
openRenameModal?: () => void;
|
||||
onAddDocToCollection?: () => void;
|
||||
}>) => {
|
||||
const {
|
||||
collectionService: service,
|
||||
workbenchService,
|
||||
featureFlagService,
|
||||
} = useServices({
|
||||
CollectionService,
|
||||
WorkbenchService,
|
||||
FeatureFlagService,
|
||||
});
|
||||
const deleteInfo = useDeleteCollectionInfo();
|
||||
const { appSettings } = useAppSettingHelper();
|
||||
const service = useService(CollectionService);
|
||||
const workbench = useService(WorkbenchService).workbench;
|
||||
const workbench = workbenchService.workbench;
|
||||
const { open: openEditCollectionModal, node: editModal } =
|
||||
useEditCollection();
|
||||
const t = useI18n();
|
||||
@@ -48,6 +59,9 @@ export const CollectionOperations = ({
|
||||
useEditCollectionName({
|
||||
title: t['com.affine.editCollection.renameCollection'](),
|
||||
});
|
||||
const enableMultiView = useLiveData(
|
||||
featureFlagService.flags.enable_multi_view.$
|
||||
);
|
||||
|
||||
const showEditName = useCallback(() => {
|
||||
// use openRenameModal if it is in the sidebar collection list
|
||||
@@ -167,7 +181,7 @@ export const CollectionOperations = ({
|
||||
name: t['com.affine.workbench.tab.page-menu-open'](),
|
||||
click: openCollectionNewTab,
|
||||
},
|
||||
...(appSettings.enableMultiView
|
||||
...(enableMultiView && environment.isDesktop
|
||||
? [
|
||||
{
|
||||
icon: (
|
||||
@@ -197,6 +211,7 @@ export const CollectionOperations = ({
|
||||
},
|
||||
],
|
||||
[
|
||||
enableMultiView,
|
||||
t,
|
||||
showEditName,
|
||||
showEdit,
|
||||
@@ -204,7 +219,6 @@ export const CollectionOperations = ({
|
||||
favorite,
|
||||
onToggleFavoritePage,
|
||||
openCollectionNewTab,
|
||||
appSettings.enableMultiView,
|
||||
openCollectionSplitView,
|
||||
service,
|
||||
deleteInfo,
|
||||
|
||||
@@ -5,7 +5,6 @@ import {
|
||||
MenuSeparator,
|
||||
useConfirmModal,
|
||||
} from '@affine/component';
|
||||
import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper';
|
||||
import { useDeleteCollectionInfo } from '@affine/core/hooks/affine/use-delete-collection-info';
|
||||
import { track } from '@affine/core/mixpanel';
|
||||
import { CollectionService } from '@affine/core/modules/collection';
|
||||
@@ -21,7 +20,12 @@ import {
|
||||
PlusIcon,
|
||||
SplitViewIcon,
|
||||
} from '@blocksuite/icons/rc';
|
||||
import { DocsService, useLiveData, useServices } from '@toeverything/infra';
|
||||
import {
|
||||
DocsService,
|
||||
FeatureFlagService,
|
||||
useLiveData,
|
||||
useServices,
|
||||
} from '@toeverything/infra';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
import type { NodeOperation } from '../../tree/types';
|
||||
@@ -32,20 +36,24 @@ export const useExplorerCollectionNodeOperations = (
|
||||
onOpenEdit: () => void
|
||||
): NodeOperation[] => {
|
||||
const t = useI18n();
|
||||
const { appSettings } = useAppSettingHelper();
|
||||
const {
|
||||
workbenchService,
|
||||
docsService,
|
||||
collectionService,
|
||||
compatibleFavoriteItemsAdapter,
|
||||
featureFlagService,
|
||||
} = useServices({
|
||||
DocsService,
|
||||
WorkbenchService,
|
||||
CollectionService,
|
||||
CompatibleFavoriteItemsAdapter,
|
||||
FeatureFlagService,
|
||||
});
|
||||
const deleteInfo = useDeleteCollectionInfo();
|
||||
|
||||
const enableMultiView = useLiveData(
|
||||
featureFlagService.flags.enable_multi_view.$
|
||||
);
|
||||
const favorite = useLiveData(
|
||||
useMemo(
|
||||
() =>
|
||||
@@ -200,7 +208,7 @@ export const useExplorerCollectionNodeOperations = (
|
||||
</MenuItem>
|
||||
),
|
||||
},
|
||||
...(appSettings.enableMultiView
|
||||
...(environment.isDesktop && enableMultiView
|
||||
? [
|
||||
{
|
||||
index: 99,
|
||||
@@ -241,7 +249,7 @@ export const useExplorerCollectionNodeOperations = (
|
||||
},
|
||||
],
|
||||
[
|
||||
appSettings.enableMultiView,
|
||||
enableMultiView,
|
||||
favorite,
|
||||
handleAddDocToCollection,
|
||||
handleDeleteCollection,
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
toast,
|
||||
useConfirmModal,
|
||||
} from '@affine/component';
|
||||
import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper';
|
||||
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
|
||||
import { track } from '@affine/core/mixpanel';
|
||||
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/properties';
|
||||
@@ -22,7 +21,12 @@ import {
|
||||
PlusIcon,
|
||||
SplitViewIcon,
|
||||
} from '@blocksuite/icons/rc';
|
||||
import { DocsService, useLiveData, useServices } from '@toeverything/infra';
|
||||
import {
|
||||
DocsService,
|
||||
FeatureFlagService,
|
||||
useLiveData,
|
||||
useServices,
|
||||
} from '@toeverything/infra';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
import type { NodeOperation } from '../../tree/types';
|
||||
@@ -35,13 +39,20 @@ export const useExplorerDocNodeOperations = (
|
||||
}
|
||||
): NodeOperation[] => {
|
||||
const t = useI18n();
|
||||
const { appSettings } = useAppSettingHelper();
|
||||
const { workbenchService, docsService, compatibleFavoriteItemsAdapter } =
|
||||
useServices({
|
||||
DocsService,
|
||||
WorkbenchService,
|
||||
CompatibleFavoriteItemsAdapter,
|
||||
});
|
||||
const {
|
||||
workbenchService,
|
||||
docsService,
|
||||
compatibleFavoriteItemsAdapter,
|
||||
featureFlagService,
|
||||
} = useServices({
|
||||
DocsService,
|
||||
WorkbenchService,
|
||||
CompatibleFavoriteItemsAdapter,
|
||||
FeatureFlagService,
|
||||
});
|
||||
const enableMultiView = useLiveData(
|
||||
featureFlagService.flags.enable_multi_view.$
|
||||
);
|
||||
const { openConfirmModal } = useConfirmModal();
|
||||
|
||||
const docRecord = useLiveData(docsService.list.doc$(docId));
|
||||
@@ -179,7 +190,7 @@ export const useExplorerDocNodeOperations = (
|
||||
</MenuItem>
|
||||
),
|
||||
},
|
||||
...(appSettings.enableMultiView
|
||||
...(enableMultiView && environment.isDesktop
|
||||
? [
|
||||
{
|
||||
index: 100,
|
||||
@@ -243,7 +254,7 @@ export const useExplorerDocNodeOperations = (
|
||||
},
|
||||
],
|
||||
[
|
||||
appSettings.enableMultiView,
|
||||
enableMultiView,
|
||||
favorite,
|
||||
handleAddLinkedPage,
|
||||
handleMoveToTrash,
|
||||
|
||||
@@ -5,7 +5,6 @@ import {
|
||||
MenuSeparator,
|
||||
toast,
|
||||
} from '@affine/component';
|
||||
import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper';
|
||||
import { track } from '@affine/core/mixpanel';
|
||||
import { FavoriteService } from '@affine/core/modules/favorite';
|
||||
import { TagService } from '@affine/core/modules/tag';
|
||||
@@ -19,7 +18,12 @@ import {
|
||||
PlusIcon,
|
||||
SplitViewIcon,
|
||||
} from '@blocksuite/icons/rc';
|
||||
import { DocsService, useLiveData, useServices } from '@toeverything/infra';
|
||||
import {
|
||||
DocsService,
|
||||
FeatureFlagService,
|
||||
useLiveData,
|
||||
useServices,
|
||||
} from '@toeverything/infra';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
import type { NodeOperation } from '../../tree/types';
|
||||
@@ -33,19 +37,27 @@ export const useExplorerTagNodeOperations = (
|
||||
}
|
||||
): NodeOperation[] => {
|
||||
const t = useI18n();
|
||||
const { appSettings } = useAppSettingHelper();
|
||||
const { docsService, workbenchService, tagService, favoriteService } =
|
||||
useServices({
|
||||
WorkbenchService,
|
||||
TagService,
|
||||
DocsService,
|
||||
FavoriteService,
|
||||
});
|
||||
const {
|
||||
docsService,
|
||||
workbenchService,
|
||||
tagService,
|
||||
favoriteService,
|
||||
featureFlagService,
|
||||
} = useServices({
|
||||
WorkbenchService,
|
||||
TagService,
|
||||
DocsService,
|
||||
FavoriteService,
|
||||
FeatureFlagService,
|
||||
});
|
||||
|
||||
const favorite = useLiveData(
|
||||
favoriteService.favoriteList.favorite$('tag', tagId)
|
||||
);
|
||||
const tagRecord = useLiveData(tagService.tagList.tagByTagId$(tagId));
|
||||
const enableMultiView = useLiveData(
|
||||
featureFlagService.flags.enable_multi_view.$
|
||||
);
|
||||
|
||||
const handleNewDoc = useCallback(() => {
|
||||
if (tagRecord) {
|
||||
@@ -114,7 +126,7 @@ export const useExplorerTagNodeOperations = (
|
||||
</MenuItem>
|
||||
),
|
||||
},
|
||||
...(appSettings.enableMultiView
|
||||
...(enableMultiView && environment.isDesktop
|
||||
? [
|
||||
{
|
||||
index: 100,
|
||||
@@ -178,7 +190,7 @@ export const useExplorerTagNodeOperations = (
|
||||
},
|
||||
],
|
||||
[
|
||||
appSettings.enableMultiView,
|
||||
enableMultiView,
|
||||
favorite,
|
||||
handleMoveToTrash,
|
||||
handleNewDoc,
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper';
|
||||
import { useCatchEventCallback } from '@affine/core/hooks/use-catch-event-hook';
|
||||
import { isNewTabTrigger } from '@affine/core/utils';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
import {
|
||||
FeatureFlagService,
|
||||
useLiveData,
|
||||
useServices,
|
||||
} from '@toeverything/infra';
|
||||
import { type To } from 'history';
|
||||
import { forwardRef, type MouseEvent } from 'react';
|
||||
|
||||
@@ -16,8 +19,14 @@ export const WorkbenchLink = forwardRef<
|
||||
} & React.HTMLProps<HTMLAnchorElement>
|
||||
>
|
||||
>(function WorkbenchLink({ to, onClick, ...other }, ref) {
|
||||
const workbench = useService(WorkbenchService).workbench;
|
||||
const { appSettings } = useAppSettingHelper();
|
||||
const { featureFlagService, workbenchService } = useServices({
|
||||
FeatureFlagService,
|
||||
WorkbenchService,
|
||||
});
|
||||
const enableMultiView = useLiveData(
|
||||
featureFlagService.flags.enable_multi_view.$
|
||||
);
|
||||
const workbench = workbenchService.workbench;
|
||||
const basename = useLiveData(workbench.basename$);
|
||||
const link =
|
||||
basename +
|
||||
@@ -30,7 +39,7 @@ export const WorkbenchLink = forwardRef<
|
||||
}
|
||||
const at = (() => {
|
||||
if (isNewTabTrigger(event)) {
|
||||
return event.altKey && appSettings.enableMultiView
|
||||
return event.altKey && enableMultiView && environment.isDesktop
|
||||
? 'tail'
|
||||
: 'new-tab';
|
||||
}
|
||||
@@ -39,7 +48,7 @@ export const WorkbenchLink = forwardRef<
|
||||
workbench.open(to, { at });
|
||||
event.preventDefault();
|
||||
},
|
||||
[appSettings.enableMultiView, onClick, to, workbench]
|
||||
[enableMultiView, onClick, to, workbench]
|
||||
);
|
||||
|
||||
// eslint suspicious runtime error
|
||||
|
||||
Reference in New Issue
Block a user