mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-22 20:46:38 +08:00
feat(core): open in app for self-hosted (#9231)
<div class='graphite__hidden'>
<div>🎥 Video uploaded on Graphite:</div>
<a href="https://app.graphite.dev/media/video/T2klNLEk0wxLh4NRDzhk/545994dd-6f7d-468d-a90c-45cb382fdb9d.mp4">
<img src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/T2klNLEk0wxLh4NRDzhk/545994dd-6f7d-468d-a90c-45cb382fdb9d.mp4">
</a>
</div>
<video src="https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/T2klNLEk0wxLh4NRDzhk/545994dd-6f7d-468d-a90c-45cb382fdb9d.mp4">20241222-1456-24.5006677.mp4</video>
fix AF-1815
This commit is contained in:
@@ -1,14 +1,24 @@
|
||||
import { Modal } from '@affine/component';
|
||||
import { SignInPanel, type SignInStep } from '@affine/core/components/sign-in';
|
||||
import type { AuthSessionStatus } from '@affine/core/modules/cloud/entities/session';
|
||||
import type {
|
||||
DialogComponentProps,
|
||||
GLOBAL_DIALOG_SCHEMA,
|
||||
} from '@affine/core/modules/dialogs';
|
||||
import { useCallback } from 'react';
|
||||
export const SignInDialog = ({
|
||||
close,
|
||||
server: initialServerBaseUrl,
|
||||
step,
|
||||
}: DialogComponentProps<GLOBAL_DIALOG_SCHEMA['sign-in']>) => {
|
||||
const onAuthenticated = useCallback(
|
||||
(status: AuthSessionStatus) => {
|
||||
if (status === 'authenticated') {
|
||||
close();
|
||||
}
|
||||
},
|
||||
[close]
|
||||
);
|
||||
return (
|
||||
<Modal
|
||||
open
|
||||
@@ -21,7 +31,8 @@ export const SignInDialog = ({
|
||||
}}
|
||||
>
|
||||
<SignInPanel
|
||||
onClose={close}
|
||||
onSkip={close}
|
||||
onAuthenticated={onAuthenticated}
|
||||
server={initialServerBaseUrl}
|
||||
initStep={step as SignInStep}
|
||||
/>
|
||||
|
||||
@@ -2,11 +2,9 @@ import { notify } from '@affine/component';
|
||||
import { AffineOtherPageLayout } from '@affine/component/affine-other-page-layout';
|
||||
import { SignInPageContainer } from '@affine/component/auth-components';
|
||||
import { SignInPanel } from '@affine/core/components/sign-in';
|
||||
import { AuthService } from '@affine/core/modules/cloud';
|
||||
import type { AuthSessionStatus } from '@affine/core/modules/cloud/entities/session';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { useService } from '@toeverything/infra';
|
||||
import { useEffect } from 'react';
|
||||
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { useNavigate, useSearchParams } from 'react-router-dom';
|
||||
|
||||
import {
|
||||
@@ -20,11 +18,12 @@ export const SignIn = ({
|
||||
redirectUrl?: string;
|
||||
}) => {
|
||||
const t = useI18n();
|
||||
const session = useService(AuthService).session;
|
||||
const navigate = useNavigate();
|
||||
const { jumpToIndex } = useNavigateHelper();
|
||||
const [searchParams] = useSearchParams();
|
||||
const redirectUrl = redirectUrlFromProps ?? searchParams.get('redirect_uri');
|
||||
|
||||
const server = searchParams.get('server') ?? undefined;
|
||||
const error = searchParams.get('error');
|
||||
|
||||
useEffect(() => {
|
||||
@@ -36,22 +35,38 @@ export const SignIn = ({
|
||||
}
|
||||
}, [error, t]);
|
||||
|
||||
const handleClose = () => {
|
||||
if (session.status$.value === 'authenticated' && redirectUrl) {
|
||||
navigate(redirectUrl, {
|
||||
replace: true,
|
||||
});
|
||||
} else {
|
||||
jumpToIndex(RouteLogic.REPLACE, {
|
||||
search: searchParams.toString(),
|
||||
});
|
||||
}
|
||||
};
|
||||
const handleClose = useCallback(() => {
|
||||
jumpToIndex(RouteLogic.REPLACE, {
|
||||
search: searchParams.toString(),
|
||||
});
|
||||
}, [jumpToIndex, searchParams]);
|
||||
|
||||
const handleAuthenticated = useCallback(
|
||||
(status: AuthSessionStatus) => {
|
||||
if (status === 'authenticated') {
|
||||
if (redirectUrl) {
|
||||
navigate(redirectUrl, {
|
||||
replace: true,
|
||||
});
|
||||
} else {
|
||||
handleClose();
|
||||
}
|
||||
}
|
||||
},
|
||||
[handleClose, navigate, redirectUrl]
|
||||
);
|
||||
|
||||
const initStep = server ? 'addSelfhosted' : 'signIn';
|
||||
|
||||
return (
|
||||
<SignInPageContainer>
|
||||
<div style={{ maxWidth: '400px', width: '100%' }}>
|
||||
<SignInPanel onClose={handleClose} />
|
||||
<SignInPanel
|
||||
onSkip={handleClose}
|
||||
onAuthenticated={handleAuthenticated}
|
||||
initStep={initStep}
|
||||
server={server}
|
||||
/>
|
||||
</div>
|
||||
</SignInPageContainer>
|
||||
);
|
||||
|
||||
@@ -3,6 +3,7 @@ import { AffineOtherPageLayout } from '@affine/component/affine-other-page-layou
|
||||
import { workbenchRoutes } from '@affine/core/desktop/workbench-router';
|
||||
import {
|
||||
DefaultServerService,
|
||||
ServersService,
|
||||
WorkspaceServerService,
|
||||
} from '@affine/core/modules/cloud';
|
||||
import { DndService } from '@affine/core/modules/dnd/services';
|
||||
@@ -21,12 +22,18 @@ import {
|
||||
} from '@toeverything/infra';
|
||||
import type { PropsWithChildren, ReactElement } from 'react';
|
||||
import { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
||||
import { matchPath, useLocation, useParams } from 'react-router-dom';
|
||||
import {
|
||||
matchPath,
|
||||
useLocation,
|
||||
useParams,
|
||||
useSearchParams,
|
||||
} from 'react-router-dom';
|
||||
|
||||
import { AffineErrorBoundary } from '../../../components/affine/affine-error-boundary';
|
||||
import { WorkbenchRoot } from '../../../modules/workbench';
|
||||
import { AppContainer } from '../../components/app-container';
|
||||
import { PageNotFound } from '../404';
|
||||
import { SignIn } from '../auth/sign-in';
|
||||
import { WorkspaceLayout } from './layouts/workspace-layout';
|
||||
import { SharePage } from './share/share-page';
|
||||
|
||||
@@ -52,6 +59,7 @@ export const Component = (): ReactElement => {
|
||||
|
||||
const params = useParams();
|
||||
const location = useLocation();
|
||||
const [searchParams] = useSearchParams();
|
||||
|
||||
// check if we are in detail doc route, if so, maybe render share page
|
||||
const detailDocRoute = useMemo(() => {
|
||||
@@ -80,6 +88,11 @@ export const Component = (): ReactElement => {
|
||||
const [workspaceNotFound, setWorkspaceNotFound] = useState(false);
|
||||
const listLoading = useLiveData(workspacesService.list.isRevalidating$);
|
||||
const workspaces = useLiveData(workspacesService.list.workspaces$);
|
||||
const serversService = useService(ServersService);
|
||||
const serverFromSearchParams = searchParams.get('server');
|
||||
const serverNotFound = serverFromSearchParams
|
||||
? serversService.getServerByBaseUrl(serverFromSearchParams)
|
||||
: null;
|
||||
const meta = useMemo(() => {
|
||||
return workspaces.find(({ id }) => id === params.workspaceId);
|
||||
}, [workspaces, params.workspaceId]);
|
||||
@@ -113,6 +126,16 @@ export const Component = (): ReactElement => {
|
||||
}, [listLoading, meta, workspaceNotFound, workspacesService]);
|
||||
|
||||
if (workspaceNotFound) {
|
||||
if (BUILD_CONFIG.isElectron && serverNotFound) {
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.delete('server');
|
||||
const redirectUrl = url.toString().replace(window.location.origin, '');
|
||||
return (
|
||||
<AffineOtherPageLayout>
|
||||
<SignIn redirectUrl={redirectUrl} />
|
||||
</AffineOtherPageLayout>
|
||||
);
|
||||
}
|
||||
if (detailDocRoute) {
|
||||
return (
|
||||
<SharePage
|
||||
|
||||
Reference in New Issue
Block a user