diff --git a/src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue b/src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue index c0cda19bf..7cca31fc5 100644 --- a/src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue +++ b/src/components/actionbar/ComfyRunButton/CloudRunButtonWrapper.vue @@ -1,7 +1,7 @@ diff --git a/src/components/dialog/content/setting/CreditsPanel.vue b/src/components/dialog/content/setting/CreditsPanel.vue index a7e0febcb..4412568b1 100644 --- a/src/components/dialog/content/setting/CreditsPanel.vue +++ b/src/components/dialog/content/setting/CreditsPanel.vue @@ -15,7 +15,7 @@ { + if (!isCloud) return true + return subscription?.isSubscribedOrIsNotCloud.value ?? false +}) const loading = computed(() => authStore.loading) const balanceLoading = computed(() => authStore.isFetchingBalance) diff --git a/src/components/topbar/CurrentUserPopover.test.ts b/src/components/topbar/CurrentUserPopover.test.ts index 1ad2321da..10a03de01 100644 --- a/src/components/topbar/CurrentUserPopover.test.ts +++ b/src/components/topbar/CurrentUserPopover.test.ts @@ -82,7 +82,7 @@ vi.mock('@/stores/firebaseAuthStore', () => ({ const mockFetchStatus = vi.fn().mockResolvedValue(undefined) vi.mock('@/platform/cloud/subscription/composables/useSubscription', () => ({ useSubscription: vi.fn(() => ({ - isActiveSubscription: { value: true }, + isSubscribedOrIsNotCloud: { value: true }, fetchStatus: mockFetchStatus })) })) diff --git a/src/components/topbar/CurrentUserPopover.vue b/src/components/topbar/CurrentUserPopover.vue index 93d7e9223..9d3f6e779 100644 --- a/src/components/topbar/CurrentUserPopover.vue +++ b/src/components/topbar/CurrentUserPopover.vue @@ -23,7 +23,10 @@ - + { dialogService.showSettingsDialog('user') diff --git a/src/composables/auth/useFirebaseAuthActions.ts b/src/composables/auth/useFirebaseAuthActions.ts index eed7eb021..8b20558b1 100644 --- a/src/composables/auth/useFirebaseAuthActions.ts +++ b/src/composables/auth/useFirebaseAuthActions.ts @@ -82,8 +82,10 @@ export const useFirebaseAuthActions = () => { ) const purchaseCredits = wrapWithErrorHandlingAsync(async (amount: number) => { - const { isActiveSubscription } = useSubscription() - if (!isActiveSubscription.value) return + if (isCloud) { + const { isSubscribedOrIsNotCloud } = useSubscription() + if (!isSubscribedOrIsNotCloud.value) return + } const response = await authStore.initiateCreditPurchase({ amount_micros: usdToMicros(amount), diff --git a/src/composables/useCoreCommands.ts b/src/composables/useCoreCommands.ts index 1cbfec909..7bdeb69e0 100644 --- a/src/composables/useCoreCommands.ts +++ b/src/composables/useCoreCommands.ts @@ -63,7 +63,7 @@ import { ManagerTab } from '@/workbench/extensions/manager/types/comfyManagerTyp import { useWorkflowTemplateSelectorDialog } from './useWorkflowTemplateSelectorDialog' -const { isActiveSubscription, showSubscriptionDialog } = useSubscription() +const { isSubscribedOrIsNotCloud, showSubscriptionDialog } = useSubscription() const moveSelectedNodesVersionAdded = '1.22.2' @@ -475,7 +475,7 @@ export function useCoreCommands(): ComfyCommand[] { trigger_source?: ExecutionTriggerSource }) => { useTelemetry()?.trackRunButton(metadata) - if (!isActiveSubscription.value) { + if (!isSubscribedOrIsNotCloud.value) { showSubscriptionDialog() return } @@ -498,7 +498,7 @@ export function useCoreCommands(): ComfyCommand[] { trigger_source?: ExecutionTriggerSource }) => { useTelemetry()?.trackRunButton(metadata) - if (!isActiveSubscription.value) { + if (!isSubscribedOrIsNotCloud.value) { showSubscriptionDialog() return } @@ -520,7 +520,7 @@ export function useCoreCommands(): ComfyCommand[] { trigger_source?: ExecutionTriggerSource }) => { useTelemetry()?.trackRunButton(metadata) - if (!isActiveSubscription.value) { + if (!isSubscribedOrIsNotCloud.value) { showSubscriptionDialog() return } diff --git a/src/platform/cloud/subscription/components/SubscribeButton.vue b/src/platform/cloud/subscription/components/SubscribeButton.vue index be57d3dad..c08df2ba2 100644 --- a/src/platform/cloud/subscription/components/SubscribeButton.vue +++ b/src/platform/cloud/subscription/components/SubscribeButton.vue @@ -51,7 +51,7 @@ const emit = defineEmits<{ subscribed: [] }>() -const { subscribe, isActiveSubscription, fetchStatus } = useSubscription() +const { subscribe, isSubscribedOrIsNotCloud, fetchStatus } = useSubscription() const telemetry = useTelemetry() const isLoading = ref(false) @@ -76,7 +76,7 @@ const startPollingSubscriptionStatus = () => { await fetchStatus() - if (isActiveSubscription.value) { + if (isSubscribedOrIsNotCloud.value) { stopPolling() telemetry?.trackMonthlySubscriptionSucceeded() emit('subscribed') diff --git a/src/platform/cloud/subscription/components/SubscriptionPanel.vue b/src/platform/cloud/subscription/components/SubscriptionPanel.vue index 29f5a8ae2..7b78cf7d2 100644 --- a/src/platform/cloud/subscription/components/SubscriptionPanel.vue +++ b/src/platform/cloud/subscription/components/SubscriptionPanel.vue @@ -4,7 +4,7 @@ {{ - isActiveSubscription + isSubscribedOrIsNotCloud ? $t('subscription.title') : $t('subscription.titleUnsubscribed') }} @@ -27,7 +27,7 @@ }} @@ -47,7 +47,7 @@ Promise - isActiveSubscription: ComputedRef + isSubscribedOrIsNotCloud: ComputedRef subscriptionStatus: Ref telemetry: Pick | null shouldWatchCancellation: () => boolean @@ -20,7 +20,7 @@ type CancellationWatcherOptions = { export function useSubscriptionCancellationWatcher({ fetchStatus, - isActiveSubscription, + isSubscribedOrIsNotCloud, subscriptionStatus, telemetry, shouldWatchCancellation @@ -73,7 +73,7 @@ export function useSubscriptionCancellationWatcher({ try { await fetchStatus() - if (!isActiveSubscription.value) { + if (!isSubscribedOrIsNotCloud.value) { if (!cancellationTracked.value) { cancellationTracked.value = true try { diff --git a/src/scripts/app.ts b/src/scripts/app.ts index 9c152d4be..9eea41a67 100644 --- a/src/scripts/app.ts +++ b/src/scripts/app.ts @@ -676,11 +676,17 @@ export class ComfyApp { 'Payment Required: Please add credits to your account to use this node.' ) ) { - const { isActiveSubscription } = useSubscription() - if (isActiveSubscription.value) { + if (!isCloud) { useDialogService().showTopUpCreditsDialog({ isInsufficientCredits: true }) + } else { + const { isSubscribedOrIsNotCloud } = useSubscription() + if (isSubscribedOrIsNotCloud.value) { + useDialogService().showTopUpCreditsDialog({ + isInsufficientCredits: true + }) + } } } else { useDialogService().showExecutionErrorDialog(detail) diff --git a/src/services/dialogService.ts b/src/services/dialogService.ts index 13e7eebf6..eb60c4cee 100644 --- a/src/services/dialogService.ts +++ b/src/services/dialogService.ts @@ -380,8 +380,10 @@ export const useDialogService = () => { function showTopUpCreditsDialog(options?: { isInsufficientCredits?: boolean }) { - const { isActiveSubscription } = useSubscription() - if (!isActiveSubscription.value) return + if (isCloud) { + const { isSubscribedOrIsNotCloud } = useSubscription() + if (!isSubscribedOrIsNotCloud.value) return + } return dialogStore.showDialog({ key: 'top-up-credits', diff --git a/tests-ui/tests/composables/useCoreCommands.test.ts b/tests-ui/tests/composables/useCoreCommands.test.ts index 6ab5d58db..1c8f0c107 100644 --- a/tests-ui/tests/composables/useCoreCommands.test.ts +++ b/tests-ui/tests/composables/useCoreCommands.test.ts @@ -100,7 +100,7 @@ vi.mock('@/composables/auth/useFirebaseAuthActions', () => ({ vi.mock('@/platform/cloud/subscription/composables/useSubscription', () => ({ useSubscription: vi.fn(() => ({ - isActiveSubscription: vi.fn().mockReturnValue(true), + isSubscribedOrIsNotCloud: vi.fn().mockReturnValue(true), showSubscriptionDialog: vi.fn() })) })) diff --git a/tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts b/tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts index b7bff37a5..d5d4e9571 100644 --- a/tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts +++ b/tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts @@ -7,7 +7,7 @@ import SubscriptionPanel from '@/platform/cloud/subscription/components/Subscrip // Mock composables const mockSubscriptionData = { - isActiveSubscription: false, + isSubscribedOrIsNotCloud: false, isCancelled: false, formattedRenewalDate: '2024-12-31', formattedEndDate: '2024-12-31', @@ -120,14 +120,14 @@ describe('SubscriptionPanel', () => { describe('subscription state functionality', () => { it('shows correct UI for active subscription', () => { - mockSubscriptionData.isActiveSubscription = true + mockSubscriptionData.isSubscribedOrIsNotCloud = true const wrapper = createWrapper() expect(wrapper.text()).toContain('Manage Subscription') expect(wrapper.text()).toContain('Add Credits') }) it('shows correct UI for inactive subscription', () => { - mockSubscriptionData.isActiveSubscription = false + mockSubscriptionData.isSubscribedOrIsNotCloud = false const wrapper = createWrapper() expect(wrapper.findComponent({ name: 'SubscribeButton' }).exists()).toBe( true @@ -137,14 +137,14 @@ describe('SubscriptionPanel', () => { }) it('shows renewal date for active non-cancelled subscription', () => { - mockSubscriptionData.isActiveSubscription = true + mockSubscriptionData.isSubscribedOrIsNotCloud = true mockSubscriptionData.isCancelled = false const wrapper = createWrapper() expect(wrapper.text()).toContain('Renews 2024-12-31') }) it('shows expiry date for cancelled subscription', () => { - mockSubscriptionData.isActiveSubscription = true + mockSubscriptionData.isSubscribedOrIsNotCloud = true mockSubscriptionData.isCancelled = true const wrapper = createWrapper() expect(wrapper.text()).toContain('Expires 2024-12-31') diff --git a/tests-ui/tests/platform/cloud/subscription/useSubscription.test.ts b/tests-ui/tests/platform/cloud/subscription/useSubscription.test.ts index 1305e9f15..5986b2546 100644 --- a/tests-ui/tests/platform/cloud/subscription/useSubscription.test.ts +++ b/tests-ui/tests/platform/cloud/subscription/useSubscription.test.ts @@ -92,7 +92,7 @@ describe('useSubscription', () => { }) describe('computed properties', () => { - it('should compute isActiveSubscription correctly when subscription is active', async () => { + it('should compute isSubscribedOrIsNotCloud correctly when subscription is active', async () => { vi.mocked(global.fetch).mockResolvedValue({ ok: true, json: async () => ({ @@ -103,13 +103,13 @@ describe('useSubscription', () => { } as Response) mockIsLoggedIn.value = true - const { isActiveSubscription, fetchStatus } = useSubscription() + const { isSubscribedOrIsNotCloud, fetchStatus } = useSubscription() await fetchStatus() - expect(isActiveSubscription.value).toBe(true) + expect(isSubscribedOrIsNotCloud.value).toBe(true) }) - it('should compute isActiveSubscription as false when subscription is inactive', async () => { + it('should compute isSubscribedOrIsNotCloud as false when subscription is inactive', async () => { vi.mocked(global.fetch).mockResolvedValue({ ok: true, json: async () => ({ @@ -120,10 +120,10 @@ describe('useSubscription', () => { } as Response) mockIsLoggedIn.value = true - const { isActiveSubscription, fetchStatus } = useSubscription() + const { isSubscribedOrIsNotCloud, fetchStatus } = useSubscription() await fetchStatus() - expect(isActiveSubscription.value).toBe(false) + expect(isSubscribedOrIsNotCloud.value).toBe(false) }) it('should format renewal date correctly', async () => { diff --git a/tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.ts b/tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.ts index 94db27549..82b130fd7 100644 --- a/tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.ts +++ b/tests-ui/tests/platform/cloud/subscription/useSubscriptionCancellationWatcher.test.ts @@ -24,7 +24,7 @@ describe('useSubscriptionCancellationWatcher', () => { baseStatus ) const isActive = ref(true) - const isActiveSubscription = computed(() => isActive.value) + const isSubscribedOrIsNotCloud = computed(() => isActive.value) let shouldWatch = true const shouldWatchCancellation = () => shouldWatch @@ -76,7 +76,7 @@ describe('useSubscriptionCancellationWatcher', () => { const { startCancellationWatcher } = initWatcher({ fetchStatus, - isActiveSubscription, + isSubscribedOrIsNotCloud, subscriptionStatus, telemetry: telemetryMock, shouldWatchCancellation @@ -106,7 +106,7 @@ describe('useSubscriptionCancellationWatcher', () => { const { startCancellationWatcher } = initWatcher({ fetchStatus, - isActiveSubscription, + isSubscribedOrIsNotCloud, subscriptionStatus, telemetry: telemetryMock, shouldWatchCancellation @@ -128,7 +128,7 @@ describe('useSubscriptionCancellationWatcher', () => { const { startCancellationWatcher } = initWatcher({ fetchStatus, - isActiveSubscription, + isSubscribedOrIsNotCloud, subscriptionStatus, telemetry: telemetryMock, shouldWatchCancellation @@ -153,7 +153,7 @@ describe('useSubscriptionCancellationWatcher', () => { const { startCancellationWatcher } = initWatcher({ fetchStatus, - isActiveSubscription, + isSubscribedOrIsNotCloud, subscriptionStatus, telemetry: telemetryMock, shouldWatchCancellation