feat(core): handle AI subscription for pro models (#13682)

<img width="576" height="251" alt="截屏2025-09-30 14 55 20"
src="https://github.com/user-attachments/assets/947a4ab3-8b34-434d-94a6-afb5dad3d32c"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added “Subscribe to AI” action across chat experiences (panel,
content, composer, input, playground, peek view) that launches an in-app
checkout flow.
- Chat content now refreshes subscription status when opened; desktop
chat pages wire the subscription action for seamless checkout.

- **Style**
  - Polished hover state for the subscription icon in chat preferences.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Wu Yue
2025-09-30 18:47:59 +08:00
committed by GitHub
parent 4b3ebd899b
commit 03ef4625bc
11 changed files with 125 additions and 3 deletions
@@ -0,0 +1,52 @@
import { generateSubscriptionCallbackLink } from '@affine/core/components/hooks/affine/use-subscription-notify';
import { AuthService, SubscriptionService } from '@affine/core/modules/cloud';
import { UrlService } from '@affine/core/modules/url';
import { SubscriptionPlan, SubscriptionRecurring } from '@affine/graphql';
import { useFramework } from '@toeverything/infra';
import { nanoid } from 'nanoid';
import { useCallback } from 'react';
/**
* Hook to handle AI subscription checkout
* @returns A function that initiates the AI subscription checkout process
*/
export const useAISubscribe = () => {
const framework = useFramework();
const handleAISubscribe = useCallback(async () => {
try {
const authService = framework.get(AuthService);
const subscriptionService = framework.get(SubscriptionService);
const urlService = framework.get(UrlService);
const account = authService.session.account$.value;
if (!account) {
return;
}
const idempotencyKey = nanoid();
const checkoutOptions = {
recurring: SubscriptionRecurring.Yearly,
plan: SubscriptionPlan.AI,
variant: null,
coupon: null,
successCallbackLink: generateSubscriptionCallbackLink(
account,
SubscriptionPlan.AI,
SubscriptionRecurring.Yearly
),
};
const session = await subscriptionService.createCheckoutSession({
idempotencyKey,
...checkoutOptions,
});
urlService.openExternal(session);
} catch (error) {
console.error(error);
}
}, [framework]);
return handleAISubscribe;
};