feat(core): open app in electron app entry (#8637)

fix PD-208
fix PD-210
fix PD-209
fix AF-1495
This commit is contained in:
pengx17
2024-10-31 06:16:32 +00:00
parent 5d92c900d1
commit 0f8b273134
36 changed files with 887 additions and 226 deletions

View File

@@ -5,11 +5,8 @@ import {
SettingWrapper,
} from '@affine/component/setting-components';
import { useAppUpdater } from '@affine/core/components/hooks/use-app-updater';
import {
appIconMap,
appNames,
} from '@affine/core/modules/open-in-app/constant';
import { UrlService } from '@affine/core/modules/url';
import { appIconMap, appNames } from '@affine/core/utils';
import { useI18n } from '@affine/i18n';
import { mixpanel } from '@affine/track';
import { ArrowRightSmallIcon, OpenInNewIcon } from '@blocksuite/icons/rc';

View File

@@ -16,6 +16,7 @@ import { useCallback, useMemo } from 'react';
import { useAppSettingHelper } from '../../../../../components/hooks/affine/use-app-setting-helper';
import { LanguageMenu } from '../../../language-menu';
import { OpenInAppLinksMenu } from './links';
import { settingWrapper } from './style.css';
import { ThemeEditorSetting } from './theme-editor-setting';
@@ -106,6 +107,17 @@ export const AppearanceSettings = () => {
{enableThemeEditor ? <ThemeEditorSetting /> : null}
</SettingWrapper>
{BUILD_CONFIG.isWeb ? (
<SettingWrapper title={t['com.affine.setting.appearance.links']()}>
<SettingRow
name={t['com.affine.setting.appearance.open-in-app']()}
desc={t['com.affine.setting.appearance.open-in-app.hint']()}
data-testid="open-in-app-links-trigger"
>
<OpenInAppLinksMenu />
</SettingRow>
</SettingWrapper>
) : null}
{BUILD_CONFIG.isElectron ? (
<SettingWrapper
title={t['com.affine.appearanceSettings.sidebar.title']()}

View File

@@ -0,0 +1,18 @@
import { cssVar } from '@toeverything/theme';
import { style } from '@vanilla-extract/css';
export const menu = style({
background: cssVar('white'),
width: '250px',
maxHeight: '30vh',
overflowY: 'auto',
});
export const menuItem = style({
color: cssVar('textPrimaryColor'),
selectors: {
'&[data-selected=true]': {
color: cssVar('primaryColor'),
},
},
});

View File

@@ -0,0 +1,55 @@
import { Menu, MenuItem, MenuTrigger } from '@affine/component';
import {
OpenInAppService,
OpenLinkMode,
} from '@affine/core/modules/open-in-app';
import { useI18n } from '@affine/i18n';
import { useLiveData, useService } from '@toeverything/infra';
import { useMemo } from 'react';
import * as styles from './links.css';
export const OpenInAppLinksMenu = () => {
const t = useI18n();
const openInAppService = useService(OpenInAppService);
const currentOpenInAppMode = useLiveData(openInAppService.openLinkMode$);
const options = useMemo(
() =>
Object.values(OpenLinkMode).map(mode => ({
label:
t.t(`com.affine.setting.appearance.open-in-app.${mode}`) ||
`com.affine.setting.appearance.open-in-app.${mode}`,
value: mode,
})),
[t]
);
return (
<Menu
items={options.map(option => {
return (
<MenuItem
key={option.value}
title={option.label}
onSelect={() => openInAppService.setOpenLinkMode(option.value)}
data-selected={currentOpenInAppMode === option.value}
>
{option.label}
</MenuItem>
);
})}
contentOptions={{
className: styles.menu,
align: 'end',
}}
>
<MenuTrigger
style={{ textTransform: 'capitalize', fontWeight: 600, width: '250px' }}
block={true}
>
{options.find(option => option.value === currentOpenInAppMode)?.label}
</MenuTrigger>
</Menu>
);
};

View File

@@ -18,14 +18,14 @@ const UpgradeSuccessLayout = ({
const t = useI18n();
const [params] = useSearchParams();
const { jumpToIndex, openInApp } = useNavigateHelper();
const { jumpToIndex, jumpToOpenInApp } = useNavigateHelper();
const openAffine = useCallback(() => {
if (params.get('scheme')) {
openInApp(params.get('scheme') ?? 'affine', 'bring-to-front');
jumpToOpenInApp('bring-to-front');
} else {
jumpToIndex();
}
}, [jumpToIndex, openInApp, params]);
}, [jumpToIndex, jumpToOpenInApp, params]);
const subtitle = (
<div className={styles.leftContentText}>

View File

@@ -25,7 +25,7 @@ import { IsFavoriteIcon } from '@affine/core/components/pure/icons';
import { useDetailPageHeaderResponsive } from '@affine/core/desktop/pages/workspace/detail-page/use-header-responsive';
import { DocInfoService } from '@affine/core/modules/doc-info';
import { EditorService } from '@affine/core/modules/editor';
import { getOpenUrlInDesktopAppLink } from '@affine/core/modules/open-in-app/utils';
import { OpenInAppService } from '@affine/core/modules/open-in-app/services';
import { WorkbenchService } from '@affine/core/modules/workbench';
import { ViewService } from '@affine/core/modules/workbench/services/view';
import { WorkspaceFlavour } from '@affine/env/workspace';
@@ -52,6 +52,7 @@ import {
FeatureFlagService,
useLiveData,
useService,
useServiceOptional,
WorkspaceService,
} from '@toeverything/infra';
import { useSetAtom } from 'jotai';
@@ -92,6 +93,7 @@ export const PageHeaderMenuButton = ({
const enableSnapshotImportExport = useLiveData(
featureFlagService.flags.enable_snapshot_import_export.$
);
const openInAppService = useServiceOptional(OpenInAppService);
const { favorite, toggleFavorite } = useFavorite(pageId);
@@ -265,11 +267,8 @@ export const PageHeaderMenuButton = ({
);
const onOpenInDesktop = useCallback(() => {
const url = getOpenUrlInDesktopAppLink(window.location.href, true);
if (url) {
window.open(url, '_blank');
}
}, []);
openInAppService?.showOpenInAppPage();
}, [openInAppService]);
const EditMenu = (
<>
@@ -376,7 +375,8 @@ export const PageHeaderMenuButton = ({
data-testid="editor-option-menu-delete"
onSelect={handleOpenTrashModal}
/>
{BUILD_CONFIG.isWeb ? (
{BUILD_CONFIG.isWeb &&
workspace.flavour === WorkspaceFlavour.AFFINE_CLOUD ? (
<MenuItem
prefixIcon={<LocalWorkspaceIcon />}
data-testid="editor-option-menu-link"

View File

@@ -1,4 +1,5 @@
import { toURLSearchParams } from '@affine/core/modules/navigation';
import { getOpenUrlInDesktopAppLink } from '@affine/core/modules/open-in-app';
import type { DocMode } from '@blocksuite/affine/blocks';
import { createContext, useCallback, useContext, useMemo } from 'react';
import type { NavigateFunction, NavigateOptions } from 'react-router-dom';
@@ -159,10 +160,16 @@ export function useNavigateHelper() {
[navigate]
);
const openInApp = useCallback(
(scheme: string, path: string) => {
const encodedUrl = encodeURIComponent(`${scheme}://${path}`);
return navigate(`/open-app/url?scheme=${scheme}&url=${encodedUrl}`);
const jumpToOpenInApp = useCallback(
(url: string, newTab = true) => {
const deeplink = getOpenUrlInDesktopAppLink(url, newTab);
if (!deeplink) {
return;
}
const encodedUrl = encodeURIComponent(deeplink);
return navigate(`/open-app/url?url=${encodedUrl}`);
},
[navigate]
);
@@ -189,7 +196,7 @@ export function useNavigateHelper() {
jumpToCollections,
jumpToTags,
jumpToTag,
openInApp,
jumpToOpenInApp,
jumpToImportTemplate,
}),
[
@@ -204,7 +211,7 @@ export function useNavigateHelper() {
jumpToCollections,
jumpToTags,
jumpToTag,
openInApp,
jumpToOpenInApp,
jumpToImportTemplate,
]
);

View File

@@ -5,11 +5,11 @@ import {
import { useAsyncCallback } from '@affine/core/components/hooks/affine-async-hooks';
import {
AddPageButton,
AppDownloadButton,
AppSidebar,
CategoryDivider,
MenuItem,
MenuLinkItem,
OpenInAppCard,
QuickSearchInput,
SidebarContainer,
SidebarScrollableContainer,
@@ -190,7 +190,7 @@ export const RootAppSidebar = (): ReactElement => {
</div>
</SidebarScrollableContainer>
<SidebarContainer>
{BUILD_CONFIG.isElectron ? <UpdaterButton /> : <AppDownloadButton />}
{BUILD_CONFIG.isElectron ? <UpdaterButton /> : <OpenInAppCard />}
</SidebarContainer>
</AppSidebar>
);