Skip to content

Commit 951b1ac

Browse files
authored
Add enableAi config to control Duck.ai visibility (#1790)
1 parent a6e8c22 commit 951b1ac

File tree

8 files changed

+73
-50
lines changed

8 files changed

+73
-50
lines changed

special-pages/pages/new-tab/app/omnibar/components/Omnibar.js

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,46 +16,53 @@ import { SearchForm } from './SearchForm';
1616
* @param {object} props
1717
* @param {OmnibarConfig['mode']} props.mode
1818
* @param {(mode: OmnibarConfig['mode']) => void} props.setMode
19+
* @param {boolean} props.enableAi
1920
*/
20-
export function Omnibar({ mode, setMode }) {
21+
export function Omnibar({ mode, setMode, enableAi }) {
2122
const { t } = useTypedTranslationWith(/** @type {Strings} */ ({}));
2223
const [query, setQuery] = useState(/** @type {String} */ (''));
2324
return (
2425
<div class={styles.root} data-mode={mode}>
2526
<div class={styles.logoWrap}>
2627
<img src="./icons/Logo-Stacked.svg" alt={t('omnibar_logoAlt')} width={144} height={115.9} />
2728
</div>
28-
<div class={styles.tabListWrap}>
29-
<div class={styles.tabList} role="tablist" aria-label={t('omnibar_tabSwitcherLabel')}>
30-
<button
31-
class={styles.tab}
32-
role="tab"
33-
aria-selected={mode === 'search'}
34-
onClick={() => {
35-
viewTransition(() => {
36-
setMode('search');
37-
});
38-
}}
39-
>
40-
<SearchIcon className={styles.searchIcon} />
41-
{t('omnibar_searchTabLabel')}
42-
</button>
43-
<button
44-
class={styles.tab}
45-
role="tab"
46-
aria-selected={mode === 'ai'}
47-
onClick={() => {
48-
viewTransition(() => {
49-
setMode('ai');
50-
});
51-
}}
52-
>
53-
<AiChatIcon className={styles.aiChatIcon} />
54-
{t('omnibar_aiTabLabel')}
55-
</button>
29+
{enableAi && (
30+
<div class={styles.tabListWrap}>
31+
<div class={styles.tabList} role="tablist" aria-label={t('omnibar_tabSwitcherLabel')}>
32+
<button
33+
class={styles.tab}
34+
role="tab"
35+
aria-selected={mode === 'search'}
36+
onClick={() => {
37+
viewTransition(() => {
38+
setMode('search');
39+
});
40+
}}
41+
>
42+
<SearchIcon className={styles.searchIcon} />
43+
{t('omnibar_searchTabLabel')}
44+
</button>
45+
<button
46+
class={styles.tab}
47+
role="tab"
48+
aria-selected={mode === 'ai'}
49+
onClick={() => {
50+
viewTransition(() => {
51+
setMode('ai');
52+
});
53+
}}
54+
>
55+
<AiChatIcon className={styles.aiChatIcon} />
56+
{t('omnibar_aiTabLabel')}
57+
</button>
58+
</div>
5659
</div>
57-
</div>
58-
{mode === 'search' ? <SearchForm term={query} setTerm={setQuery} /> : <AiChatForm chat={query} setChat={setQuery} />}
60+
)}
61+
{mode === 'search' ? (
62+
<SearchForm enableAi={enableAi} term={query} setTerm={setQuery} />
63+
) : (
64+
<AiChatForm chat={query} setChat={setQuery} />
65+
)}
5966
</div>
6067
);
6168
}

special-pages/pages/new-tab/app/omnibar/components/OmnibarConsumer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,5 @@ export function OmnibarConsumer() {
3333
*/
3434
function OmnibarReadyState({ config }) {
3535
const { setMode } = useContext(OmnibarContext);
36-
return <Omnibar mode={config.mode} setMode={setMode} />;
36+
return <Omnibar mode={config.mode} setMode={setMode} enableAi={config.enableAi ?? true} />;
3737
}

special-pages/pages/new-tab/app/omnibar/components/SearchForm.js

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import cn from 'classnames';
2-
import { h } from 'preact';
2+
import { Fragment, h } from 'preact';
33
import { useContext } from 'preact/hooks';
44
import { eventToTarget } from '../../../../../shared/handlers';
55
import { AiChatIcon, SearchIcon } from '../../components/Icons.js';
@@ -17,10 +17,11 @@ import { useSuggestions } from './useSuggestions';
1717

1818
/**
1919
* @param {object} props
20+
* @param {boolean} props.enableAi
2021
* @param {string} props.term
2122
* @param {(term: string) => void} props.setTerm
2223
*/
23-
export function SearchForm({ term, setTerm }) {
24+
export function SearchForm({ enableAi, term, setTerm }) {
2425
const { submitSearch, submitChat } = useContext(OmnibarContext);
2526

2627
const { t } = useTypedTranslationWith(/** @type {Strings} */ ({}));
@@ -80,20 +81,24 @@ export function SearchForm({ term, setTerm }) {
8081
<button type="submit" class={cn(styles.inputAction)} aria-label={t('searchForm_searchButtonLabel')} inert>
8182
<SearchIcon />
8283
</button>
83-
<div class={styles.separator}></div>
84-
<button
85-
class={cn(styles.inputAction, styles.squareButton)}
86-
aria-label={t('searchForm_aiButtonLabel')}
87-
onClick={(event) => {
88-
event.preventDefault();
89-
submitChat({
90-
chat: term,
91-
target: eventToTarget(event, platformName),
92-
});
93-
}}
94-
>
95-
<AiChatIcon className={styles.aiChatIcon} />
96-
</button>
84+
{enableAi && (
85+
<>
86+
<div class={styles.separator}></div>
87+
<button
88+
class={cn(styles.inputAction, styles.squareButton)}
89+
aria-label={t('searchForm_aiButtonLabel')}
90+
onClick={(event) => {
91+
event.preventDefault();
92+
submitChat({
93+
chat: term,
94+
target: eventToTarget(event, platformName),
95+
});
96+
}}
97+
>
98+
<AiChatIcon className={styles.aiChatIcon} />
99+
</button>
100+
</>
101+
)}
97102
</div>
98103
</div>
99104
</div>

special-pages/pages/new-tab/app/omnibar/mocks/omnibar.mock-transport.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ export function omnibarMockTransport() {
4646
if (modeOverride === 'search' || modeOverride === 'ai') {
4747
config.mode = modeOverride;
4848
}
49+
const enableAiOverride = url.searchParams.get('omnibar.enableAi');
50+
if (enableAiOverride === 'true' || enableAiOverride === 'false') {
51+
config.enableAi = enableAiOverride === 'true';
52+
}
4953
return config;
5054
}
5155
case 'omnibar_getSuggestions': {

special-pages/pages/new-tab/app/omnibar/strings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"omnibar_menuTitle": {
3-
"title": "Search & Duck.ai",
3+
"title": "Search",
44
"description": "Title of the omnibar widget in the customizer panel."
55
},
66
"aiChatForm_placeholder": {

special-pages/pages/new-tab/messages/types/omnibar-config.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
"title": "Omnibar Mode",
1111
"type": "string",
1212
"enum": ["search", "ai"]
13+
},
14+
"enableAi": {
15+
"title": "Enable Duck.ai",
16+
"type": "boolean",
17+
"default": true
1318
}
1419
}
1520
}

special-pages/pages/new-tab/public/locales/en/new-tab.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@
126126
"note": "An aggregated count of blocked entries not present in the main list. For example, '200 attempts from other networks'"
127127
},
128128
"omnibar_menuTitle": {
129-
"title": "Search & Duck.ai",
129+
"title": "Search",
130130
"description": "Title of the omnibar widget in the customizer panel."
131131
},
132132
"aiChatForm_placeholder": {

special-pages/pages/new-tab/types/new-tab.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ export type Suggestion =
6363
| HistoryEntrySuggestion
6464
| InternalPageSuggestion;
6565
export type OmnibarMode = "search" | "ai";
66+
export type EnableDuckAi = boolean;
6667
export type FeedType = "privacy-stats" | "activity";
6768
/**
6869
* The visibility state of the widget, as configured by the user
@@ -505,6 +506,7 @@ export interface OmnibarSetConfigNotification {
505506
}
506507
export interface OmnibarConfig {
507508
mode: OmnibarMode;
509+
enableAi?: EnableDuckAi;
508510
}
509511
/**
510512
* Generated from @see "../messages/omnibar_submitChat.notify.json"

0 commit comments

Comments
 (0)