mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 12:28:42 +00:00
fix(core): improve client-app navigation flow after team workspace upgrade (#11201)
This commit is contained in:
@@ -47,7 +47,8 @@ export const generateSubscriptionCallbackLink = (
|
||||
account: AuthAccountInfo | null,
|
||||
plan: SubscriptionPlan,
|
||||
recurring: SubscriptionRecurring,
|
||||
workspaceId?: string
|
||||
workspaceId?: string,
|
||||
clientScheme?: string
|
||||
) => {
|
||||
const baseUrl =
|
||||
plan === SubscriptionPlan.AI
|
||||
@@ -79,7 +80,7 @@ export const generateSubscriptionCallbackLink = (
|
||||
workspaceId ?? '',
|
||||
].join(separator);
|
||||
|
||||
return `${baseUrl}?info=${encodeURIComponent(query)}`;
|
||||
return `${baseUrl}?info=${encodeURIComponent(query)}${clientScheme ? `&client=${clientScheme}` : ''}`;
|
||||
};
|
||||
|
||||
export const getSubscriptionInfo = (searchParams: URLSearchParams) => {
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
SubscriptionService,
|
||||
} from '@affine/core/modules/cloud';
|
||||
import { GlobalDialogService } from '@affine/core/modules/dialogs';
|
||||
import { UrlService } from '@affine/core/modules/url';
|
||||
import {
|
||||
type CreateCheckoutSessionInput,
|
||||
SubscriptionPlan,
|
||||
@@ -249,19 +250,25 @@ const Downgrade = ({ disabled }: { disabled?: boolean }) => {
|
||||
const UpgradeToTeam = ({ recurring }: { recurring: SubscriptionRecurring }) => {
|
||||
const t = useI18n();
|
||||
const serverService = useService(ServerService);
|
||||
const urlService = useService(UrlService);
|
||||
const url = `${serverService.server.baseUrl}/upgrade-to-team?recurring=${recurring}`;
|
||||
const scheme = urlService.getClientScheme();
|
||||
const urlParams = new URLSearchParams();
|
||||
if (scheme) {
|
||||
urlParams.set('client', scheme);
|
||||
}
|
||||
|
||||
return (
|
||||
<a
|
||||
className={styles.planAction}
|
||||
href={url}
|
||||
href={`${url}${urlParams.toString() ? `&${urlParams.toString()}` : ''}`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Button
|
||||
className={styles.planAction}
|
||||
variant="primary"
|
||||
data-event-args-url={url}
|
||||
data-event-args-url={`${url}${urlParams.toString() ? `&${urlParams.toString()}` : ''}`}
|
||||
>
|
||||
{t['com.affine.payment.upgrade']()}
|
||||
</Button>
|
||||
@@ -289,6 +296,8 @@ export const Upgrade = ({
|
||||
}) => {
|
||||
const t = useI18n();
|
||||
const authService = useService(AuthService);
|
||||
const urlService = useService(UrlService);
|
||||
const schema = urlService.getClientScheme();
|
||||
|
||||
const handleBeforeCheckout = useCallback(() => {
|
||||
track.$.settingsPanel.plans.checkout({
|
||||
@@ -308,7 +317,8 @@ export const Upgrade = ({
|
||||
authService.session.account$.value,
|
||||
plan,
|
||||
recurring,
|
||||
workspaceId
|
||||
workspaceId || '',
|
||||
schema
|
||||
),
|
||||
...checkoutInput,
|
||||
}),
|
||||
@@ -317,6 +327,7 @@ export const Upgrade = ({
|
||||
checkoutInput,
|
||||
plan,
|
||||
recurring,
|
||||
schema,
|
||||
workspaceId,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -16,14 +16,15 @@ export const Component = () => {
|
||||
const t = useI18n();
|
||||
const [params] = useSearchParams();
|
||||
|
||||
const { jumpToIndex, jumpToOpenInApp } = useNavigateHelper();
|
||||
const openAffine = useCallback(() => {
|
||||
if (params.get('scheme')) {
|
||||
jumpToOpenInApp('bring-to-front');
|
||||
const { jumpToOpenInApp } = useNavigateHelper();
|
||||
const openAFFiNE = useCallback(() => {
|
||||
if (params.get('client')) {
|
||||
return jumpToOpenInApp('bring-to-front');
|
||||
} else {
|
||||
jumpToIndex();
|
||||
// close popup window
|
||||
return window.close();
|
||||
}
|
||||
}, [jumpToIndex, jumpToOpenInApp, params]);
|
||||
}, [jumpToOpenInApp, params]);
|
||||
|
||||
const subtitle = (
|
||||
<div className={styles.leftContentText}>
|
||||
@@ -49,7 +50,7 @@ export const Component = () => {
|
||||
title={t['com.affine.payment.ai-upgrade-success-page.title']()}
|
||||
subtitle={subtitle}
|
||||
>
|
||||
<Button variant="primary" size="extraLarge" onClick={openAffine}>
|
||||
<Button variant="primary" size="extraLarge" onClick={openAFFiNE}>
|
||||
{t['com.affine.other-page.nav.open-affine']()}
|
||||
</Button>
|
||||
</AuthPageContainer>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Button, Loading } from '@affine/component';
|
||||
import { UrlService } from '@affine/core/modules/url';
|
||||
import { UserFriendlyError } from '@affine/error';
|
||||
import {
|
||||
SubscriptionPlan,
|
||||
@@ -95,9 +96,10 @@ function getProductTriple(searchParams: URLSearchParams): ProductTriple {
|
||||
}
|
||||
|
||||
export const Component = () => {
|
||||
const { authService, subscriptionService } = useServices({
|
||||
const { authService, subscriptionService, urlService } = useServices({
|
||||
AuthService,
|
||||
SubscriptionService,
|
||||
UrlService,
|
||||
});
|
||||
const [searchParams] = useSearchParams();
|
||||
const [message, setMessage] = useState('');
|
||||
@@ -155,7 +157,8 @@ export const Component = () => {
|
||||
),
|
||||
});
|
||||
setMessage('Redirecting...');
|
||||
location.href = checkout;
|
||||
urlService.openPopupWindow(checkout);
|
||||
jumpToIndex();
|
||||
} catch (err) {
|
||||
const e = UserFriendlyError.fromAny(err);
|
||||
setMessage(e.message);
|
||||
@@ -180,6 +183,7 @@ export const Component = () => {
|
||||
retryKey,
|
||||
variant,
|
||||
coupon,
|
||||
urlService,
|
||||
]);
|
||||
|
||||
return (
|
||||
|
||||
@@ -16,16 +16,15 @@ export const Component = () => {
|
||||
const t = useI18n();
|
||||
const [params] = useSearchParams();
|
||||
|
||||
const { jumpToIndex, jumpToOpenInApp } = useNavigateHelper();
|
||||
const openAffine = useCallback(() => {
|
||||
if (params.get('schema')) {
|
||||
jumpToOpenInApp('bring-to-front');
|
||||
const { jumpToOpenInApp } = useNavigateHelper();
|
||||
const openAFFiNE = useCallback(() => {
|
||||
if (params.get('client')) {
|
||||
return jumpToOpenInApp('bring-to-front');
|
||||
} else {
|
||||
jumpToIndex();
|
||||
// close popup window
|
||||
return window.close();
|
||||
}
|
||||
// close popup window
|
||||
window.close();
|
||||
}, [jumpToIndex, jumpToOpenInApp, params]);
|
||||
}, [jumpToOpenInApp, params]);
|
||||
|
||||
const subtitle = (
|
||||
<div className={styles.leftContentText}>
|
||||
@@ -51,7 +50,7 @@ export const Component = () => {
|
||||
title={t['com.affine.payment.upgrade-success-page.title']()}
|
||||
subtitle={subtitle}
|
||||
>
|
||||
<Button variant="primary" size="extraLarge" onClick={openAffine}>
|
||||
<Button variant="primary" size="extraLarge" onClick={openAFFiNE}>
|
||||
{t['com.affine.other-page.nav.open-affine']()}
|
||||
</Button>
|
||||
</AuthPageContainer>
|
||||
|
||||
@@ -71,9 +71,12 @@ export const UpgradeToTeam = ({ recurring }: { recurring: string | null }) => {
|
||||
const [selectedWorkspace, setSelectedWorkspace] =
|
||||
useState<WorkspaceMetadata | null>(null);
|
||||
|
||||
const information = useWorkspaceInfo(selectedWorkspace || undefined);
|
||||
|
||||
const name = information?.name ?? UNTITLED_WORKSPACE_NAME;
|
||||
const workspacesService = useService(WorkspacesService);
|
||||
const profile = selectedWorkspace
|
||||
? workspacesService.getProfile(selectedWorkspace)
|
||||
: undefined;
|
||||
const workspaceInfo = useLiveData(profile?.profile$);
|
||||
const name = workspaceInfo?.name ?? UNTITLED_WORKSPACE_NAME;
|
||||
|
||||
const menuTriggerText = useMemo(() => {
|
||||
if (selectedWorkspace) {
|
||||
@@ -92,6 +95,39 @@ export const UpgradeToTeam = ({ recurring }: { recurring: string | null }) => {
|
||||
setOpenCreate(true);
|
||||
}, []);
|
||||
|
||||
const revalidate = useCallback(() => {
|
||||
profile?.revalidate();
|
||||
}, [profile]);
|
||||
|
||||
const { jumpToPage, jumpToOpenInApp } = useNavigateHelper();
|
||||
const [params] = useSearchParams();
|
||||
const isTeam = workspaceInfo?.isTeam;
|
||||
|
||||
const openAFFiNE = useCallback(() => {
|
||||
if (params.get('client')) {
|
||||
jumpToOpenInApp(`/workspace/${selectedWorkspace?.id}/all`);
|
||||
} else if (selectedWorkspace) {
|
||||
jumpToPage(selectedWorkspace.id, 'all');
|
||||
}
|
||||
}, [jumpToOpenInApp, jumpToPage, params, selectedWorkspace]);
|
||||
|
||||
useEffect(() => {
|
||||
revalidate();
|
||||
}, [selectedWorkspace, revalidate]);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('focus', revalidate);
|
||||
return () => {
|
||||
window.removeEventListener('focus', revalidate);
|
||||
};
|
||||
}, [revalidate]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isTeam && selectedWorkspace) {
|
||||
return openAFFiNE();
|
||||
}
|
||||
}, [isTeam, jumpToPage, openAFFiNE, selectedWorkspace]);
|
||||
|
||||
return (
|
||||
<AuthPageContainer title={t['com.affine.upgrade-to-team-page.title']()}>
|
||||
<div className={styles.root}>
|
||||
@@ -139,12 +175,15 @@ export const UpgradeToTeam = ({ recurring }: { recurring: string | null }) => {
|
||||
<div>
|
||||
{t['com.affine.upgrade-to-team-page.benefit.description']()}
|
||||
</div>
|
||||
<UpgradeDialog
|
||||
recurring={recurring}
|
||||
open={openUpgrade}
|
||||
onOpenChange={setOpenUpgrade}
|
||||
selectedWorkspace={selectedWorkspace}
|
||||
/>
|
||||
{selectedWorkspace && (
|
||||
<UpgradeDialog
|
||||
recurring={recurring}
|
||||
open={openUpgrade}
|
||||
onOpenChange={setOpenUpgrade}
|
||||
workspaceId={selectedWorkspace.id}
|
||||
workspaceName={name}
|
||||
/>
|
||||
)}
|
||||
<CreateWorkspaceDialog
|
||||
open={openCreate}
|
||||
onOpenChange={setOpenCreate}
|
||||
@@ -172,52 +211,22 @@ export const UpgradeToTeam = ({ recurring }: { recurring: string | null }) => {
|
||||
const UpgradeDialog = ({
|
||||
open,
|
||||
onOpenChange,
|
||||
selectedWorkspace,
|
||||
workspaceId,
|
||||
workspaceName,
|
||||
recurring,
|
||||
}: {
|
||||
open: boolean;
|
||||
selectedWorkspace: WorkspaceMetadata | null;
|
||||
workspaceId: string;
|
||||
workspaceName: string;
|
||||
recurring: string | null;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
}) => {
|
||||
const t = useI18n();
|
||||
const workspacesService = useService(WorkspacesService);
|
||||
const { jumpToPage } = useNavigateHelper();
|
||||
|
||||
const profile = selectedWorkspace
|
||||
? workspacesService.getProfile(selectedWorkspace)
|
||||
: undefined;
|
||||
const workspaceInfo = useLiveData(profile?.profile$);
|
||||
const isTeam = workspaceInfo?.isTeam;
|
||||
const workspaceName = workspaceInfo?.name;
|
||||
const workspaceId = selectedWorkspace?.id;
|
||||
|
||||
const onClose = useCallback(() => {
|
||||
onOpenChange(false);
|
||||
}, [onOpenChange]);
|
||||
|
||||
const revalidate = useCallback(() => {
|
||||
profile?.revalidate();
|
||||
}, [profile]);
|
||||
|
||||
useEffect(() => {
|
||||
revalidate();
|
||||
}, [selectedWorkspace, revalidate]);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('focus', revalidate);
|
||||
return () => {
|
||||
window.removeEventListener('focus', revalidate);
|
||||
};
|
||||
}, [revalidate]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isTeam && selectedWorkspace) {
|
||||
onClose();
|
||||
return jumpToPage(selectedWorkspace.id, 'all');
|
||||
}
|
||||
}, [isTeam, jumpToPage, onClose, selectedWorkspace]);
|
||||
|
||||
const currentRecurring =
|
||||
recurring &&
|
||||
recurring.toLowerCase() === SubscriptionRecurring.Yearly.toLowerCase()
|
||||
|
||||
Reference in New Issue
Block a user