@@ -66,91 +65,32 @@
@click="handleBuy"
/>
-
-
-
-
-
- {{ $t('credits.topUp.insufficientTitle') }}
-
-
- {{ $t('credits.topUp.insufficientMessage') }}
-
-
-
-
-
-
-
- {{ $t('credits.yourCreditBalance') }}
-
-
-
-
-
-
-
-
-
-
-
{{ $t('credits.topUp.quickPurchase') }}:
-
-
-
-
-
-
-
diff --git a/src/components/dialog/content/credit/LegacyCreditTopUpOption.vue b/src/components/dialog/content/credit/LegacyCreditTopUpOption.vue
deleted file mode 100644
index f33c3845b..000000000
--- a/src/components/dialog/content/credit/LegacyCreditTopUpOption.vue
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
-
-
- (customAmount = clampUsd(Number(e.value)))
- "
- @input="
- (e: InputNumberInputEvent) =>
- (customAmount = clampUsd(Number(e.value)))
- "
- />
- {{ formattedCredits }}
-
-
- {{ formattedCredits }}
- {{ formattedUsd }}
-
-
-
-
-
-
-
diff --git a/src/components/topbar/CurrentUserPopover.test.ts b/src/components/topbar/CurrentUserPopover.test.ts
index cb2efd7b7..72ef7a1ee 100644
--- a/src/components/topbar/CurrentUserPopover.test.ts
+++ b/src/components/topbar/CurrentUserPopover.test.ts
@@ -138,15 +138,6 @@ vi.mock('@/composables/useExternalLink', () => ({
}))
}))
-// Mock useFeatureFlags
-vi.mock('@/composables/useFeatureFlags', () => ({
- useFeatureFlags: vi.fn(() => ({
- flags: {
- subscriptionTiersEnabled: true
- }
- }))
-}))
-
// Mock useTelemetry
vi.mock('@/platform/telemetry', () => ({
useTelemetry: vi.fn(() => ({
diff --git a/src/components/topbar/CurrentUserPopover.vue b/src/components/topbar/CurrentUserPopover.vue
index f5a6f0610..5c500e570 100644
--- a/src/components/topbar/CurrentUserPopover.vue
+++ b/src/components/topbar/CurrentUserPopover.vue
@@ -42,7 +42,6 @@
formattedBalance
}}
@@ -147,7 +146,6 @@ import UserAvatar from '@/components/common/UserAvatar.vue'
import { useCurrentUser } from '@/composables/auth/useCurrentUser'
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
import { useExternalLink } from '@/composables/useExternalLink'
-import { useFeatureFlags } from '@/composables/useFeatureFlags'
import SubscribeButton from '@/platform/cloud/subscription/components/SubscribeButton.vue'
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
import { useSubscriptionDialog } from '@/platform/cloud/subscription/composables/useSubscriptionDialog'
@@ -174,7 +172,6 @@ const {
fetchStatus
} = useSubscription()
const subscriptionDialog = useSubscriptionDialog()
-const { flags } = useFeatureFlags()
const { locale } = useI18n()
const formattedBalance = computed(() => {
diff --git a/src/composables/node/usePriceBadge.ts b/src/composables/node/usePriceBadge.ts
index 26cecdfac..93f396a5a 100644
--- a/src/composables/node/usePriceBadge.ts
+++ b/src/composables/node/usePriceBadge.ts
@@ -1,7 +1,6 @@
import type { LGraph, LGraphNode } from '@/lib/litegraph/src/litegraph'
import { LGraphBadge } from '@/lib/litegraph/src/litegraph'
-import { useFeatureFlags } from '@/composables/useFeatureFlags'
import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore'
import { adjustColor } from '@/utils/colorUtil'
@@ -10,7 +9,6 @@ componentIconSvg.src =
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='oklch(83.01%25 0.163 83.16)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M15.536 11.293a1 1 0 0 0 0 1.414l2.376 2.377a1 1 0 0 0 1.414 0l2.377-2.377a1 1 0 0 0 0-1.414l-2.377-2.377a1 1 0 0 0-1.414 0zm-13.239 0a1 1 0 0 0 0 1.414l2.377 2.377a1 1 0 0 0 1.414 0l2.377-2.377a1 1 0 0 0 0-1.414L6.088 8.916a1 1 0 0 0-1.414 0zm6.619 6.619a1 1 0 0 0 0 1.415l2.377 2.376a1 1 0 0 0 1.414 0l2.377-2.376a1 1 0 0 0 0-1.415l-2.377-2.376a1 1 0 0 0-1.414 0zm0-13.238a1 1 0 0 0 0 1.414l2.377 2.376a1 1 0 0 0 1.414 0l2.377-2.376a1 1 0 0 0 0-1.414l-2.377-2.377a1 1 0 0 0-1.414 0z'/%3E%3C/svg%3E"
export const usePriceBadge = () => {
- const { flags } = useFeatureFlags()
function updateSubgraphCredits(node: LGraphNode) {
if (!node.isSubgraphNode()) return
node.badges = node.badges.filter((b) => !isCreditsBadge(b))
@@ -40,53 +38,26 @@ export const usePriceBadge = () => {
function isCreditsBadge(badge: LGraphBadge | (() => LGraphBadge)): boolean {
const badgeInstance = typeof badge === 'function' ? badge() : badge
- if (flags.subscriptionTiersEnabled) {
- return badgeInstance.icon?.image === componentIconSvg
- } else {
- return badgeInstance.icon?.unicode === '\ue96b'
- }
+ return badgeInstance.icon?.image === componentIconSvg
}
const colorPaletteStore = useColorPaletteStore()
function getCreditsBadge(price: string): LGraphBadge {
const isLightTheme = colorPaletteStore.completedActivePalette.light_theme
- if (flags.subscriptionTiersEnabled) {
- return new LGraphBadge({
- text: price,
- iconOptions: {
- image: componentIconSvg,
- size: 8
- },
- fgColor:
- colorPaletteStore.completedActivePalette.colors.litegraph_base
- .BADGE_FG_COLOR,
- bgColor: isLightTheme
- ? adjustColor('#8D6932', { lightness: 0.5 })
- : '#8D6932'
- })
- } else {
- return new LGraphBadge({
- text: price,
- iconOptions: {
- unicode: '\ue96b',
- fontFamily: 'PrimeIcons',
- color: isLightTheme
- ? adjustColor('#FABC25', { lightness: 0.5 })
- : '#FABC25',
- bgColor: isLightTheme
- ? adjustColor('#654020', { lightness: 0.5 })
- : '#654020',
- fontSize: 8
- },
- fgColor:
- colorPaletteStore.completedActivePalette.colors.litegraph_base
- .BADGE_FG_COLOR,
- bgColor: isLightTheme
- ? adjustColor('#8D6932', { lightness: 0.5 })
- : '#8D6932'
- })
- }
+ return new LGraphBadge({
+ text: price,
+ iconOptions: {
+ image: componentIconSvg,
+ size: 8
+ },
+ fgColor:
+ colorPaletteStore.completedActivePalette.colors.litegraph_base
+ .BADGE_FG_COLOR,
+ bgColor: isLightTheme
+ ? adjustColor('#8D6932', { lightness: 0.5 })
+ : '#8D6932'
+ })
}
return {
getCreditsBadge,
diff --git a/src/composables/useFeatureFlags.ts b/src/composables/useFeatureFlags.ts
index 07b82ff40..4f2e65abd 100644
--- a/src/composables/useFeatureFlags.ts
+++ b/src/composables/useFeatureFlags.ts
@@ -13,7 +13,6 @@ export enum ServerFeatureFlag {
MODEL_UPLOAD_BUTTON_ENABLED = 'model_upload_button_enabled',
ASSET_UPDATE_OPTIONS_ENABLED = 'asset_update_options_enabled',
PRIVATE_MODELS_ENABLED = 'private_models_enabled',
- SUBSCRIPTION_TIERS_ENABLED = 'subscription_tiers_enabled',
ONBOARDING_SURVEY_ENABLED = 'onboarding_survey_enabled'
}
@@ -58,16 +57,6 @@ export function useFeatureFlags() {
api.getServerFeature(ServerFeatureFlag.PRIVATE_MODELS_ENABLED, false)
)
},
- get subscriptionTiersEnabled() {
- // Check remote config first (from /api/features), fall back to websocket feature flags
- return (
- remoteConfig.value.subscription_tiers_enabled ??
- api.getServerFeature(
- ServerFeatureFlag.SUBSCRIPTION_TIERS_ENABLED,
- true // Default to true (new design)
- )
- )
- },
get onboardingSurveyEnabled() {
return (
remoteConfig.value.onboarding_survey_enabled ??
diff --git a/src/platform/cloud/subscription/components/SubscribeButton.vue b/src/platform/cloud/subscription/components/SubscribeButton.vue
index 670fb48b0..de3572a00 100644
--- a/src/platform/cloud/subscription/components/SubscribeButton.vue
+++ b/src/platform/cloud/subscription/components/SubscribeButton.vue
@@ -26,7 +26,6 @@
import Button from 'primevue/button'
import { computed, onBeforeUnmount, ref, watch } from 'vue'
-import { useFeatureFlags } from '@/composables/useFeatureFlags'
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
import { isCloud } from '@/platform/distribution/types'
import { useTelemetry } from '@/platform/telemetry'
@@ -54,10 +53,7 @@ const emit = defineEmits<{
const { subscribe, isActiveSubscription, fetchStatus, showSubscriptionDialog } =
useSubscription()
-const { flags } = useFeatureFlags()
-const shouldUseStripePricing = computed(
- () => isCloud && Boolean(flags.subscriptionTiersEnabled)
-)
+
const telemetry = useTelemetry()
const isLoading = ref(false)
@@ -112,7 +108,7 @@ const stopPolling = () => {
watch(
[isAwaitingStripeSubscription, isActiveSubscription],
([awaiting, isActive]) => {
- if (shouldUseStripePricing.value && awaiting && isActive) {
+ if (isCloud && awaiting && isActive) {
emit('subscribed')
isAwaitingStripeSubscription.value = false
}
@@ -122,9 +118,6 @@ watch(
const handleSubscribe = async () => {
if (isCloud) {
useTelemetry()?.trackSubscription('subscribe_clicked')
- }
-
- if (shouldUseStripePricing.value) {
isAwaitingStripeSubscription.value = true
showSubscriptionDialog()
return
diff --git a/src/platform/cloud/subscription/composables/useSubscription.ts b/src/platform/cloud/subscription/composables/useSubscription.ts
index 2647d35ff..77e889f13 100644
--- a/src/platform/cloud/subscription/composables/useSubscription.ts
+++ b/src/platform/cloud/subscription/composables/useSubscription.ts
@@ -16,9 +16,9 @@ import { useDialogService } from '@/services/dialogService'
import type { components, operations } from '@/types/comfyRegistryTypes'
import { useSubscriptionCancellationWatcher } from './useSubscriptionCancellationWatcher'
-type CloudSubscriptionCheckoutResponse = {
- checkout_url: string
-}
+type CloudSubscriptionCheckoutResponse = NonNullable<
+ operations['createCloudSubscriptionCheckout']['responses']['201']['content']['application/json']
+>
export type CloudSubscriptionStatusResponse = NonNullable<
operations['GetCloudSubscriptionStatus']['responses']['200']['content']['application/json']
diff --git a/src/platform/remoteConfig/types.ts b/src/platform/remoteConfig/types.ts
index e2660853b..1a4ef1261 100644
--- a/src/platform/remoteConfig/types.ts
+++ b/src/platform/remoteConfig/types.ts
@@ -37,6 +37,5 @@ export type RemoteConfig = {
model_upload_button_enabled?: boolean
asset_update_options_enabled?: boolean
private_models_enabled?: boolean
- subscription_tiers_enabled?: boolean
onboarding_survey_enabled?: boolean
}
diff --git a/src/platform/settings/composables/useSettingUI.ts b/src/platform/settings/composables/useSettingUI.ts
index 70ade08b2..79a54fba4 100644
--- a/src/platform/settings/composables/useSettingUI.ts
+++ b/src/platform/settings/composables/useSettingUI.ts
@@ -3,7 +3,6 @@ import type { Component } from 'vue'
import { useI18n } from 'vue-i18n'
import { useCurrentUser } from '@/composables/auth/useCurrentUser'
-import { useFeatureFlags } from '@/composables/useFeatureFlags'
import { isCloud } from '@/platform/distribution/types'
import type { SettingTreeNode } from '@/platform/settings/settingStore'
import { useSettingStore } from '@/platform/settings/settingStore'
@@ -36,7 +35,6 @@ export function useSettingUI(
const { shouldRenderVueNodes } = useVueFeatureFlags()
const { isActiveSubscription } = useSubscription()
- const { flags } = useFeatureFlags()
const settingRoot = computed
(() => {
const root = buildTree(
@@ -106,7 +104,6 @@ export function useSettingUI(
const shouldShowPlanCreditsPanel = computed(() => {
if (!subscriptionPanel) return false
- if (!flags.subscriptionTiersEnabled) return true
return isActiveSubscription.value
})
diff --git a/src/renderer/extensions/vueNodes/components/NodeHeader.vue b/src/renderer/extensions/vueNodes/components/NodeHeader.vue
index e767d2702..fe99c5d62 100644
--- a/src/renderer/extensions/vueNodes/components/NodeHeader.vue
+++ b/src/renderer/extensions/vueNodes/components/NodeHeader.vue
@@ -40,17 +40,7 @@
()
-const { flags } = useFeatureFlags()
-
// Error boundary implementation
const renderError = ref(null)
const { toastErrorHandler } = useErrorHandling()
diff --git a/tests-ui/tests/composables/node/useCreditsBadge.test.ts b/tests-ui/tests/composables/node/useCreditsBadge.test.ts
index 1725eb043..eb894566a 100644
--- a/tests-ui/tests/composables/node/useCreditsBadge.test.ts
+++ b/tests-ui/tests/composables/node/useCreditsBadge.test.ts
@@ -1,8 +1,6 @@
import { describe, expect, vi } from 'vitest'
import { LGraphNode } from '@/lib/litegraph/src/litegraph'
-import type { LGraphBadge } from '@/lib/litegraph/src/LGraphBadge'
-import type { LGraphIcon } from '@/lib/litegraph/src/LGraphIcon'
import { subgraphTest } from '../../litegraph/subgraph/fixtures/subgraphFixtures'
@@ -17,23 +15,10 @@ vi.mock('@/stores/workspace/colorPaletteStore', () => ({
})
}))
-vi.mock('@/composables/useFeatureFlags', () => ({
- useFeatureFlags: () => ({
- flags: {
- subscriptionTiersEnabled: false // Test legacy badge behavior
- }
- })
-}))
-
-const { updateSubgraphCredits } = usePriceBadge()
+const { updateSubgraphCredits, getCreditsBadge } = usePriceBadge()
const mockNode = new LGraphNode('mock node')
-const mockIcon: Partial = { unicode: '\ue96b' }
-const badge: Partial = {
- icon: mockIcon as LGraphIcon,
- text: '$0.05/Run'
-}
-mockNode.badges = [badge as LGraphBadge]
+mockNode.badges = [getCreditsBadge('$0.05/Run')]
function getBadgeText(node: LGraphNode): string {
const badge = node.badges[0]