From 3432f355b0e31637a766f2c81f0d0dcbb1967345 Mon Sep 17 00:00:00 2001 From: DarkSky Date: Wed, 28 Feb 2024 08:29:37 +0000 Subject: [PATCH] feat: backend module awareness & optional request (#5909) --- packages/backend/server/src/core/config.ts | 1 + .../server/src/plugins/payment/index.ts | 9 ++++---- .../setting-modal/account-setting/index.tsx | 6 ++--- .../setting-modal/general-setting/index.tsx | 6 ++--- .../new-workspace-setting-detail/index.tsx | 6 ++--- .../src/hooks/affine/use-server-config.ts | 23 +++++++++++-------- .../core/src/hooks/use-subscription.ts | 14 +++++------ 7 files changed, 34 insertions(+), 31 deletions(-) diff --git a/packages/backend/server/src/core/config.ts b/packages/backend/server/src/core/config.ts index c6e7549058..6940a77aca 100644 --- a/packages/backend/server/src/core/config.ts +++ b/packages/backend/server/src/core/config.ts @@ -46,6 +46,7 @@ export class ServerConfigType { @Field(() => [ServerFeature], { description: 'enabled server features' }) features!: ServerFeature[]; } + export class ServerConfigResolver { @Query(() => ServerConfigType, { description: 'server config', diff --git a/packages/backend/server/src/plugins/payment/index.ts b/packages/backend/server/src/plugins/payment/index.ts index 0539b9fd90..9a4e33578f 100644 --- a/packages/backend/server/src/plugins/payment/index.ts +++ b/packages/backend/server/src/plugins/payment/index.ts @@ -17,11 +17,10 @@ import { StripeWebhook } from './webhook'; UserSubscriptionResolver, ], controllers: [StripeWebhook], - // TODO(@forehalo): enable this requirements when conditional query is implemented in frontend - // requires: [ - // 'plugins.payment.stripe.keys.APIKey', - // 'plugins.payment.stripe.keys.webhookKey', - // ], + requires: [ + 'plugins.payment.stripe.keys.APIKey', + 'plugins.payment.stripe.keys.webhookKey', + ], contributesTo: ServerFeature.Payment, if: config => config.flavor.graphql, }) diff --git a/packages/frontend/core/src/components/affine/setting-modal/account-setting/index.tsx b/packages/frontend/core/src/components/affine/setting-modal/account-setting/index.tsx index 2f148bae68..287042d2af 100644 --- a/packages/frontend/core/src/components/affine/setting-modal/account-setting/index.tsx +++ b/packages/frontend/core/src/components/affine/setting-modal/account-setting/index.tsx @@ -34,7 +34,7 @@ import { openSignOutModalAtom, } from '../../../../atoms'; import { useCurrentUser } from '../../../../hooks/affine/use-current-user'; -import { useSelfHosted } from '../../../../hooks/affine/use-server-config'; +import { useServerFeatures } from '../../../../hooks/affine/use-server-config'; import { useMutation } from '../../../../hooks/use-mutation'; import { useQuery } from '../../../../hooks/use-query'; import { useUserSubscription } from '../../../../hooks/use-subscription'; @@ -169,7 +169,7 @@ export const AvatarAndName = () => { const StoragePanel = () => { const t = useAFFiNEI18N(); - const isSelfHosted = useSelfHosted(); + const { payment: hasPaymentFeature } = useServerFeatures(); const { data } = useQuery({ query: allBlobSizesQuery, @@ -205,7 +205,7 @@ const StoragePanel = () => { plan={plan} value={data.collectAllBlobSizes.size} onUpgrade={onUpgrade} - upgradable={!isSelfHosted} + upgradable={hasPaymentFeature} /> ); diff --git a/packages/frontend/core/src/components/affine/setting-modal/general-setting/index.tsx b/packages/frontend/core/src/components/affine/setting-modal/general-setting/index.tsx index fda5ddd85e..029ffed410 100644 --- a/packages/frontend/core/src/components/affine/setting-modal/general-setting/index.tsx +++ b/packages/frontend/core/src/components/affine/setting-modal/general-setting/index.tsx @@ -7,7 +7,7 @@ import { import type { ReactElement, SVGProps } from 'react'; import { useCurrentLoginStatus } from '../../../../hooks/affine/use-current-login-status'; -import { useSelfHosted } from '../../../../hooks/affine/use-server-config'; +import { useServerFeatures } from '../../../../hooks/affine/use-server-config'; import type { GeneralSettingKey } from '../types'; import { AboutAffine } from './about'; import { AppearanceSettings } from './appearance'; @@ -28,7 +28,7 @@ export type GeneralSettingList = GeneralSettingListItem[]; export const useGeneralSettingList = (): GeneralSettingList => { const t = useAFFiNEI18N(); const status = useCurrentLoginStatus(); - const isSelfHosted = useSelfHosted(); + const { payment: hasPaymentFeature } = useServerFeatures(); const settings: GeneralSettingListItem[] = [ { @@ -51,7 +51,7 @@ export const useGeneralSettingList = (): GeneralSettingList => { }, ]; - if (!isSelfHosted) { + if (hasPaymentFeature) { settings.splice(3, 0, { key: 'plans', title: t['com.affine.payment.title'](), diff --git a/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/new-workspace-setting-detail/index.tsx b/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/new-workspace-setting-detail/index.tsx index 8e9708f18f..2d178dd85e 100644 --- a/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/new-workspace-setting-detail/index.tsx +++ b/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/new-workspace-setting-detail/index.tsx @@ -3,7 +3,7 @@ import { SettingRow, SettingWrapper, } from '@affine/component/setting-components'; -import { useSelfHosted } from '@affine/core/hooks/affine/use-server-config'; +import { useServerFeatures } from '@affine/core/hooks/affine/use-server-config'; import { useWorkspace } from '@affine/core/hooks/use-workspace'; import { useWorkspaceInfo } from '@affine/core/hooks/use-workspace-info'; import { UNTITLED_WORKSPACE_NAME } from '@affine/env/constant'; @@ -20,7 +20,7 @@ import type { WorkspaceSettingDetailProps } from './types'; export const WorkspaceSettingDetail = (props: WorkspaceSettingDetailProps) => { const t = useAFFiNEI18N(); - const isSelfHosted = useSelfHosted(); + const { payment: hasPaymentFeature } = useServerFeatures(); const workspaceMetadata = props.workspaceMetadata; // useWorkspace hook is a vary heavy operation here, but we need syncing name and avatar changes here, @@ -49,7 +49,7 @@ export const WorkspaceSettingDetail = (props: WorkspaceSettingDetailProps) => { - + {environment.isDesktop && ( diff --git a/packages/frontend/core/src/hooks/affine/use-server-config.ts b/packages/frontend/core/src/hooks/affine/use-server-config.ts index 1c6f8afdc4..ef0878d1de 100644 --- a/packages/frontend/core/src/hooks/affine/use-server-config.ts +++ b/packages/frontend/core/src/hooks/affine/use-server-config.ts @@ -1,4 +1,5 @@ -import { serverConfigQuery, ServerDeploymentType } from '@affine/graphql'; +import type { ServerFeature } from '@affine/graphql'; +import { serverConfigQuery } from '@affine/graphql'; import type { BareFetcher, Middleware } from 'swr'; import { useQueryImmutable } from '../use-query'; @@ -25,20 +26,22 @@ const useServerConfig = () => { return config.serverConfig; }; -export const useServerType = () => { +type LowercaseServerFeature = Lowercase; +type ServerFeatureRecord = { + [key in LowercaseServerFeature]: boolean; +}; + +export const useServerFeatures = (): ServerFeatureRecord => { const config = useServerConfig(); if (!config) { - return 'local'; + return {} as ServerFeatureRecord; } - return config.type; -}; - -export const useSelfHosted = () => { - const serverType = useServerType(); - - return ['local', ServerDeploymentType.Selfhosted].includes(serverType); + return Array.from(new Set(config.features)).reduce((acc, cur) => { + acc[cur.toLowerCase() as LowercaseServerFeature] = true; + return acc; + }, {} as ServerFeatureRecord); }; export const useServerBaseUrl = () => { diff --git a/packages/frontend/core/src/hooks/use-subscription.ts b/packages/frontend/core/src/hooks/use-subscription.ts index be6a1a0b78..d6c95a8c10 100644 --- a/packages/frontend/core/src/hooks/use-subscription.ts +++ b/packages/frontend/core/src/hooks/use-subscription.ts @@ -1,7 +1,7 @@ import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks'; import { type SubscriptionQuery, subscriptionQuery } from '@affine/graphql'; -import { useSelfHosted } from './affine/use-server-config'; +import { useServerFeatures } from './affine/use-server-config'; import { useQuery } from './use-query'; export type Subscription = NonNullable< @@ -14,10 +14,10 @@ const selector = (data: SubscriptionQuery) => data.currentUser?.subscription ?? null; export const useUserSubscription = () => { - const isSelfHosted = useSelfHosted(); - const { data, mutate } = useQuery({ - query: subscriptionQuery, - }); + const { payment: hasPaymentFeature } = useServerFeatures(); + const { data, mutate } = useQuery( + hasPaymentFeature ? { query: subscriptionQuery } : undefined + ); const set: SubscriptionMutator = useAsyncCallback( async (update?: Partial) => { @@ -39,8 +39,8 @@ export const useUserSubscription = () => { [mutate] ); - if (isSelfHosted) { - return [selector(data), () => {}] as const; + if (!hasPaymentFeature) { + return [null, () => {}] as const; } return [selector(data), set] as const;