Cloud/gate topup on subscription (#6399)

## Summary

Gate the Top up buttons in the user dropdown and credits page of the
settings.


┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6399-Cloud-gate-topup-on-subscription-29c6d73d36508127866cdcbcfda66c46)
by [Unito](https://www.unito.io)

---------

Co-authored-by: DrJKL <DrJKL0424@gmail.com>
This commit is contained in:
Christian Byrne
2025-11-01 01:37:00 -07:00
committed by GitHub
parent 6fc5748a32
commit c8e24190cd
4 changed files with 18 additions and 4 deletions

View File

@@ -15,7 +15,7 @@
<UserCredit text-class="text-3xl font-bold" />
<Skeleton v-if="loading" width="2rem" height="2rem" />
<Button
v-else
v-else-if="isActiveSubscription"
:label="$t('credits.purchaseCredits')"
:loading="loading"
@click="handlePurchaseCreditsClick"
@@ -123,6 +123,7 @@ import { computed, ref, watch } from 'vue'
import UserCredit from '@/components/common/UserCredit.vue'
import UsageLogsTable from '@/components/dialog/content/setting/UsageLogsTable.vue'
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
import { useDialogService } from '@/services/dialogService'
import { useCommandStore } from '@/stores/commandStore'
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
@@ -139,6 +140,7 @@ const dialogService = useDialogService()
const authStore = useFirebaseAuthStore()
const authActions = useFirebaseAuthActions()
const commandStore = useCommandStore()
const { isActiveSubscription } = useSubscription()
const loading = computed(() => authStore.loading)
const balanceLoading = computed(() => authStore.isFetchingBalance)

View File

@@ -7,6 +7,7 @@ import { useErrorHandling } from '@/composables/useErrorHandling'
import type { ErrorRecoveryStrategy } from '@/composables/useErrorHandling'
import { t } from '@/i18n'
import { isCloud } from '@/platform/distribution/types'
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
import { useToastStore } from '@/platform/updates/common/toastStore'
import { useDialogService } from '@/services/dialogService'
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
@@ -82,6 +83,9 @@ export const useFirebaseAuthActions = () => {
)
const purchaseCredits = wrapWithErrorHandlingAsync(async (amount: number) => {
const { isActiveSubscription } = useSubscription()
if (!isActiveSubscription.value) return
const response = await authStore.initiateCreditPurchase({
amount_micros: usdToMicros(amount),
currency: 'usd'

View File

@@ -49,6 +49,7 @@ import { getMp3Metadata } from '@/scripts/metadata/mp3'
import { getOggMetadata } from '@/scripts/metadata/ogg'
import { getSvgMetadata } from '@/scripts/metadata/svg'
import { useDialogService } from '@/services/dialogService'
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
import { useExtensionService } from '@/services/extensionService'
import { useLitegraphService } from '@/services/litegraphService'
import { useSubgraphService } from '@/services/subgraphService'
@@ -703,9 +704,12 @@ export class ComfyApp {
'Payment Required: Please add credits to your account to use this node.'
)
) {
useDialogService().showTopUpCreditsDialog({
isInsufficientCredits: true
})
const { isActiveSubscription } = useSubscription()
if (isActiveSubscription.value) {
useDialogService().showTopUpCreditsDialog({
isInsufficientCredits: true
})
}
} else {
useDialogService().showExecutionErrorDialog(detail)
}

View File

@@ -14,6 +14,7 @@ import ComfyOrgHeader from '@/components/dialog/header/ComfyOrgHeader.vue'
import SettingDialogHeader from '@/components/dialog/header/SettingDialogHeader.vue'
import { t } from '@/i18n'
import { isCloud } from '@/platform/distribution/types'
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
import SettingDialogContent from '@/platform/settings/components/SettingDialogContent.vue'
import type { ExecutionErrorWsMessage } from '@/schemas/apiSchema'
import { useDialogStore } from '@/stores/dialogStore'
@@ -341,6 +342,9 @@ export const useDialogService = () => {
function showTopUpCreditsDialog(options?: {
isInsufficientCredits?: boolean
}) {
const { isActiveSubscription } = useSubscription()
if (!isActiveSubscription.value) return
return dialogStore.showDialog({
key: 'top-up-credits',
component: TopUpCreditsDialogContent,