Skip to content

Commit ba19c69

Browse files
committed
Make the entire banner clickable! Don't show expanded panel of info
1 parent 1cb0939 commit ba19c69

File tree

1 file changed

+79
-65
lines changed

1 file changed

+79
-65
lines changed

cli/src/components/ad-banner.tsx

Lines changed: 79 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { TextAttributes } from '@opentui/core'
22
import open from 'open'
3-
import React, { useCallback, useState } from 'react'
3+
import React, { useState } from 'react'
44

55
import { Button } from './button'
6+
import { Clickable } from './clickable'
67
import { useTerminalDimensions } from '../hooks/use-terminal-dimensions'
78
import { useTheme } from '../hooks/use-theme'
89
import { IS_FREEBUFF } from '../utils/constants'
@@ -34,14 +35,6 @@ export const AdBanner: React.FC<AdBannerProps> = ({ ad, onDisableAds, isFreeMode
3435
const [isHideHovered, setIsHideHovered] = useState(false)
3536
const [isCloseHovered, setIsCloseHovered] = useState(false)
3637

37-
const handleClick = useCallback(() => {
38-
if (ad.clickUrl) {
39-
open(ad.clickUrl).catch((err) => {
40-
logger.error(err, 'Failed to open ad link')
41-
})
42-
}
43-
}, [ad.clickUrl])
44-
4538
// Use 'url' field for display domain (the actual destination)
4639
const domain = extractDomain(ad.url)
4740
// Use cta field for button text, with title as fallback
@@ -51,6 +44,17 @@ export const AdBanner: React.FC<AdBannerProps> = ({ ad, onDisableAds, isFreeMode
5144
// Account for: padding (2), "Ad ?" label with space (5)
5245
const maxTextWidth = separatorWidth - 7
5346

47+
// Wrapper for hover detection - makes entire ad content clickable
48+
const handleAdMouseOver = () => setIsLinkHovered(true)
49+
const handleAdMouseOut = () => setIsLinkHovered(false)
50+
const handleAdClick = () => {
51+
if (ad.clickUrl) {
52+
open(ad.clickUrl).catch((err) => {
53+
logger.error(err, 'Failed to open ad link')
54+
})
55+
}
56+
}
57+
5458
return (
5559
<box
5660
style={{
@@ -60,59 +64,75 @@ export const AdBanner: React.FC<AdBannerProps> = ({ ad, onDisableAds, isFreeMode
6064
>
6165
{/* Horizontal divider line */}
6266
<text style={{ fg: theme.muted }}>{'─'.repeat(terminalWidth)}</text>
63-
{/* Top line: ad text + Ad label */}
64-
<box
67+
{/* Clickable ad content area - wrapped in Button for click detection */}
68+
<Button
69+
onClick={handleAdClick}
70+
onMouseOver={handleAdMouseOver}
71+
onMouseOut={handleAdMouseOut}
6572
style={{
6673
width: '100%',
67-
paddingLeft: 1,
68-
paddingRight: 1,
69-
flexDirection: 'row',
70-
justifyContent: 'space-between',
71-
alignItems: 'flex-start',
74+
flexDirection: 'column',
7275
}}
7376
>
74-
<text
77+
{/* Top line: ad text + Ad label */}
78+
<box
7579
style={{
76-
fg: theme.foreground,
77-
flexShrink: 1,
78-
maxWidth: maxTextWidth,
80+
width: '100%',
81+
paddingLeft: 1,
82+
paddingRight: 1,
83+
flexDirection: 'row',
84+
justifyContent: 'space-between',
85+
alignItems: 'flex-start',
7986
}}
80-
>
81-
{ad.adText}
82-
</text>
83-
<Button
84-
onClick={() => setShowInfoPanel(true)}
85-
onMouseOver={() => setIsAdLabelHovered(true)}
86-
onMouseOut={() => setIsAdLabelHovered(false)}
8787
>
8888
<text
8989
style={{
90-
fg: isAdLabelHovered && !showInfoPanel ? theme.foreground : theme.muted,
91-
flexShrink: 0,
90+
fg: theme.foreground,
91+
flexShrink: 1,
92+
maxWidth: maxTextWidth,
9293
}}
9394
>
94-
{isAdLabelHovered && !showInfoPanel ? 'Ad ?' : ' Ad'}
95+
{ad.adText}
9596
</text>
96-
</Button>
97-
</box>
98-
{/* Bottom line: button, domain, credits */}
99-
<box
100-
style={{
101-
width: '100%',
102-
paddingLeft: 1,
103-
paddingRight: 1,
104-
flexDirection: 'row',
105-
flexWrap: 'wrap',
106-
columnGap: 2,
107-
alignItems: 'center',
108-
}}
109-
>
110-
{ctaText && (
111-
<Button
112-
onClick={handleClick}
113-
onMouseOver={() => setIsLinkHovered(true)}
114-
onMouseOut={() => setIsLinkHovered(false)}
115-
>
97+
{!IS_FREEBUFF ? (
98+
<Clickable
99+
onMouseDown={() => setShowInfoPanel(true)}
100+
onMouseOver={() => setIsAdLabelHovered(true)}
101+
onMouseOut={() => setIsAdLabelHovered(false)}
102+
>
103+
<text
104+
style={{
105+
fg: isAdLabelHovered && !showInfoPanel ? theme.foreground : theme.muted,
106+
flexShrink: 0,
107+
}}
108+
>
109+
{isAdLabelHovered && !showInfoPanel ? 'Ad ?' : ' Ad'}
110+
</text>
111+
</Clickable>
112+
) : (
113+
<text
114+
style={{
115+
fg: theme.muted,
116+
flexShrink: 0,
117+
}}
118+
>
119+
{' Ad'}
120+
</text>
121+
)}
122+
</box>
123+
{/* Bottom line: button, domain, credits */}
124+
<box
125+
style={{
126+
width: '100%',
127+
paddingLeft: 1,
128+
paddingRight: 1,
129+
flexDirection: 'row',
130+
flexWrap: 'wrap',
131+
columnGap: 2,
132+
alignItems: 'center',
133+
}}
134+
>
135+
{ctaText && (
116136
<text
117137
style={{
118138
fg: theme.name === 'light' ? '#ffffff' : theme.background,
@@ -122,14 +142,8 @@ export const AdBanner: React.FC<AdBannerProps> = ({ ad, onDisableAds, isFreeMode
122142
>
123143
{` ${ctaText} `}
124144
</text>
125-
</Button>
126-
)}
127-
{domain && (
128-
<Button
129-
onClick={handleClick}
130-
onMouseOver={() => setIsLinkHovered(true)}
131-
onMouseOut={() => setIsLinkHovered(false)}
132-
>
145+
)}
146+
{domain && (
133147
<text
134148
style={{
135149
fg: theme.muted,
@@ -138,13 +152,13 @@ export const AdBanner: React.FC<AdBannerProps> = ({ ad, onDisableAds, isFreeMode
138152
>
139153
{domain}
140154
</text>
141-
</Button>
142-
)}
143-
<box style={{ flexGrow: 1 }} />
144-
{!IS_FREEBUFF && ad.credits != null && ad.credits > 0 && (
145-
<text style={{ fg: theme.muted }}>+{ad.credits} credits</text>
146-
)}
147-
</box>
155+
)}
156+
<box style={{ flexGrow: 1 }} />
157+
{!IS_FREEBUFF && ad.credits != null && ad.credits > 0 && (
158+
<text style={{ fg: theme.muted }}>+{ad.credits} credits</text>
159+
)}
160+
</box>
161+
</Button>
148162
{/* Info panel: shown when Ad label is clicked, below the ad */}
149163
{showInfoPanel && (
150164
<box

0 commit comments

Comments
 (0)