Skip to content

Commit 5fce596

Browse files
committed
Disable ads when you have a subscription
1 parent e8efaff commit 5fce596

File tree

3 files changed

+25
-13
lines changed

3 files changed

+25
-13
lines changed

cli/src/chat.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -162,19 +162,21 @@ export const Chat = ({
162162
} = useChatState()
163163

164164
const { statusMessage } = useClipboard()
165-
const { ad } = useGravityAd()
165+
166+
// Fetch subscription data early - needed for session credits tracking and ad gating
167+
const { data: subscriptionData } = useSubscriptionQuery({
168+
refetchInterval: 60 * 1000,
169+
})
170+
const hasSubscription = subscriptionData?.hasSubscription ?? false
171+
172+
const { ad } = useGravityAd({ enabled: !hasSubscription })
166173
const [adsManuallyDisabled, setAdsManuallyDisabled] = useState(false)
167174

168175
const handleDisableAds = useCallback(() => {
169176
handleAdsDisable()
170177
setAdsManuallyDisabled(true)
171178
}, [])
172179

173-
// Fetch subscription data early - needed for session credits tracking
174-
const { data: subscriptionData } = useSubscriptionQuery({
175-
refetchInterval: 60 * 1000,
176-
})
177-
178180
// Set initial mode from CLI flag on mount
179181
useEffect(() => {
180182
if (initialMode) {
@@ -221,16 +223,17 @@ export const Chat = ({
221223
const loadedSkills = useMemo(() => getLoadedSkills(), [])
222224

223225
// Filter slash commands based on current ads state - only show the option that changes state
226+
// Hide both ads commands entirely for subscribers
224227
// Also merge in skill commands
225228
const filteredSlashCommands = useMemo(() => {
226229
const adsEnabled = getAdsEnabled()
227230
const allCommands = getSlashCommandsWithSkills(loadedSkills)
228231
return allCommands.filter((cmd) => {
229-
if (cmd.id === 'ads:enable') return !adsEnabled
230-
if (cmd.id === 'ads:disable') return adsEnabled
232+
if (cmd.id === 'ads:enable') return !hasSubscription && !adsEnabled
233+
if (cmd.id === 'ads:disable') return !hasSubscription && adsEnabled
231234
return true
232235
})
233-
}, [inputValue, loadedSkills]) // Re-evaluate when input changes (user may have just toggled)
236+
}, [inputValue, loadedSkills, hasSubscription]) // Re-evaluate when input changes (user may have just toggled)
234237

235238
const {
236239
slashContext,

cli/src/components/help-banner.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react'
22

33
import { BottomBanner } from './bottom-banner'
4+
import { useSubscriptionQuery } from '../hooks/use-subscription-query'
45
import { useTheme } from '../hooks/use-theme'
56
import { useChatStore } from '../state/chat-store'
67

@@ -33,6 +34,8 @@ const Shortcut = ({
3334
export const HelpBanner = () => {
3435
const setInputMode = useChatStore((state) => state.setInputMode)
3536
const theme = useTheme()
37+
const { data: subscriptionData } = useSubscriptionQuery()
38+
const hasSubscription = subscriptionData?.hasSubscription ?? false
3639

3740
// Auto-hide after timeout
3841
React.useEffect(() => {
@@ -80,8 +83,12 @@ export const HelpBanner = () => {
8083
<text style={{ fg: theme.foreground }}>/subscribe</text>
8184
<text style={{ fg: theme.muted }}>·</text>
8285
<text style={{ fg: theme.foreground }}>/usage</text>
83-
<text style={{ fg: theme.muted }}>·</text>
84-
<text style={{ fg: theme.foreground }}>/ads:enable</text>
86+
{!hasSubscription && (
87+
<>
88+
<text style={{ fg: theme.muted }}>·</text>
89+
<text style={{ fg: theme.foreground }}>/ads:enable</text>
90+
</>
91+
)}
8592
</box>
8693
<text style={{ fg: theme.muted }}>
8794
Subscribe for the best credit rates — /subscribe

cli/src/hooks/use-gravity-ad.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ function nextFromCache(ctrl: GravityController): AdResponse | null {
6868
*
6969
* Activity is tracked via the global activity-tracker module.
7070
*/
71-
export const useGravityAd = (): GravityAdState => {
71+
export const useGravityAd = (options?: { enabled?: boolean }): GravityAdState => {
72+
const enabled = options?.enabled ?? true
7273
const [ad, setAd] = useState<AdResponse | null>(null)
7374
const [isLoading, setIsLoading] = useState(false)
7475

@@ -81,7 +82,8 @@ export const useGravityAd = (): GravityAdState => {
8182
const isFreeMode = agentMode === 'FREE'
8283

8384
// Skip ads on very compact screens unless in FREE mode (where ads are mandatory)
84-
const shouldHideAds = isVeryCompactHeight && !isFreeMode
85+
// Also skip if explicitly disabled (e.g. user has a subscription)
86+
const shouldHideAds = !enabled || (isVeryCompactHeight && !isFreeMode)
8587

8688
// Use Zustand selector instead of manual subscription - only rerenders when value changes
8789
const hasUserMessaged = useChatStore((s) =>

0 commit comments

Comments
 (0)