mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-07 09:21:24 +08:00
feat(core): compatible with multiple subscriptions (#6277)
This commit is contained in:
@@ -4,7 +4,7 @@ import { Loading } from '@affine/component/ui/loading';
|
|||||||
import { AffineShapeIcon } from '@affine/core/components/page-list';
|
import { AffineShapeIcon } from '@affine/core/components/page-list';
|
||||||
import { useCredentialsRequirement } from '@affine/core/hooks/affine/use-server-config';
|
import { useCredentialsRequirement } from '@affine/core/hooks/affine/use-server-config';
|
||||||
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
|
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
|
||||||
import type { SubscriptionPlan, SubscriptionRecurring } from '@affine/graphql';
|
import { SubscriptionPlan, type SubscriptionRecurring } from '@affine/graphql';
|
||||||
import {
|
import {
|
||||||
changePasswordMutation,
|
changePasswordMutation,
|
||||||
createCheckoutSessionMutation,
|
createCheckoutSessionMutation,
|
||||||
@@ -138,7 +138,11 @@ const SubscriptionRedirectWithData = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subscriptionData.currentUser?.subscription) {
|
if (
|
||||||
|
subscriptionData.currentUser?.subscriptions?.some(
|
||||||
|
sub => sub.plan === SubscriptionPlan.Pro
|
||||||
|
)
|
||||||
|
) {
|
||||||
return <SubscriptionExisting />;
|
return <SubscriptionExisting />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,22 @@
|
|||||||
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
|
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
|
||||||
import type { SubscriptionQuery } from '@affine/graphql';
|
import type { SubscriptionQuery } from '@affine/graphql';
|
||||||
import { subscriptionQuery } from '@affine/graphql';
|
import { SubscriptionPlan, subscriptionQuery } from '@affine/graphql';
|
||||||
|
|
||||||
import { useServerFeatures } from './affine/use-server-config';
|
import { useServerFeatures } from './affine/use-server-config';
|
||||||
import { useQuery } from './use-query';
|
import { useQuery } from './use-query';
|
||||||
|
|
||||||
export type Subscription = NonNullable<
|
export type Subscription = NonNullable<
|
||||||
NonNullable<SubscriptionQuery['currentUser']>['subscription']
|
NonNullable<SubscriptionQuery['currentUser']>['subscriptions'][number]
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export type SubscriptionMutator = (update?: Partial<Subscription>) => void;
|
export type SubscriptionMutator = (update?: Partial<Subscription>) => void;
|
||||||
|
|
||||||
const selector = (data: SubscriptionQuery) =>
|
const selector = (data: SubscriptionQuery, plan: SubscriptionPlan) =>
|
||||||
data.currentUser?.subscription ?? null;
|
(data.currentUser?.subscriptions ?? []).find(p => p.plan === plan);
|
||||||
|
|
||||||
export const useUserSubscription = () => {
|
export const useUserSubscription = (
|
||||||
|
plan: SubscriptionPlan = SubscriptionPlan.Pro
|
||||||
|
) => {
|
||||||
const { payment: hasPaymentFeature } = useServerFeatures();
|
const { payment: hasPaymentFeature } = useServerFeatures();
|
||||||
const { data, mutate } = useQuery(
|
const { data, mutate } = useQuery(
|
||||||
hasPaymentFeature ? { query: subscriptionQuery } : undefined
|
hasPaymentFeature ? { query: subscriptionQuery } : undefined
|
||||||
@@ -23,26 +25,25 @@ export const useUserSubscription = () => {
|
|||||||
const set: SubscriptionMutator = useAsyncCallback(
|
const set: SubscriptionMutator = useAsyncCallback(
|
||||||
async (update?: Partial<Subscription>) => {
|
async (update?: Partial<Subscription>) => {
|
||||||
await mutate(prev => {
|
await mutate(prev => {
|
||||||
if (!update || !prev?.currentUser?.subscription) {
|
if (!update || !prev?.currentUser?.subscriptions?.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
currentUser: {
|
currentUser: {
|
||||||
subscription: {
|
subscriptions: (prev.currentUser?.subscriptions ?? []).map(sub =>
|
||||||
...prev.currentUser?.subscription,
|
sub.plan !== plan ? sub : { ...sub, ...update }
|
||||||
...update,
|
),
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[mutate]
|
[mutate, plan]
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!hasPaymentFeature) {
|
if (!hasPaymentFeature) {
|
||||||
return [null, () => {}] as const;
|
return [null, () => {}] as const;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [selector(data), set] as const;
|
return [selector(data, plan), set] as const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -748,7 +748,7 @@ export const subscriptionQuery = {
|
|||||||
query: `
|
query: `
|
||||||
query subscription {
|
query subscription {
|
||||||
currentUser {
|
currentUser {
|
||||||
subscription {
|
subscriptions {
|
||||||
id
|
id
|
||||||
status
|
status
|
||||||
plan
|
plan
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
query subscription {
|
query subscription {
|
||||||
currentUser {
|
currentUser {
|
||||||
subscription {
|
subscriptions {
|
||||||
id
|
id
|
||||||
status
|
status
|
||||||
plan
|
plan
|
||||||
|
|||||||
@@ -743,7 +743,7 @@ export type SubscriptionQuery = {
|
|||||||
__typename?: 'Query';
|
__typename?: 'Query';
|
||||||
currentUser: {
|
currentUser: {
|
||||||
__typename?: 'UserType';
|
__typename?: 'UserType';
|
||||||
subscription: {
|
subscriptions: Array<{
|
||||||
__typename?: 'UserSubscription';
|
__typename?: 'UserSubscription';
|
||||||
id: string;
|
id: string;
|
||||||
status: SubscriptionStatus;
|
status: SubscriptionStatus;
|
||||||
@@ -753,7 +753,7 @@ export type SubscriptionQuery = {
|
|||||||
end: string;
|
end: string;
|
||||||
nextBillAt: string | null;
|
nextBillAt: string | null;
|
||||||
canceledAt: string | null;
|
canceledAt: string | null;
|
||||||
} | null;
|
}>;
|
||||||
} | null;
|
} | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user