@@ -2,6 +2,7 @@ import { Message, WEBSITE_URL } from '@codebuff/sdk'
22import { useEffect , useRef , useState } from 'react'
33
44import { getAdsEnabled } from '../commands/ads'
5+ import { useTerminalLayout } from './use-terminal-layout'
56import { useChatStore } from '../state/chat-store'
67import { isUserActive , subscribeToActivity } from '../utils/activity-tracker'
78import { getAuthToken } from '../utils/auth'
@@ -69,6 +70,17 @@ export const useGravityAd = (): GravityAdState => {
6970 const [ ad , setAd ] = useState < AdResponse | null > ( null )
7071 const [ isLoading , setIsLoading ] = useState ( false )
7172
73+ // Check if terminal height is too small to show ads
74+ const { terminalHeight } = useTerminalLayout ( )
75+ const isVeryCompactHeight = terminalHeight <= 17
76+
77+ // Get agent mode - FREE mode always shows ads even on compact screens
78+ const agentMode = useChatStore ( ( s ) => s . agentMode )
79+ const isFreeMode = agentMode === 'FREE'
80+
81+ // Skip ads on very compact screens unless in FREE mode (where ads are mandatory)
82+ const shouldHideAds = isVeryCompactHeight && ! isFreeMode
83+
7284 // Use Zustand selector instead of manual subscription - only rerenders when value changes
7385 const hasUserMessaged = useChatStore ( ( s ) =>
7486 s . messages . some ( ( m ) => m . variant === 'user' ) ,
@@ -87,8 +99,15 @@ export const useGravityAd = (): GravityAdState => {
8799 // Ref for the tick function (avoids useCallback dependency issues)
88100 const tickRef = useRef < ( ) => void > ( ( ) => { } )
89101
102+ // Ref to track whether ads should be hidden for use in async code
103+ const shouldHideAdsRef = useRef ( shouldHideAds )
104+ shouldHideAdsRef . current = shouldHideAds
105+
90106 // Fire impression and update credits (called when showing an ad)
91107 const recordImpressionOnce = ( impUrl : string ) : void => {
108+ // Don't record impressions when ads should be hidden
109+ if ( shouldHideAdsRef . current ) return
110+
92111 const ctrl = ctrlRef . current
93112 if ( ctrl . impressionsFired . has ( impUrl ) ) return
94113 ctrl . impressionsFired . add ( impUrl )
@@ -137,6 +156,8 @@ export const useGravityAd = (): GravityAdState => {
137156
138157 // Fetch an ad via web API
139158 const fetchAd = async ( ) : Promise < AdResponse | null > => {
159+ // Don't fetch ads when they should be hidden
160+ if ( shouldHideAdsRef . current ) return null
140161 if ( ! getAdsEnabled ( ) ) return null
141162
142163 const authToken = getAuthToken ( )
@@ -252,7 +273,7 @@ export const useGravityAd = (): GravityAdState => {
252273
253274 // Start rotation when user sends first message
254275 useEffect ( ( ) => {
255- if ( ! hasUserMessaged || ! getAdsEnabled ( ) ) return
276+ if ( ! hasUserMessaged || ! getAdsEnabled ( ) || shouldHideAds ) return
256277
257278 setIsLoading ( true )
258279
@@ -275,9 +296,10 @@ export const useGravityAd = (): GravityAdState => {
275296 clearInterval ( id )
276297 ctrlRef . current . intervalId = null
277298 }
278- } , [ hasUserMessaged ] )
299+ } , [ hasUserMessaged , shouldHideAds ] )
279300
280- return { ad : hasUserMessaged ? ad : null , isLoading }
301+ // Don't return ad when ads should be hidden
302+ return { ad : hasUserMessaged && ! shouldHideAds ? ad : null , isLoading }
281303}
282304
283305type AdMessage = { role : 'user' | 'assistant' ; content : string }
0 commit comments