diff --git a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/billing/payment-method.tsx b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/billing/payment-method.tsx index ba6ab9c9e6..61d2799138 100644 --- a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/billing/payment-method.tsx +++ b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/billing/payment-method.tsx @@ -1,3 +1,4 @@ +import { notify } from '@affine/component'; import { SettingRow } from '@affine/component/setting-components'; import { Button, @@ -7,6 +8,7 @@ import { import { useAsyncCallback } from '@affine/core/components/hooks/affine-async-hooks'; import { SubscriptionService } from '@affine/core/modules/cloud'; import { UrlService } from '@affine/core/modules/url'; +import { UserFriendlyError } from '@affine/error'; import { createCustomerPortalMutation } from '@affine/graphql'; import { useI18n } from '@affine/i18n'; import { ArrowRightSmallIcon } from '@blocksuite/icons/rc'; @@ -92,8 +94,11 @@ export const PaymentMethodUpdater = ({ const update = useAsyncCallback(async () => { await trigger(null, { onSuccess: data => { - urlService.openPopupWindow(data.createCustomerPortal); + urlService.openExternal(data.createCustomerPortal); }, + }).catch(e => { + const userFriendlyError = UserFriendlyError.fromAny(e); + notify.error(userFriendlyError); }); }, [trigger, urlService]); diff --git a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/plans/checkout-slot.tsx b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/plans/checkout-slot.tsx index 252cf517ee..9ab30793e5 100644 --- a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/plans/checkout-slot.tsx +++ b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/plans/checkout-slot.tsx @@ -65,7 +65,7 @@ export const CheckoutSlot = ({ idempotencyKey, ...checkoutOptions, }); - urlService.openPopupWindow(session); + urlService.openExternal(session); setOpenedExternalWindow(true); setIdempotencyKey(nanoid()); onCheckoutSuccess?.(); diff --git a/packages/frontend/core/src/desktop/dialogs/setting/workspace-setting/billing/payment-method.tsx b/packages/frontend/core/src/desktop/dialogs/setting/workspace-setting/billing/payment-method.tsx index 1df6f3f987..c61b74e5d8 100644 --- a/packages/frontend/core/src/desktop/dialogs/setting/workspace-setting/billing/payment-method.tsx +++ b/packages/frontend/core/src/desktop/dialogs/setting/workspace-setting/billing/payment-method.tsx @@ -1,8 +1,9 @@ -import { Button } from '@affine/component'; +import { Button, notify } from '@affine/component'; import { SettingRow } from '@affine/component/setting-components'; import { useAsyncCallback } from '@affine/core/components/hooks/affine-async-hooks'; import { useMutation } from '@affine/core/components/hooks/use-mutation'; import { UrlService } from '@affine/core/modules/url'; +import { UserFriendlyError } from '@affine/error'; import { createCustomerPortalMutation } from '@affine/graphql'; import { useI18n } from '@affine/i18n'; import { useService } from '@toeverything/infra'; @@ -19,8 +20,11 @@ export const PaymentMethodUpdater = () => { const update = useAsyncCallback(async () => { await trigger(null, { onSuccess: data => { - urlService.openPopupWindow(data.createCustomerPortal); + urlService.openExternal(data.createCustomerPortal); }, + }).catch(e => { + const userFriendlyError = UserFriendlyError.fromAny(e); + notify.error(userFriendlyError); }); }, [trigger, urlService]); diff --git a/packages/frontend/core/src/desktop/dialogs/setting/workspace-setting/license/index.tsx b/packages/frontend/core/src/desktop/dialogs/setting/workspace-setting/license/index.tsx index d72fb70aac..1b86ba0abf 100644 --- a/packages/frontend/core/src/desktop/dialogs/setting/workspace-setting/license/index.tsx +++ b/packages/frontend/core/src/desktop/dialogs/setting/workspace-setting/license/index.tsx @@ -1,4 +1,4 @@ -import { Button } from '@affine/component'; +import { Button, notify } from '@affine/component'; import { SettingHeader, SettingRow, @@ -13,6 +13,7 @@ import { import { WorkspacePermissionService } from '@affine/core/modules/permissions'; import { UrlService } from '@affine/core/modules/url'; import { WorkspaceService } from '@affine/core/modules/workspace'; +import { UserFriendlyError } from '@affine/error'; import { createSelfhostCustomerPortalMutation, SubscriptionPlan, @@ -111,12 +112,13 @@ const PaymentMethodUpdater = () => { }, { onSuccess: data => { - urlService.openPopupWindow( - data.createSelfhostWorkspaceCustomerPortal - ); + urlService.openExternal(data.createSelfhostWorkspaceCustomerPortal); }, } - ); + ).catch(e => { + const userFriendlyError = UserFriendlyError.fromAny(e); + notify.error(userFriendlyError); + }); }, [trigger, urlService, workspace.id]); if (!isTeam) { diff --git a/packages/frontend/core/src/desktop/pages/ai-upgrade-success/index.tsx b/packages/frontend/core/src/desktop/pages/ai-upgrade-success/index.tsx index 81ca31fbc9..dca1b8b859 100644 --- a/packages/frontend/core/src/desktop/pages/ai-upgrade-success/index.tsx +++ b/packages/frontend/core/src/desktop/pages/ai-upgrade-success/index.tsx @@ -16,15 +16,14 @@ export const Component = () => { const t = useI18n(); const [params] = useSearchParams(); - const { jumpToOpenInApp } = useNavigateHelper(); + const { jumpToIndex, jumpToOpenInApp } = useNavigateHelper(); const openAFFiNE = useCallback(() => { if (params.get('client')) { return jumpToOpenInApp('bring-to-front'); } else { - // close popup window - return window.close(); + jumpToIndex(); } - }, [jumpToOpenInApp, params]); + }, [jumpToIndex, jumpToOpenInApp, params]); const subtitle = (
diff --git a/packages/frontend/core/src/desktop/pages/subscribe/index.tsx b/packages/frontend/core/src/desktop/pages/subscribe/index.tsx index d9712debde..5b29400078 100644 --- a/packages/frontend/core/src/desktop/pages/subscribe/index.tsx +++ b/packages/frontend/core/src/desktop/pages/subscribe/index.tsx @@ -157,8 +157,7 @@ export const Component = () => { ), }); setMessage('Redirecting...'); - urlService.openPopupWindow(checkout); - jumpToIndex(); + urlService.openExternal(checkout); } catch (err) { const e = UserFriendlyError.fromAny(err); setMessage(e.message); diff --git a/packages/frontend/core/src/desktop/pages/upgrade-success/index.tsx b/packages/frontend/core/src/desktop/pages/upgrade-success/index.tsx index f2b280e259..e4e64e6490 100644 --- a/packages/frontend/core/src/desktop/pages/upgrade-success/index.tsx +++ b/packages/frontend/core/src/desktop/pages/upgrade-success/index.tsx @@ -15,16 +15,15 @@ import * as styles from './styles.css'; export const Component = () => { const t = useI18n(); const [params] = useSearchParams(); + const { jumpToIndex, jumpToOpenInApp } = useNavigateHelper(); - const { jumpToOpenInApp } = useNavigateHelper(); const openAFFiNE = useCallback(() => { if (params.get('client')) { return jumpToOpenInApp('bring-to-front'); } else { - // close popup window - return window.close(); + jumpToIndex(); } - }, [jumpToOpenInApp, params]); + }, [jumpToIndex, jumpToOpenInApp, params]); const subtitle = (
diff --git a/packages/frontend/core/src/desktop/pages/upgrade-success/team/index.tsx b/packages/frontend/core/src/desktop/pages/upgrade-success/team/index.tsx index 88021ddc9f..73ff29a070 100644 --- a/packages/frontend/core/src/desktop/pages/upgrade-success/team/index.tsx +++ b/packages/frontend/core/src/desktop/pages/upgrade-success/team/index.tsx @@ -1,5 +1,6 @@ import { Button } from '@affine/component'; import { AuthPageContainer } from '@affine/component/auth-components'; +import { useNavigateHelper } from '@affine/core/components/hooks/use-navigate-helper'; import { Trans, useI18n } from '@affine/i18n'; import { useCallback } from 'react'; @@ -12,11 +13,11 @@ import * as styles from './styles.css'; */ export const Component = () => { const t = useI18n(); + const { jumpToIndex } = useNavigateHelper(); const openWorkspace = useCallback(() => { - // close popup window - window.close(); - }, []); + jumpToIndex(); + }, [jumpToIndex]); const subtitle = (
diff --git a/packages/frontend/core/src/modules/url/services/url.ts b/packages/frontend/core/src/modules/url/services/url.ts index cc7c5b9f93..b764f3ac1e 100644 --- a/packages/frontend/core/src/modules/url/services/url.ts +++ b/packages/frontend/core/src/modules/url/services/url.ts @@ -20,6 +20,8 @@ export class UrlService extends Service { * open a popup window, provide different implementations in different environments. * e.g. in electron, use system default browser to open a popup window. * + * !IMPORTANT: browser will block popup windows in async callbacks, so you should use openExternal instead. + * * @param url only full url with http/https protocol is supported */ openPopupWindow(url: string) { @@ -28,4 +30,19 @@ export class UrlService extends Service { } this.popupWindowProvider?.open(url); } + + /** + * Opens an external URL with different implementations based on the environment. + * Unlike openPopupWindow, openExternal opens the URL in the current browser tab, + * making it more suitable for cases where popup windows might be blocked by browsers. + * + * @param url only full url with http/https protocol is supported + */ + openExternal(url: string) { + if (BUILD_CONFIG.isWeb || BUILD_CONFIG.isMobileWeb) { + location.href = url; + } else { + this.popupWindowProvider?.open(url); + } + } }