Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/composables/useFeatureFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export enum ServerFeatureFlag {
MAX_UPLOAD_SIZE = 'max_upload_size',
MANAGER_SUPPORTS_V4 = 'extension.manager.supports_v4',
MODEL_UPLOAD_BUTTON_ENABLED = 'model_upload_button_enabled',
ASSET_UPDATE_OPTIONS_ENABLED = 'asset_update_options_enabled'
ASSET_UPDATE_OPTIONS_ENABLED = 'asset_update_options_enabled',
PRIVATE_MODELS_ENABLED = 'private_models_enabled'
}

/**
Expand Down Expand Up @@ -47,6 +48,13 @@ export function useFeatureFlags() {
false
)
)
},
get privateModelsEnabled() {
// Check remote config first (from /api/features), fall back to websocket feature flags
return (
remoteConfig.value.private_models_enabled ??
api.getServerFeature(ServerFeatureFlag.PRIVATE_MODELS_ENABLED, false)
)
}
})

Expand Down
2 changes: 2 additions & 0 deletions src/locales/en/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -2121,6 +2121,8 @@
"modelUploaded": "Model imported! 🎉",
"findInLibrary": "Find it in the {type} section of the models library.",
"finish": "Finish",
"upgradeToUnlockFeature": "Upgrade to unlock this feature",
"upgradeFeatureDescription": "This feature is only available with Creator or Pro plans.",
"allModels": "All Models",
"allCategory": "All {category}",
"unknown": "Unknown",
Expand Down
30 changes: 30 additions & 0 deletions src/platform/assets/components/UploadModelUpgradeModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<template>
<div
class="flex flex-col justify-between gap-10 p-4 border-t border-border-default w-auto max-w-[min(500px,90vw)]"
>
<UploadModelUpgradeModalBody />

<UploadModelUpgradeModalFooter
@close="handleClose"
@subscribe="handleSubscribe"
/>
</div>
</template>

<script setup lang="ts">
import UploadModelUpgradeModalBody from '@/platform/assets/components/UploadModelUpgradeModalBody.vue'
import UploadModelUpgradeModalFooter from '@/platform/assets/components/UploadModelUpgradeModalFooter.vue'
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
import { useDialogStore } from '@/stores/dialogStore'

const dialogStore = useDialogStore()
const { showSubscriptionDialog } = useSubscription()

function handleClose() {
dialogStore.closeDialog({ key: 'upload-model-upgrade' })
}

function handleSubscribe() {
showSubscriptionDialog()
}
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<template>
<div
class="flex flex-1 flex-col items-center justify-center text-base text-muted-foreground"
>
<p class="m-0 max-w-md">
{{ $t('assetBrowser.upgradeFeatureDescription') }}
</p>
</div>
</template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<template>
<div class="flex flex-wrap justify-end gap-2 w-full">
<a
href="https://blog.comfy.org/p/comfy-cloud-new-features-and-pricing"
target="_blank"
rel="noopener noreferrer"
class="text-muted-foreground mr-auto underline flex items-center gap-2"
>
<i class="icon-[lucide--external-link]" />
<span>{{ $t('g.learnMore') }}</span>
</a>
<TextButton
:label="$t('g.close')"
type="transparent"
size="md"
@click="emit('close')"
/>
<TextButton
:label="$t('subscription.required.subscribe')"
type="secondary"
size="md"
@click="emit('subscribe')"
/>
</div>
</template>

<script setup lang="ts">
import TextButton from '@/components/button/TextButton.vue'

const emit = defineEmits<{
close: []
subscribe: []
}>()
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<template>
<div class="flex items-center gap-2 p-4 font-bold">
<span>{{ $t('assetBrowser.upgradeToUnlockFeature') }}</span>
</div>
</template>
46 changes: 32 additions & 14 deletions src/platform/assets/composables/useModelUpload.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { useFeatureFlags } from '@/composables/useFeatureFlags'
import UploadModelDialog from '@/platform/assets/components/UploadModelDialog.vue'
import UploadModelDialogHeader from '@/platform/assets/components/UploadModelDialogHeader.vue'
import UploadModelUpgradeModal from '@/platform/assets/components/UploadModelUpgradeModal.vue'
import UploadModelUpgradeModalHeader from '@/platform/assets/components/UploadModelUpgradeModalHeader.vue'
import type { AssetItem } from '@/platform/assets/schemas/assetSchema'
import { useDialogStore } from '@/stores/dialogStore'
import type { UseAsyncStateReturn } from '@vueuse/core'
Expand All @@ -14,22 +16,38 @@ export function useModelUpload(
const isUploadButtonEnabled = computed(() => flags.modelUploadButtonEnabled)

function showUploadDialog() {
dialogStore.showDialog({
key: 'upload-model',
headerComponent: UploadModelDialogHeader,
component: UploadModelDialog,
props: {
onUploadSuccess: async () => {
await execute?.()
if (!flags.privateModelsEnabled) {
// Show upgrade modal if private models are disabled
dialogStore.showDialog({
key: 'upload-model-upgrade',
headerComponent: UploadModelUpgradeModalHeader,
component: UploadModelUpgradeModal,
dialogComponentProps: {
pt: {
header: 'py-0! pl-0!',
content: 'p-0!'
}
}
},
dialogComponentProps: {
pt: {
header: 'py-0! pl-0!',
content: 'p-0!'
})
} else {
// Show regular upload modal
dialogStore.showDialog({
key: 'upload-model',
headerComponent: UploadModelDialogHeader,
component: UploadModelDialog,
props: {
onUploadSuccess: async () => {
await execute?.()
}
},
dialogComponentProps: {
pt: {
header: 'py-0! pl-0!',
content: 'p-0!'
}
}
}
})
})
}
}
return { isUploadButtonEnabled, showUploadDialog }
}
1 change: 1 addition & 0 deletions src/platform/remoteConfig/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ export type RemoteConfig = {
telemetry_disabled_events?: TelemetryEventName[]
model_upload_button_enabled?: boolean
asset_update_options_enabled?: boolean
private_models_enabled?: boolean
}
Loading