From dbf699c5d23b23af896655f88b25ba753ff74bca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 14 Aug 2025 12:50:17 +0200 Subject: [PATCH 1/9] update icon, title, and copy in rebranded AI Features settings --- .../impl/ui/DuckChatSettingsActivity.kt | 5 ++ .../src/main/res/drawable/ic_ai_128.xml | 84 +++++++++++++++++++ .../main/res/values-bg/strings-duckchat.xml | 1 - .../main/res/values-cs/strings-duckchat.xml | 1 - .../main/res/values-da/strings-duckchat.xml | 1 - .../main/res/values-de/strings-duckchat.xml | 1 - .../main/res/values-el/strings-duckchat.xml | 1 - .../main/res/values-es/strings-duckchat.xml | 1 - .../main/res/values-et/strings-duckchat.xml | 1 - .../main/res/values-fi/strings-duckchat.xml | 1 - .../main/res/values-fr/strings-duckchat.xml | 1 - .../main/res/values-hr/strings-duckchat.xml | 1 - .../main/res/values-hu/strings-duckchat.xml | 1 - .../main/res/values-it/strings-duckchat.xml | 1 - .../main/res/values-lt/strings-duckchat.xml | 1 - .../main/res/values-lv/strings-duckchat.xml | 1 - .../main/res/values-nb/strings-duckchat.xml | 1 - .../main/res/values-nl/strings-duckchat.xml | 1 - .../main/res/values-pl/strings-duckchat.xml | 1 - .../main/res/values-pt/strings-duckchat.xml | 1 - .../main/res/values-ro/strings-duckchat.xml | 1 - .../main/res/values-ru/strings-duckchat.xml | 1 - .../main/res/values-sk/strings-duckchat.xml | 1 - .../main/res/values-sl/strings-duckchat.xml | 1 - .../main/res/values-sv/strings-duckchat.xml | 1 - .../main/res/values-tr/strings-duckchat.xml | 1 - .../src/main/res/values/strings-duckchat.xml | 2 +- 27 files changed, 90 insertions(+), 25 deletions(-) create mode 100644 duckchat/duckchat-impl/src/main/res/drawable/ic_ai_128.xml diff --git a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/DuckChatSettingsActivity.kt b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/DuckChatSettingsActivity.kt index 1a03b4843d30..74a76a8a213e 100644 --- a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/DuckChatSettingsActivity.kt +++ b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/DuckChatSettingsActivity.kt @@ -19,6 +19,7 @@ package com.duckduckgo.duckchat.impl.ui import android.os.Bundle import android.view.View import android.widget.CompoundButton +import androidx.core.content.ContextCompat import androidx.core.view.isVisible import androidx.lifecycle.Lifecycle import androidx.lifecycle.flowWithLifecycle @@ -107,6 +108,8 @@ class DuckChatSettingsActivity : DuckDuckGoActivity() { private fun renderViewState(viewState: ViewState) { if (viewState.isRebrandingAiFeaturesEnabled) { + binding.includeToolbar.toolbar.title = getString(R.string.duck_chat_title_rebranding) + binding.duckChatSettingsIcon.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_ai_128)) binding.userEnabledDuckChatToggleRebranding.quietlySetIsChecked(viewState.isDuckChatUserEnabled, userEnabledDuckChatToggleListener) binding.duckChatSettingsTitle.setText(R.string.duck_chat_title_rebranding) binding.userEnabledDuckChatToggle.gone() @@ -115,6 +118,8 @@ class DuckChatSettingsActivity : DuckDuckGoActivity() { binding.showDuckChatSearchSettingsLink.setPrimaryText(getString(R.string.duck_chat_assist_settings_title_rebranding)) binding.showDuckChatSearchSettingsLink.setSecondaryText(getString(R.string.duck_chat_assist_settings_description_rebranding)) } else { + binding.includeToolbar.toolbar.title = getString(R.string.duck_ai_paid_settings_title) + binding.duckChatSettingsIcon.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.chat_private_128)) binding.userEnabledDuckChatToggle.quietlySetIsChecked(viewState.isDuckChatUserEnabled, userEnabledDuckChatToggleListener) binding.duckChatSettingsTitle.setText(R.string.duck_chat_title) binding.userEnabledDuckChatToggle.show() diff --git a/duckchat/duckchat-impl/src/main/res/drawable/ic_ai_128.xml b/duckchat/duckchat-impl/src/main/res/drawable/ic_ai_128.xml new file mode 100644 index 000000000000..be9e62673d9f --- /dev/null +++ b/duckchat/duckchat-impl/src/main/res/drawable/ic_ai_128.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/duckchat/duckchat-impl/src/main/res/values-bg/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-bg/strings-duckchat.xml index c834b14ccb1b..1fa5ade74070 100644 --- a/duckchat/duckchat-impl/src/main/res/values-bg/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-bg/strings-duckchat.xml @@ -64,7 +64,6 @@ Функции с изкуствен интелект Функциите на DuckDuckGo AI са поверителни и незадължителни.Вашите данни не се използват за обучение на AI.\nНаучете повече Duck.ai - Анонимен чат с популярни AI модели на трети страни Преки пътища за Duck.ai Настройки за Assist при търсене Изберете колко често искате да се появяват отговори, подпомагани от изкуствен интелект, в търсенето diff --git a/duckchat/duckchat-impl/src/main/res/values-cs/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-cs/strings-duckchat.xml index 0c4e95df7165..9f1403dce8c0 100644 --- a/duckchat/duckchat-impl/src/main/res/values-cs/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-cs/strings-duckchat.xml @@ -64,7 +64,6 @@ Funkce AI Funkce AI na DuckDuckGo jsou soukromé a volitelné.Tvoje data se nepoužívají k trénování umělé inteligence.\nDalší informace Duck.ai - S populárními AI modely třetích stran můžeš chatovat anonymně Zkratky Duck.ai Nastavení vyhledávání s funkcí Assist Vyber, jak často chceš, aby se odpovědi s podporou umělé inteligence zobrazovaly ve tvých vyhledáváních diff --git a/duckchat/duckchat-impl/src/main/res/values-da/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-da/strings-duckchat.xml index ee21ac651ae9..352b1344cb60 100644 --- a/duckchat/duckchat-impl/src/main/res/values-da/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-da/strings-duckchat.xml @@ -64,7 +64,6 @@ AI-funktioner DuckDuckGo AI-funktioner er private og valgfrie.\nDine data bruges ikke til at træne AI.\nLæs mere Duck.ai - Chat anonymt med populære tredjeparts AI-chatmodeller Duck.ai-genveje Indstillinger for Search Assist Vælg, hvor ofte du vil have AI-assisterede svar til at optræde i dine søgninger diff --git a/duckchat/duckchat-impl/src/main/res/values-de/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-de/strings-duckchat.xml index d8fce7407d23..07ba0832ac15 100644 --- a/duckchat/duckchat-impl/src/main/res/values-de/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-de/strings-duckchat.xml @@ -64,7 +64,6 @@ KI-Funktionen Die KI-Funktionen von DuckDuckGo sind privat und optional.\nIhre Daten werden nicht zum Trainieren von KI verwendet.\nMehr erfahren Duck.ai - Chatte anonym mit beliebten KI-Chatmodellen von Drittanbietern Duck.ai-Shortcuts Such-Assist-Einstellungen Du kannst auswählen, wie oft KI-gestützte Antworten in deinen Suchergebnissen angezeigt werden sollen. diff --git a/duckchat/duckchat-impl/src/main/res/values-el/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-el/strings-duckchat.xml index a9a32a6729a3..6e60bad2178a 100644 --- a/duckchat/duckchat-impl/src/main/res/values-el/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-el/strings-duckchat.xml @@ -64,7 +64,6 @@ Λειτουργίες τεχνητής νοημοσύνης Οι λειτουργίες τεχνητής νοημοσύνης του DuckDuckGo είναι ιδιωτικές και προαιρετικές.Τα δεδομένα σας δεν χρησιμοποιούνται για εκπαίδευση της τεχνητής νοημοσύνης.\nΜάθετε περισσότερα Duck.ai - Συνομίλησε ανώνυμα με δημοφιλή μοντέλα συνομιλίας μέσω τεχνητής νοημοσύνης, τρίτων μερών Συντομεύσεις Duck.ai Ρυθμίσεις αναζήτησης Assist Επιλέξτε πόσο συχνά θέλετε να εμφανίζονται οι απαντήσεις που υποστηρίζονται από τεχνητή νοημοσύνη στις αναζητήσεις σας diff --git a/duckchat/duckchat-impl/src/main/res/values-es/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-es/strings-duckchat.xml index d01cb3e678b6..2059e0d3e0be 100644 --- a/duckchat/duckchat-impl/src/main/res/values-es/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-es/strings-duckchat.xml @@ -64,7 +64,6 @@ Características de la IA Las funciones de IA de DuckDuckGo son privadas y opcionales.Tus datos no se utilizan para entrenar la IA.\nMás información Duck.ai - Chatea de forma anónima con modelos de chat de IA populares de terceros Atajos de Duck.ai Configuración de Asistente de búsqueda Elige con qué frecuencia deseas que las respuestas asistidas por IA aparezcan en tus búsquedas diff --git a/duckchat/duckchat-impl/src/main/res/values-et/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-et/strings-duckchat.xml index 6e60eb7c3c32..23b18213b970 100644 --- a/duckchat/duckchat-impl/src/main/res/values-et/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-et/strings-duckchat.xml @@ -64,7 +64,6 @@ AI funktsioonid DuckDuckGo tehisintellekti funktsioonid on privaatsed ja valikulised.Sinu andmeid ei kasutata tehisintellekti treenimiseks.\nLisateave Duck.ai - Vestle anonüümselt populaarsete kolmanda osapoole tehisintellekti vestlusmudelitega Duck.ai otseteed Otsingu Assist seaded Vali, kui tihti soovid, et AI-toega vastused ilmuksid sinu otsingutesse diff --git a/duckchat/duckchat-impl/src/main/res/values-fi/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-fi/strings-duckchat.xml index 63323c07bf4a..cc8e01e603ca 100644 --- a/duckchat/duckchat-impl/src/main/res/values-fi/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-fi/strings-duckchat.xml @@ -64,7 +64,6 @@ Tekoälyominaisuudet DuckDuckGon tekoälyominaisuudet ovat yksityisiä ja valinnaisia.\nTietojasi ei käytetä tekoälyn kouluttamiseen.\nLue lisää Duck.ai - Keskustele nimettömästi suosittujen kolmannen osapuolen tekoälykeskustelumallien kanssa Duck.ai-pikakuvakkeet Search Assist -asetukset Valitse, kuinka usein haluat tekoälyavusteisten vastausten näkyvän hauissasi diff --git a/duckchat/duckchat-impl/src/main/res/values-fr/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-fr/strings-duckchat.xml index 669f5a3b10b0..d6a5984c2de5 100644 --- a/duckchat/duckchat-impl/src/main/res/values-fr/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-fr/strings-duckchat.xml @@ -64,7 +64,6 @@ Fonctionnalités de l\'IA Les fonctionnalités de DuckDuckGo AI sont privées et facultatives.Vos données ne servent pas à entraîner l’IA.\nEn savoir plus Duck.ai - Discutez anonymement avec des modèles de chat IA tiers populaires Raccourcis Duck.ai Paramètres de recherche Assist Choisissez la fréquence à laquelle vous souhaitez que les réponses assistées par l\'IA apparaissent dans vos recherches diff --git a/duckchat/duckchat-impl/src/main/res/values-hr/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-hr/strings-duckchat.xml index c7b1b8be5efe..3ee3ad6ff6fc 100644 --- a/duckchat/duckchat-impl/src/main/res/values-hr/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-hr/strings-duckchat.xml @@ -64,7 +64,6 @@ AI značajke DuckDuckGo AI značajke privatne su i neobavezne.Tvoji podaci se ne koriste za obuku umjetne inteligencije.\nSaznaj više Duck.ai - Anonimno čavrljaj s popularnim modelima umjetne inteligencije trećih strana Duck.ai prečaci Pretraži postavke Assista Odaberi koliko često želiš da se odgovori potpomognuti umjetnom inteligencijom pojavljuju u tvojim pretraživanjima diff --git a/duckchat/duckchat-impl/src/main/res/values-hu/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-hu/strings-duckchat.xml index 24988ad2940f..19f1a2b19e1c 100644 --- a/duckchat/duckchat-impl/src/main/res/values-hu/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-hu/strings-duckchat.xml @@ -64,7 +64,6 @@ AI funkciók A DuckDuckGo AI-funkciói privátak és opcionálisak.\nAz adataidat nem használjuk fel az AI tanítására.\nTovábbi részletek Duck.ai - Névtelen csevegés harmadik féltől származó népszerű AI-modellekkel Duck.ai-gyorsparancsok Keresési asszisztens beállításai Válaszd ki, milyen gyakran szeretnél mesterséges intelligenciával generált válaszokat látni a kereséseid során diff --git a/duckchat/duckchat-impl/src/main/res/values-it/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-it/strings-duckchat.xml index f4c6e7ad86aa..59b2b7f68012 100644 --- a/duckchat/duckchat-impl/src/main/res/values-it/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-it/strings-duckchat.xml @@ -64,7 +64,6 @@ Funzionalità IA Le funzionalità AI di DuckDuckGo sono private e opzionali.I tuoi dati non vengono usati per addestrare l\'IA.\nScopri di più Duck.ai - Chatta in forma anonima con i più diffusi modelli di chat AI di terze parti Scorciatoie Duck.ai Impostazioni di Search Assist Scegli la frequenza con cui vuoi che le risposte assistite dall\'intelligenza artificiale appaiano nelle tue ricerche diff --git a/duckchat/duckchat-impl/src/main/res/values-lt/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-lt/strings-duckchat.xml index 3d587326ae12..fd6c971b166f 100644 --- a/duckchat/duckchat-impl/src/main/res/values-lt/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-lt/strings-duckchat.xml @@ -64,7 +64,6 @@ DI funkcijos „DuckDuckGo“ DI funkcijos yra privačios ir neprivalomos.Nenaudojame jūsų duomenų dirbtinio intelekto mokymui.\nSužinokite daugiau Duck.ai - Kalbėkitės anonimiškai su populiariais trečiųjų šalių DI pokalbių modeliais „Duck.ai“ spartieji klavišai „Assist“ paieškos nustatymai Pasirink, kaip dažnai nori, kad tavo paieškose būtų rodomi DI generuojami atsakymai diff --git a/duckchat/duckchat-impl/src/main/res/values-lv/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-lv/strings-duckchat.xml index 3f0300297722..1a736947c096 100644 --- a/duckchat/duckchat-impl/src/main/res/values-lv/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-lv/strings-duckchat.xml @@ -64,7 +64,6 @@ Mākslīgā intelekta funkcijas DuckDuckGo MI funkcijas ir privātas un nav obligātas.Tavi dati netiek izmantoti mākslīgā intelekta apmācībai.\nUzzini vairāk Duck.ai - Tērzē anonīmi ar populāriem trešo personu MI tērzēšanas modeļiem Duck.ai īsceļi Meklēšanas Assist iestatījumi Izvēlies, cik bieži tu vēlies, lai MI atbalstītās atbildes parādītos tavos meklējumos. diff --git a/duckchat/duckchat-impl/src/main/res/values-nb/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-nb/strings-duckchat.xml index f1b37dafc657..635162a4d2a2 100644 --- a/duckchat/duckchat-impl/src/main/res/values-nb/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-nb/strings-duckchat.xml @@ -64,7 +64,6 @@ AI-funksjoner AI-funksjonene i DuckDuckGo er private og valgfrie.\nDataene dine brukes ikke til å trene AI.\nLes mer Duck.ai - Chat anonymt med populære tredjeparts AI-chat-modeller Duck.ai-snarveier Innstillinger for Search Assist Velg hvor ofte du vil at AI-assisterte svar skal vises i søkene dine diff --git a/duckchat/duckchat-impl/src/main/res/values-nl/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-nl/strings-duckchat.xml index 7064e0d30285..c7a7cded325f 100644 --- a/duckchat/duckchat-impl/src/main/res/values-nl/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-nl/strings-duckchat.xml @@ -64,7 +64,6 @@ AI-functies DuckDuckGo AI-functies zijn privé en optioneel.\nJe gegevens worden niet gebruikt om AI te trainen.\nMeer informatie Duck.ai - Chat anoniem met populaire AI-chatmodellen van derden Duck.ai-snelkoppelingen Instellingen voor zoek Assist Kies hoe vaak antwoorden op basis van AI in je zoekresultaten moeten worden weergegeven diff --git a/duckchat/duckchat-impl/src/main/res/values-pl/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-pl/strings-duckchat.xml index 9c51c94543f1..7fbb5199f90e 100644 --- a/duckchat/duckchat-impl/src/main/res/values-pl/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-pl/strings-duckchat.xml @@ -64,7 +64,6 @@ Funkcje AI Funkcje sztucznej inteligencji DuckDuckGo są prywatne i opcjonalne.Twoje dane nie są używane do trenowania AI.\nDowiedz się więcej Duck.ai - Czatuj anonimowo z popularnymi modelami czatu AI innych firm Skróty Duck.ai Ustawienia wyszukiwania Assist Wybierz, jak często w wyszukiwaniach mają pojawiać się odpowiedzi wspomagane przez sztuczną inteligencję diff --git a/duckchat/duckchat-impl/src/main/res/values-pt/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-pt/strings-duckchat.xml index 1c341262469a..af4eb458607a 100644 --- a/duckchat/duckchat-impl/src/main/res/values-pt/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-pt/strings-duckchat.xml @@ -64,7 +64,6 @@ Funcionalidades de IA As funcionalidades de IA do DuckDuckGo são privadas e opcionais.Os teus dados não são utilizados para treinar a IA.\nSabe mais Duck.ai - Conversa anonimamente com modelos de chat com IA populares de terceiros Atalhos Duck.ai Definições do Assist de pesquisa Escolhe a frequência com que queres que as respostas assistidas por IA apareçam nas suas pesquisas diff --git a/duckchat/duckchat-impl/src/main/res/values-ro/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-ro/strings-duckchat.xml index f991e1a26a1c..15ed40b04278 100644 --- a/duckchat/duckchat-impl/src/main/res/values-ro/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-ro/strings-duckchat.xml @@ -64,7 +64,6 @@ Caracteristici AI Funcțiile IA ale DuckDuckGo sunt private și opționale.Datele tale nu sunt folosite pentru a antrena IA.\nAflă mai multe Duck.ai - Discută anonim cu modele populare de chat IA de la terțe părți Comenzi rapide Duck.ai Setări Search Assist Alege cât de des vrei să apară răspunsurile asistate de IA în căutările tale diff --git a/duckchat/duckchat-impl/src/main/res/values-ru/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-ru/strings-duckchat.xml index 560313e2685a..e1d492c53ccf 100644 --- a/duckchat/duckchat-impl/src/main/res/values-ru/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-ru/strings-duckchat.xml @@ -64,7 +64,6 @@ Функции ИИ DuckDuckGo AI — дополнительный конфиденциальный сервис.\nВаши данные не применяются для обучения ИИ.\nПодробнее... Duck.ai - Анонимные чаты с популярными сторонними ИИ-моделями Ярлыки Duck.ai Настройки Search Assist Выберите, как часто вы хотите видеть ответы от ИИ в результатах поиска. diff --git a/duckchat/duckchat-impl/src/main/res/values-sk/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-sk/strings-duckchat.xml index f9fe93028250..796c89529f7f 100644 --- a/duckchat/duckchat-impl/src/main/res/values-sk/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-sk/strings-duckchat.xml @@ -64,7 +64,6 @@ Funkcie AI Funkcie DuckDuckGo AI sú súkromné a voliteľné.\nTvoje údaje sa nepoužívajú na trénovanie umelej inteligencie.\nViac informácií Duck.ai - Chatuj anonymne s populárnymi AI modelmi chatu tretích strán Skratky Duck.ai Nastavenia Assist vyhľadávania Vyber, ako často chceš, aby sa vo vyhľadávaní zobrazovali odpovede podporované AI diff --git a/duckchat/duckchat-impl/src/main/res/values-sl/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-sl/strings-duckchat.xml index 2e6928bfbabb..11385f25e39f 100644 --- a/duckchat/duckchat-impl/src/main/res/values-sl/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-sl/strings-duckchat.xml @@ -64,7 +64,6 @@ Lastnosti UI Funkcije umetne inteligence DuckDuckGo so zasebne in izbirne.\nVaši podatki se ne uporabljajo za usposabljanje umetne inteligence.\nVeč o tem Duck.ai - Anonimno klepetajte s priljubljenimi modeli umetne inteligence tretjih oseb Bližnjice do Duck.ai Nastavitve modula Search Assist Izberite, kako pogosto želite, da se odgovori s pomočjo umetne inteligence prikazujejo v vaših iskanjih diff --git a/duckchat/duckchat-impl/src/main/res/values-sv/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-sv/strings-duckchat.xml index 83744e1fd950..d371f5bc4f1b 100644 --- a/duckchat/duckchat-impl/src/main/res/values-sv/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-sv/strings-duckchat.xml @@ -64,7 +64,6 @@ AI-funktioner DuckDuckGos AI-funktioner är privata och valfria.\nDina data används inte för att träna AI.\nLäs mer Duck.ai - Chatta anonymt med populära AI-chattmodeller från tredje part Duck.ai-genvägar Inställningar för Search Assist Välj hur ofta du vill att AI-assisterade svar ska visas i dina sökningar diff --git a/duckchat/duckchat-impl/src/main/res/values-tr/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-tr/strings-duckchat.xml index 1bae6aa12af8..0a6e193e9f60 100644 --- a/duckchat/duckchat-impl/src/main/res/values-tr/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-tr/strings-duckchat.xml @@ -64,7 +64,6 @@ AI Özellikleri DuckDuckGo AI özellikleri gizli ve isteğe bağlıdır.\nVerileriniz yapay zekayı eğitmek için kullanılmaz.\nDaha Fazla Bilgi Duck.ai - Popüler üçüncü taraf AI sohbet modelleriyle anonim olarak sohbet edin Duck.ai Kısayolları Search Assist Ayarları Yapay zeka destekli yanıtların aramalarınızda ne sıklıkta görünmesini istediğinizi seçin diff --git a/duckchat/duckchat-impl/src/main/res/values/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values/strings-duckchat.xml index 70fc8c42e654..4f2d9e0085f6 100644 --- a/duckchat/duckchat-impl/src/main/res/values/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values/strings-duckchat.xml @@ -63,7 +63,7 @@ AI Features DuckDuckGo AI features are private and optional.\nYour data is not used to train AI.\nLearn More Duck.ai - Chat anonymously with popular 3rd-party AI chat models + Chat privately with popular 3rd-party AI models Duck.ai Shortcuts Search Assist Settings Choose how often you want AI-Assisted answers to appear in your searches From 7c74d85c09f8ea20655fa587293279cd62c7d2ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 14 Aug 2025 13:42:33 +0200 Subject: [PATCH 2/9] move Duck.ai shortcut settings to a separate screen --- .../src/main/AndroidManifest.xml | 7 +- .../DuckAiShortcutSettingsActivity.kt | 76 ++++++++++++ .../DuckAiShortcutSettingsViewModel.kt | 72 ++++++++++++ .../DuckChatSettingsActivity.kt | 36 ++---- .../DuckChatSettingsViewModel.kt | 30 +++-- .../activity_duck_ai_shortcut_settings.xml | 56 +++++++++ .../layout/activity_duck_chat_settings.xml | 22 +--- .../main/res/values-bg/strings-duckchat.xml | 2 - .../main/res/values-cs/strings-duckchat.xml | 2 - .../main/res/values-da/strings-duckchat.xml | 2 - .../main/res/values-de/strings-duckchat.xml | 2 - .../main/res/values-el/strings-duckchat.xml | 2 - .../main/res/values-es/strings-duckchat.xml | 2 - .../main/res/values-et/strings-duckchat.xml | 2 - .../main/res/values-fi/strings-duckchat.xml | 2 - .../main/res/values-fr/strings-duckchat.xml | 2 - .../main/res/values-hr/strings-duckchat.xml | 2 - .../main/res/values-hu/strings-duckchat.xml | 2 - .../main/res/values-it/strings-duckchat.xml | 2 - .../main/res/values-lt/strings-duckchat.xml | 2 - .../main/res/values-lv/strings-duckchat.xml | 2 - .../main/res/values-nb/strings-duckchat.xml | 2 - .../main/res/values-nl/strings-duckchat.xml | 2 - .../main/res/values-pl/strings-duckchat.xml | 2 - .../main/res/values-pt/strings-duckchat.xml | 2 - .../main/res/values-ro/strings-duckchat.xml | 2 - .../main/res/values-ru/strings-duckchat.xml | 2 - .../main/res/values-sk/strings-duckchat.xml | 2 - .../main/res/values-sl/strings-duckchat.xml | 2 - .../main/res/values-sv/strings-duckchat.xml | 2 - .../main/res/values-tr/strings-duckchat.xml | 2 - .../src/main/res/values/strings-duckchat.xml | 4 +- .../DuckAiShortcutSettingsViewModelTest.kt | 111 ++++++++++++++++++ .../DuckChatSettingsViewModelTest.kt | 102 ++++------------ 34 files changed, 376 insertions(+), 188 deletions(-) create mode 100644 duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckAiShortcutSettingsActivity.kt create mode 100644 duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckAiShortcutSettingsViewModel.kt rename duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/{ => settings}/DuckChatSettingsActivity.kt (85%) rename duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/{ => settings}/DuckChatSettingsViewModel.kt (82%) create mode 100644 duckchat/duckchat-impl/src/main/res/layout/activity_duck_ai_shortcut_settings.xml create mode 100644 duckchat/duckchat-impl/src/test/kotlin/com/duckduckgo/duckchat/impl/ui/settings/DuckAiShortcutSettingsViewModelTest.kt rename duckchat/duckchat-impl/src/test/kotlin/com/duckduckgo/duckchat/impl/ui/{ => settings}/DuckChatSettingsViewModelTest.kt (69%) diff --git a/duckchat/duckchat-impl/src/main/AndroidManifest.xml b/duckchat/duckchat-impl/src/main/AndroidManifest.xml index ae960da40092..d653e3642d66 100644 --- a/duckchat/duckchat-impl/src/main/AndroidManifest.xml +++ b/duckchat/duckchat-impl/src/main/AndroidManifest.xml @@ -18,10 +18,15 @@ + + viewModel.onShowDuckChatInMenuToggled(isChecked) + } + + private val addressBarToggleListener = + CompoundButton.OnCheckedChangeListener { _, isChecked -> + viewModel.onShowDuckChatInAddressBarToggled(isChecked) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContentView(binding.root) + + setupToolbar(binding.includeToolbar.toolbar) + + observeViewModel() + } + + private fun observeViewModel() { + viewModel.viewState + .flowWithLifecycle(lifecycle, Lifecycle.State.RESUMED) + .onEach { renderViewState(it) } + .launchIn(lifecycleScope) + } + + private fun renderViewState(viewState: ViewState) { + binding.showDuckAiInMenuToggle.apply { + quietlySetIsChecked(viewState.showInBrowserMenu, menuToggleListener) + } + binding.showDuckAiInAddressBarToggle.apply { + isVisible = viewState.shouldShowAddressBarToggle + quietlySetIsChecked(viewState.showInAddressBar, addressBarToggleListener) + } + } +} diff --git a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckAiShortcutSettingsViewModel.kt b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckAiShortcutSettingsViewModel.kt new file mode 100644 index 000000000000..c7040a71315d --- /dev/null +++ b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckAiShortcutSettingsViewModel.kt @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2025 DuckDuckGo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.duckduckgo.duckchat.impl.ui.settings + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.duckduckgo.anvil.annotations.ContributesViewModel +import com.duckduckgo.app.statistics.pixels.Pixel +import com.duckduckgo.common.ui.experiments.visual.store.ExperimentalThemingDataStore +import com.duckduckgo.di.scopes.ActivityScope +import com.duckduckgo.duckchat.impl.DuckChatInternal +import com.duckduckgo.duckchat.impl.pixel.DuckChatPixelName +import com.duckduckgo.duckchat.impl.ui.settings.DuckChatSettingsViewModel.Command.OpenLink +import com.duckduckgo.duckchat.impl.ui.settings.DuckChatSettingsViewModel.Command.OpenLinkInNewTab +import com.duckduckgo.subscriptions.api.SubscriptionRebrandingFeatureToggle +import javax.inject.Inject +import kotlinx.coroutines.channels.BufferOverflow.DROP_OLDEST +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.launch + +@ContributesViewModel(ActivityScope::class) +class DuckAiShortcutSettingsViewModel @Inject constructor( + private val duckChat: DuckChatInternal, +) : ViewModel() { + + data class ViewState( + val showInBrowserMenu: Boolean = false, + val showInAddressBar: Boolean = false, + val shouldShowAddressBarToggle: Boolean = false, + ) + + val viewState = combine( + duckChat.observeShowInBrowserMenuUserSetting(), + duckChat.observeShowInAddressBarUserSetting(), + ) { showInBrowserMenu, showInAddressBar -> + ViewState( + showInBrowserMenu = showInBrowserMenu, + showInAddressBar = showInAddressBar, + shouldShowAddressBarToggle = duckChat.isAddressBarEntryPointEnabled(), + ) + }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), ViewState()) + + fun onShowDuckChatInMenuToggled(checked: Boolean) { + viewModelScope.launch { + duckChat.setShowInBrowserMenuUserSetting(checked) + } + } + + fun onShowDuckChatInAddressBarToggled(checked: Boolean) { + viewModelScope.launch { + duckChat.setShowInAddressBarUserSetting(checked) + } + } +} diff --git a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/DuckChatSettingsActivity.kt b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt similarity index 85% rename from duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/DuckChatSettingsActivity.kt rename to duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt index 74a76a8a213e..8089daf6e521 100644 --- a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/DuckChatSettingsActivity.kt +++ b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt @@ -14,8 +14,9 @@ * limitations under the License. */ -package com.duckduckgo.duckchat.impl.ui +package com.duckduckgo.duckchat.impl.ui.settings +import android.content.Intent import android.os.Bundle import android.view.View import android.widget.CompoundButton @@ -28,6 +29,7 @@ import com.duckduckgo.anvil.annotations.ContributeToActivityStarter import com.duckduckgo.anvil.annotations.InjectWith import com.duckduckgo.app.statistics.pixels.Pixel import com.duckduckgo.app.tabs.BrowserNav +import com.duckduckgo.browser.api.ui.BrowserScreens.FeedbackActivityWithEmptyParams import com.duckduckgo.browser.api.ui.BrowserScreens.WebViewActivityWithParams import com.duckduckgo.common.ui.DuckDuckGoActivity import com.duckduckgo.common.ui.spans.DuckDuckGoClickableSpan @@ -40,11 +42,12 @@ import com.duckduckgo.duckchat.api.DuckChatSettingsNoParams import com.duckduckgo.duckchat.impl.R import com.duckduckgo.duckchat.impl.databinding.ActivityDuckChatSettingsBinding import com.duckduckgo.duckchat.impl.pixel.DuckChatPixelName.DUCK_CHAT_SETTINGS_DISPLAYED -import com.duckduckgo.duckchat.impl.ui.DuckChatSettingsViewModel.ViewState +import com.duckduckgo.duckchat.impl.ui.settings.DuckChatSettingsViewModel.ViewState import com.duckduckgo.navigation.api.GlobalActivityStarter import javax.inject.Inject import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import com.duckduckgo.mobile.android.R as CommonR @InjectWith(ActivityScope::class) @ContributeToActivityStarter(DuckChatSettingsNoParams::class, screenName = "duckai.settings") @@ -63,16 +66,6 @@ class DuckChatSettingsActivity : DuckDuckGoActivity() { viewModel.onDuckAiInputScreenToggled(isChecked) } - private val menuToggleListener = - CompoundButton.OnCheckedChangeListener { _, isChecked -> - viewModel.onShowDuckChatInMenuToggled(isChecked) - } - - private val addressBarToggleListener = - CompoundButton.OnCheckedChangeListener { _, isChecked -> - viewModel.onShowDuckChatInAddressBarToggled(isChecked) - } - @Inject lateinit var globalActivityStarter: GlobalActivityStarter @@ -114,7 +107,6 @@ class DuckChatSettingsActivity : DuckDuckGoActivity() { binding.duckChatSettingsTitle.setText(R.string.duck_chat_title_rebranding) binding.userEnabledDuckChatToggle.gone() binding.userEnabledDuckChatToggleRebranding.show() - binding.duckChatToggleSettingsTitle.setText(R.string.duck_chat_show_in_heading_rebranding) binding.showDuckChatSearchSettingsLink.setPrimaryText(getString(R.string.duck_chat_assist_settings_title_rebranding)) binding.showDuckChatSearchSettingsLink.setSecondaryText(getString(R.string.duck_chat_assist_settings_description_rebranding)) } else { @@ -124,7 +116,6 @@ class DuckChatSettingsActivity : DuckDuckGoActivity() { binding.duckChatSettingsTitle.setText(R.string.duck_chat_title) binding.userEnabledDuckChatToggle.show() binding.userEnabledDuckChatToggleRebranding.gone() - binding.duckChatToggleSettingsTitle.setText(R.string.duck_chat_show_in_heading) binding.showDuckChatSearchSettingsLink.setPrimaryText(getString(R.string.duck_chat_assist_settings_title)) binding.showDuckChatSearchSettingsLink.setSecondaryText(getString(R.string.duck_chat_assist_settings_description)) } @@ -149,15 +140,9 @@ class DuckChatSettingsActivity : DuckDuckGoActivity() { quietlySetIsChecked(viewState.isInputScreenEnabled, inputScreenToggleListener) } - binding.duckChatToggleSettingsTitle.isVisible = viewState.isDuckChatUserEnabled - - binding.showDuckChatInMenuToggle.apply { - isVisible = viewState.shouldShowAddressBarToggle - quietlySetIsChecked(viewState.showInBrowserMenu, menuToggleListener) - } - binding.showDuckChatInAddressBarToggle.apply { - isVisible = viewState.shouldShowAddressBarToggle - quietlySetIsChecked(viewState.showInAddressBar, addressBarToggleListener) + binding.duckAiShortcuts.isVisible = viewState.shouldShowShortcuts + binding.duckAiShortcuts.setOnClickListener { + viewModel.onDuckAiShortcutsClicked() } binding.showDuckChatSearchSettingsLink.setOnClickListener { viewModel.duckChatSearchAISettingsClicked() @@ -178,6 +163,11 @@ class DuckChatSettingsActivity : DuckDuckGoActivity() { is DuckChatSettingsViewModel.Command.OpenLinkInNewTab -> { startActivity(browserNav.openInNewTab(this@DuckChatSettingsActivity, command.link)) } + + is DuckChatSettingsViewModel.Command.OpenShortcutSettings -> { + val intent = Intent(this, DuckAiShortcutSettingsActivity::class.java) + startActivity(intent) + } } } } diff --git a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/DuckChatSettingsViewModel.kt b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsViewModel.kt similarity index 82% rename from duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/DuckChatSettingsViewModel.kt rename to duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsViewModel.kt index 6c0fd7ed984b..d0c55884ff30 100644 --- a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/DuckChatSettingsViewModel.kt +++ b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsViewModel.kt @@ -14,18 +14,18 @@ * limitations under the License. */ -package com.duckduckgo.duckchat.impl.ui +package com.duckduckgo.duckchat.impl.ui.settings import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.duckduckgo.anvil.annotations.ContributesViewModel import com.duckduckgo.app.statistics.pixels.Pixel -import com.duckduckgo.common.ui.experiments.visual.store.ExperimentalThemingDataStore import com.duckduckgo.di.scopes.ActivityScope import com.duckduckgo.duckchat.impl.DuckChatInternal import com.duckduckgo.duckchat.impl.pixel.DuckChatPixelName -import com.duckduckgo.duckchat.impl.ui.DuckChatSettingsViewModel.Command.OpenLink -import com.duckduckgo.duckchat.impl.ui.DuckChatSettingsViewModel.Command.OpenLinkInNewTab +import com.duckduckgo.duckchat.impl.ui.settings.DuckChatSettingsViewModel.Command.OpenLink +import com.duckduckgo.duckchat.impl.ui.settings.DuckChatSettingsViewModel.Command.OpenLinkInNewTab +import com.duckduckgo.duckchat.impl.ui.settings.DuckChatSettingsViewModel.Command.OpenShortcutSettings import com.duckduckgo.subscriptions.api.SubscriptionRebrandingFeatureToggle import javax.inject.Inject import kotlinx.coroutines.channels.BufferOverflow.DROP_OLDEST @@ -40,7 +40,6 @@ import kotlinx.coroutines.launch class DuckChatSettingsViewModel @Inject constructor( private val duckChat: DuckChatInternal, private val pixel: Pixel, - private val experimentalThemingDataStore: ExperimentalThemingDataStore, private val rebrandingAiFeaturesEnabled: SubscriptionRebrandingFeatureToggle, ) : ViewModel() { @@ -50,28 +49,20 @@ class DuckChatSettingsViewModel @Inject constructor( data class ViewState( val isDuckChatUserEnabled: Boolean = false, val isInputScreenEnabled: Boolean = false, - val showInBrowserMenu: Boolean = false, - val showInAddressBar: Boolean = false, + val shouldShowShortcuts: Boolean = false, val shouldShowInputScreenToggle: Boolean = false, - val shouldShowBrowserMenuToggle: Boolean = false, - val shouldShowAddressBarToggle: Boolean = false, val isRebrandingAiFeaturesEnabled: Boolean = false, ) val viewState = combine( duckChat.observeEnableDuckChatUserSetting(), duckChat.observeInputScreenUserSettingEnabled(), - duckChat.observeShowInBrowserMenuUserSetting(), - duckChat.observeShowInAddressBarUserSetting(), - ) { isDuckChatUserEnabled, isInputScreenEnabled, showInBrowserMenu, showInAddressBar -> + ) { isDuckChatUserEnabled, isInputScreenEnabled -> ViewState( isDuckChatUserEnabled = isDuckChatUserEnabled, isInputScreenEnabled = isInputScreenEnabled, - showInBrowserMenu = showInBrowserMenu, - showInAddressBar = showInAddressBar, + shouldShowShortcuts = isDuckChatUserEnabled, shouldShowInputScreenToggle = isDuckChatUserEnabled && duckChat.isInputScreenFeatureAvailable(), - shouldShowBrowserMenuToggle = isDuckChatUserEnabled, - shouldShowAddressBarToggle = isDuckChatUserEnabled && duckChat.isAddressBarEntryPointEnabled(), isRebrandingAiFeaturesEnabled = rebrandingAiFeaturesEnabled.isAIFeaturesRebrandingEnabled(), ) }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), ViewState()) @@ -79,6 +70,7 @@ class DuckChatSettingsViewModel @Inject constructor( sealed class Command { data class OpenLink(val link: String) : Command() data class OpenLinkInNewTab(val link: String) : Command() + data object OpenShortcutSettings : Command() } fun onDuckChatUserEnabledToggled(checked: Boolean) { @@ -138,6 +130,12 @@ class DuckChatSettingsViewModel @Inject constructor( } } + fun onDuckAiShortcutsClicked() { + viewModelScope.launch { + commandChannel.send(OpenShortcutSettings) + } + } + companion object { const val DUCK_CHAT_LEARN_MORE_LINK = "https://duckduckgo.com/duckduckgo-help-pages/aichat/" const val DUCK_CHAT_SEARCH_AI_SETTINGS_LINK = "https://duckduckgo.com/settings?ko=-1#aifeatures" diff --git a/duckchat/duckchat-impl/src/main/res/layout/activity_duck_ai_shortcut_settings.xml b/duckchat/duckchat-impl/src/main/res/layout/activity_duck_ai_shortcut_settings.xml new file mode 100644 index 000000000000..f05eb94cea8d --- /dev/null +++ b/duckchat/duckchat-impl/src/main/res/layout/activity_duck_ai_shortcut_settings.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml b/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml index ff7563496e5a..dabaf6511d24 100644 --- a/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml +++ b/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml @@ -98,25 +98,13 @@ app:showBetaPill="true" app:showSwitch="true"/> - - - - - + android:visibility="gone" + app:primaryText="@string/duck_ai_shortcut_settings_title" + app:secondaryText="@string/duck_ai_shortcut_settings_description" /> Duck.ai е незадължителна функция, чрез която можете да разговаряте анонимно с популярни AI чат модели от трети страни. Чатовете Ви не се използват за обучение на AI.\nНаучете повече Активиране на Duck.ai - Бързи Връзки Меню на браузъра Адресна лента Настройки на Assist @@ -64,7 +63,6 @@ Функции с изкуствен интелект Функциите на DuckDuckGo AI са поверителни и незадължителни.Вашите данни не се използват за обучение на AI.\nНаучете повече Duck.ai - Преки пътища за Duck.ai Настройки за Assist при търсене Изберете колко често искате да се появяват отговори, подпомагани от изкуствен интелект, в търсенето \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-cs/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-cs/strings-duckchat.xml index 9f1403dce8c0..01a920ffd2ea 100644 --- a/duckchat/duckchat-impl/src/main/res/values-cs/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-cs/strings-duckchat.xml @@ -39,7 +39,6 @@ Duck.ai je volitelná funkce, která umožňuje anonymně chatovat s populárními AI chatovacími modely třetích stran. Tvoje chaty neslouží k trénování umělé inteligence.\nDalší informace Povolit službu Duck.ai - Zkratky Menu prohlížeče Adresní řádek Nastavení funkce Assist @@ -64,7 +63,6 @@ Funkce AI Funkce AI na DuckDuckGo jsou soukromé a volitelné.Tvoje data se nepoužívají k trénování umělé inteligence.\nDalší informace Duck.ai - Zkratky Duck.ai Nastavení vyhledávání s funkcí Assist Vyber, jak často chceš, aby se odpovědi s podporou umělé inteligence zobrazovaly ve tvých vyhledáváních \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-da/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-da/strings-duckchat.xml index 352b1344cb60..32023ee913f0 100644 --- a/duckchat/duckchat-impl/src/main/res/values-da/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-da/strings-duckchat.xml @@ -39,7 +39,6 @@ Duck.ai er en valgfri funktion, der giver dig mulighed for at chatte anonymt med populære tredjeparts AI-chatmodeller. Dine chats bruges ikke til at træne AI.\nLæs mere Aktiver Duck.ai - Genveje Browsermenu Adresselinje Assist-indstillinger @@ -64,7 +63,6 @@ AI-funktioner DuckDuckGo AI-funktioner er private og valgfrie.\nDine data bruges ikke til at træne AI.\nLæs mere Duck.ai - Duck.ai-genveje Indstillinger for Search Assist Vælg, hvor ofte du vil have AI-assisterede svar til at optræde i dine søgninger \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-de/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-de/strings-duckchat.xml index 07ba0832ac15..5d644a211902 100644 --- a/duckchat/duckchat-impl/src/main/res/values-de/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-de/strings-duckchat.xml @@ -39,7 +39,6 @@ Duck.ai ist eine optionale Funktion, mit der du anonym mit beliebten KI-Chatmodellen von Drittanbietern chatten kannst. Deine Chats werden nicht zum Trainieren von KI verwendet.\nMehr erfahren Aktiviere Duck.ai - Shortcuts Browsermenü Adresszeile Assist-Einstellungen @@ -64,7 +63,6 @@ KI-Funktionen Die KI-Funktionen von DuckDuckGo sind privat und optional.\nIhre Daten werden nicht zum Trainieren von KI verwendet.\nMehr erfahren Duck.ai - Duck.ai-Shortcuts Such-Assist-Einstellungen Du kannst auswählen, wie oft KI-gestützte Antworten in deinen Suchergebnissen angezeigt werden sollen. \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-el/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-el/strings-duckchat.xml index 6e60bad2178a..b821f998196e 100644 --- a/duckchat/duckchat-impl/src/main/res/values-el/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-el/strings-duckchat.xml @@ -39,7 +39,6 @@ Το Duck.ai αποτελεί προαιρετική λειτουργία που σας επιτρέπει να συνομιλείτε ανώνυμα με δημοφιλή μοντέλα τρίτων για συνομιλία μέσω τεχνητής νοημοσύνης. Οι συνομιλίες σας δεν χρησιμοποιούνται για την εκπαίδευση τεχνητής συνομιλίας.\nΜάθετε περισσότερα Ενεργοποίηση του Duck.ai - Συντομευσεις Μενού προγράμματος περιήγησης Γραμμή διευθύνσεων Ρυθμίσεις Assist @@ -64,7 +63,6 @@ Λειτουργίες τεχνητής νοημοσύνης Οι λειτουργίες τεχνητής νοημοσύνης του DuckDuckGo είναι ιδιωτικές και προαιρετικές.Τα δεδομένα σας δεν χρησιμοποιούνται για εκπαίδευση της τεχνητής νοημοσύνης.\nΜάθετε περισσότερα Duck.ai - Συντομεύσεις Duck.ai Ρυθμίσεις αναζήτησης Assist Επιλέξτε πόσο συχνά θέλετε να εμφανίζονται οι απαντήσεις που υποστηρίζονται από τεχνητή νοημοσύνη στις αναζητήσεις σας \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-es/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-es/strings-duckchat.xml index 2059e0d3e0be..534a58bc1222 100644 --- a/duckchat/duckchat-impl/src/main/res/values-es/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-es/strings-duckchat.xml @@ -39,7 +39,6 @@ Duck.ai es una función opcional que te permite chatear de forma anónima con modelos populares de chat de IA de terceros. Tus chats no se utilizan para entrenar la IA.\nMás información Activa Duck.ai - Accesos directos Menú del navegador Barra de direcciones Ajustes de Assist @@ -64,7 +63,6 @@ Características de la IA Las funciones de IA de DuckDuckGo son privadas y opcionales.Tus datos no se utilizan para entrenar la IA.\nMás información Duck.ai - Atajos de Duck.ai Configuración de Asistente de búsqueda Elige con qué frecuencia deseas que las respuestas asistidas por IA aparezcan en tus búsquedas \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-et/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-et/strings-duckchat.xml index 23b18213b970..3847ae24b6ed 100644 --- a/duckchat/duckchat-impl/src/main/res/values-et/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-et/strings-duckchat.xml @@ -39,7 +39,6 @@ Duck.ai on valikuline funktsioon, mis võimaldab anonüümselt vestelda populaarsete kolmanda poole AI vestlusmudelitega. Teie vestlusi ei kasutata tehisintellekti treenimiseks.\nLisateave Luba Duck.ai - Otseteed Brauseri menüü Aadressiriba Assisti seaded @@ -64,7 +63,6 @@ AI funktsioonid DuckDuckGo tehisintellekti funktsioonid on privaatsed ja valikulised.Sinu andmeid ei kasutata tehisintellekti treenimiseks.\nLisateave Duck.ai - Duck.ai otseteed Otsingu Assist seaded Vali, kui tihti soovid, et AI-toega vastused ilmuksid sinu otsingutesse \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-fi/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-fi/strings-duckchat.xml index cc8e01e603ca..229a5afb3ebb 100644 --- a/duckchat/duckchat-impl/src/main/res/values-fi/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-fi/strings-duckchat.xml @@ -39,7 +39,6 @@ Duck.ai on valinnainen ominaisuus, jonka avulla voit keskustella anonyymisti suosittujen kolmannen osapuolen tekoälykeskustelumallien kanssa. Keskustelujasi ei käytetä tekoälyn kouluttamiseen.\nLue lisää Ota Duck.ai käyttöön - Pikavalinnat Selainvalikko Osoitekenttä Assist-asetukset @@ -64,7 +63,6 @@ Tekoälyominaisuudet DuckDuckGon tekoälyominaisuudet ovat yksityisiä ja valinnaisia.\nTietojasi ei käytetä tekoälyn kouluttamiseen.\nLue lisää Duck.ai - Duck.ai-pikakuvakkeet Search Assist -asetukset Valitse, kuinka usein haluat tekoälyavusteisten vastausten näkyvän hauissasi \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-fr/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-fr/strings-duckchat.xml index d6a5984c2de5..e5eefc386859 100644 --- a/duckchat/duckchat-impl/src/main/res/values-fr/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-fr/strings-duckchat.xml @@ -39,7 +39,6 @@ Duck.ai est une fonctionnalité optionnelle qui vous permet de discuter anonymement avec des modèles de chat IA tiers populaires. Vos discussions ne servent pas à entraîner l’IA.\nEn savoir plus Activer Duck.ai - Raccourcis Menu du navigateur Barre d\'adresse Paramètres d\'Assist @@ -64,7 +63,6 @@ Fonctionnalités de l\'IA Les fonctionnalités de DuckDuckGo AI sont privées et facultatives.Vos données ne servent pas à entraîner l’IA.\nEn savoir plus Duck.ai - Raccourcis Duck.ai Paramètres de recherche Assist Choisissez la fréquence à laquelle vous souhaitez que les réponses assistées par l\'IA apparaissent dans vos recherches \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-hr/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-hr/strings-duckchat.xml index 3ee3ad6ff6fc..ed89d1ef95ed 100644 --- a/duckchat/duckchat-impl/src/main/res/values-hr/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-hr/strings-duckchat.xml @@ -39,7 +39,6 @@ Duck.ai izborna je značajka koja ti omogućuje anonimno čavrljanje s popularnim AI modelima \'chata\' trećih strana. Tvoja čavrljanja se ne koriste za obuku AI-a.\nSaznaj više Omogući Duck.ai - Prečaci Izbornik preglednika Adresna traka Postavke Assista @@ -64,7 +63,6 @@ AI značajke DuckDuckGo AI značajke privatne su i neobavezne.Tvoji podaci se ne koriste za obuku umjetne inteligencije.\nSaznaj više Duck.ai - Duck.ai prečaci Pretraži postavke Assista Odaberi koliko često želiš da se odgovori potpomognuti umjetnom inteligencijom pojavljuju u tvojim pretraživanjima \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-hu/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-hu/strings-duckchat.xml index 19f1a2b19e1c..0e047a79ed8f 100644 --- a/duckchat/duckchat-impl/src/main/res/values-hu/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-hu/strings-duckchat.xml @@ -39,7 +39,6 @@ A Duck.ai egy opcionális funkció, amely lehetővé teszi a harmadik féltől származó népszerű AI-csevegési modellekkel való névtelen csevegést. A csevegéseidet nem használjuk fel az AI tanítására.\nTovábbi részletek Duck.ai engedélyezése - Gyorsparancsok Böngészési menü Címsor Assist-beállítások @@ -64,7 +63,6 @@ AI funkciók A DuckDuckGo AI-funkciói privátak és opcionálisak.\nAz adataidat nem használjuk fel az AI tanítására.\nTovábbi részletek Duck.ai - Duck.ai-gyorsparancsok Keresési asszisztens beállításai Válaszd ki, milyen gyakran szeretnél mesterséges intelligenciával generált válaszokat látni a kereséseid során \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-it/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-it/strings-duckchat.xml index 59b2b7f68012..dfa527fae3c0 100644 --- a/duckchat/duckchat-impl/src/main/res/values-it/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-it/strings-duckchat.xml @@ -39,7 +39,6 @@ Duck.ai è una funzionalità opzionale che consente di chattare in forma anonima con i più diffusi modelli di chat AI di terze parti. Le chat non vengono usate per addestrare l\'IA.\nScopri di più Abilita Duck.ai - Scorciatoie Menu del browser Barra degli indirizzi Impostazioni di Assist @@ -64,7 +63,6 @@ Funzionalità IA Le funzionalità AI di DuckDuckGo sono private e opzionali.I tuoi dati non vengono usati per addestrare l\'IA.\nScopri di più Duck.ai - Scorciatoie Duck.ai Impostazioni di Search Assist Scegli la frequenza con cui vuoi che le risposte assistite dall\'intelligenza artificiale appaiano nelle tue ricerche \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-lt/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-lt/strings-duckchat.xml index fd6c971b166f..5cbe75429a37 100644 --- a/duckchat/duckchat-impl/src/main/res/values-lt/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-lt/strings-duckchat.xml @@ -39,7 +39,6 @@ „Duck.ai“ yra pasirenkama funkcija, leidžianti anonimiškai kalbėtis su populiariais trečiųjų šalių DI pokalbių modeliais. Tavo pokalbiai nenaudojami dirbtinio intelekto mokymui.\nSužinok daugiau Įjungti „Duck.ai“ - Šaukiniai Naršyklės meniu Adreso juosta „Assist“ nustatymai @@ -64,7 +63,6 @@ DI funkcijos „DuckDuckGo“ DI funkcijos yra privačios ir neprivalomos.Nenaudojame jūsų duomenų dirbtinio intelekto mokymui.\nSužinokite daugiau Duck.ai - „Duck.ai“ spartieji klavišai „Assist“ paieškos nustatymai Pasirink, kaip dažnai nori, kad tavo paieškose būtų rodomi DI generuojami atsakymai \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-lv/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-lv/strings-duckchat.xml index 1a736947c096..cc00b090cfd5 100644 --- a/duckchat/duckchat-impl/src/main/res/values-lv/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-lv/strings-duckchat.xml @@ -39,7 +39,6 @@ Duck.ai ir papildu līdzeklis, kas ļauj anonīmi tērzēt ar populāriem trešo pušu Ml tērzēšanas modeļiem. Tavas tērzēšanas sarunas netiek izmantotas AMI apmācībai.\nUzzini vairāk Iespējot Duck.ai - Saīsnes Pārlūka izvēlne Adreses josla Assist iestatījumi @@ -64,7 +63,6 @@ Mākslīgā intelekta funkcijas DuckDuckGo MI funkcijas ir privātas un nav obligātas.Tavi dati netiek izmantoti mākslīgā intelekta apmācībai.\nUzzini vairāk Duck.ai - Duck.ai īsceļi Meklēšanas Assist iestatījumi Izvēlies, cik bieži tu vēlies, lai MI atbalstītās atbildes parādītos tavos meklējumos. \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-nb/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-nb/strings-duckchat.xml index 635162a4d2a2..60780367b59e 100644 --- a/duckchat/duckchat-impl/src/main/res/values-nb/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-nb/strings-duckchat.xml @@ -39,7 +39,6 @@ Duck.ai er en valgfri funksjon der du kan chatte anonymt med populære tredjeparts AI-chat-modeller. Chattene dine brukes ikke til å trene AI.\nLes mer Aktiver Duck.ai - Snarveier Nettlesermeny Adressefelt Assist-innstillinger @@ -64,7 +63,6 @@ AI-funksjoner AI-funksjonene i DuckDuckGo er private og valgfrie.\nDataene dine brukes ikke til å trene AI.\nLes mer Duck.ai - Duck.ai-snarveier Innstillinger for Search Assist Velg hvor ofte du vil at AI-assisterte svar skal vises i søkene dine \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-nl/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-nl/strings-duckchat.xml index c7a7cded325f..d6a58a9fd35f 100644 --- a/duckchat/duckchat-impl/src/main/res/values-nl/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-nl/strings-duckchat.xml @@ -39,7 +39,6 @@ Duck.ai is een optionele functie waarmee je anoniem kunt chatten met populaire AI-chatmodellen van derden. Je chats worden niet gebruikt om AI te trainen.\nMeer informatie Duck.ai inschakelen - Sneltoetsen Browsermenu Adresbalk Assist-instellingen @@ -64,7 +63,6 @@ AI-functies DuckDuckGo AI-functies zijn privé en optioneel.\nJe gegevens worden niet gebruikt om AI te trainen.\nMeer informatie Duck.ai - Duck.ai-snelkoppelingen Instellingen voor zoek Assist Kies hoe vaak antwoorden op basis van AI in je zoekresultaten moeten worden weergegeven \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-pl/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-pl/strings-duckchat.xml index 7fbb5199f90e..80b607932cf7 100644 --- a/duckchat/duckchat-impl/src/main/res/values-pl/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-pl/strings-duckchat.xml @@ -39,7 +39,6 @@ Duck.ai to opcjonalna funkcja, która umożliwia prowadzenie anonimowych rozmów z popularnymi modelami czatu AI innych firm. Twoje czaty nie są używane do trenowania AI.\nDowiedz się więcej Włącz Duck.ai - Skróty Menu przeglądarki Pasek adresu Ustawienia Assist @@ -64,7 +63,6 @@ Funkcje AI Funkcje sztucznej inteligencji DuckDuckGo są prywatne i opcjonalne.Twoje dane nie są używane do trenowania AI.\nDowiedz się więcej Duck.ai - Skróty Duck.ai Ustawienia wyszukiwania Assist Wybierz, jak często w wyszukiwaniach mają pojawiać się odpowiedzi wspomagane przez sztuczną inteligencję \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-pt/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-pt/strings-duckchat.xml index af4eb458607a..ed4bfa522b76 100644 --- a/duckchat/duckchat-impl/src/main/res/values-pt/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-pt/strings-duckchat.xml @@ -39,7 +39,6 @@ O Duck.ai é uma funcionalidade opcional que te permite conversar anonimamente com modelos de chat de IA populares de terceiros. As tuas conversas não são utilizadas para treinar a IA.\nSabe mais Ativar Duck.ai - Atalhos Menu do navegador Barra de endereço Definições do Assist @@ -64,7 +63,6 @@ Funcionalidades de IA As funcionalidades de IA do DuckDuckGo são privadas e opcionais.Os teus dados não são utilizados para treinar a IA.\nSabe mais Duck.ai - Atalhos Duck.ai Definições do Assist de pesquisa Escolhe a frequência com que queres que as respostas assistidas por IA apareçam nas suas pesquisas \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-ro/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-ro/strings-duckchat.xml index 15ed40b04278..573992401727 100644 --- a/duckchat/duckchat-impl/src/main/res/values-ro/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-ro/strings-duckchat.xml @@ -39,7 +39,6 @@ Duck.ai este o caracteristică opțională care îți permite să discuți anonim cu modele populare de chat AI de la terțe părți. Chaturile tale nu sunt folosite pentru a antrena AI.\nAflă mai multe Activează Duck.ai - Scurtături Meniu browser Bara de adrese Setări Assist @@ -64,7 +63,6 @@ Caracteristici AI Funcțiile IA ale DuckDuckGo sunt private și opționale.Datele tale nu sunt folosite pentru a antrena IA.\nAflă mai multe Duck.ai - Comenzi rapide Duck.ai Setări Search Assist Alege cât de des vrei să apară răspunsurile asistate de IA în căutările tale \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-ru/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-ru/strings-duckchat.xml index e1d492c53ccf..6de77a8d2c56 100644 --- a/duckchat/duckchat-impl/src/main/res/values-ru/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-ru/strings-duckchat.xml @@ -39,7 +39,6 @@ Duck.ai — дополнительная функция, позволяющая анонимно беседовать с популярными сторонними чат-моделями на базе искусственного интеллекта. Содержимое чатов не применяется для обучения ИИ.\nПодробнее... Включить Duck.ai - Ярлыки Меню браузера Адресная строка Настройки Assist @@ -64,7 +63,6 @@ Функции ИИ DuckDuckGo AI — дополнительный конфиденциальный сервис.\nВаши данные не применяются для обучения ИИ.\nПодробнее... Duck.ai - Ярлыки Duck.ai Настройки Search Assist Выберите, как часто вы хотите видеть ответы от ИИ в результатах поиска. \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-sk/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-sk/strings-duckchat.xml index 796c89529f7f..107b8d166bbc 100644 --- a/duckchat/duckchat-impl/src/main/res/values-sk/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-sk/strings-duckchat.xml @@ -39,7 +39,6 @@ Duck.ai je voliteľná funkcia, ktorá ti umožňuje anonymne chatovať s obľúbenými modelmi chatu s umelou inteligenciou tretích strán. Tvoje chaty sa nepoužívajú na trénovanie AI.\nViac informácií Povoliť Duck.ai - Skratky Ponuka prehliadača Riadok adresy Nastavenia Assist @@ -64,7 +63,6 @@ Funkcie AI Funkcie DuckDuckGo AI sú súkromné a voliteľné.\nTvoje údaje sa nepoužívajú na trénovanie umelej inteligencie.\nViac informácií Duck.ai - Skratky Duck.ai Nastavenia Assist vyhľadávania Vyber, ako často chceš, aby sa vo vyhľadávaní zobrazovali odpovede podporované AI \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-sl/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-sl/strings-duckchat.xml index 11385f25e39f..b9d21a550bc6 100644 --- a/duckchat/duckchat-impl/src/main/res/values-sl/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-sl/strings-duckchat.xml @@ -39,7 +39,6 @@ Duck.ai je izbirna funkcija, ki vam omogoča anonimen klepet s priljubljenimi modeli za klepet z umetno inteligenco drugih ponudnikov. Vaši klepeti se ne uporabljajo za usposabljanje umetne inteligence.\nVeč o tem Omogoči Duck.ai - Bližnjice Meni brskalnika Naslovna vrstica Nastavitve modula Assist @@ -64,7 +63,6 @@ Lastnosti UI Funkcije umetne inteligence DuckDuckGo so zasebne in izbirne.\nVaši podatki se ne uporabljajo za usposabljanje umetne inteligence.\nVeč o tem Duck.ai - Bližnjice do Duck.ai Nastavitve modula Search Assist Izberite, kako pogosto želite, da se odgovori s pomočjo umetne inteligence prikazujejo v vaših iskanjih \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-sv/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-sv/strings-duckchat.xml index d371f5bc4f1b..860559aeb74d 100644 --- a/duckchat/duckchat-impl/src/main/res/values-sv/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-sv/strings-duckchat.xml @@ -39,7 +39,6 @@ Duck.ai är en valfri funktion som låter dig chatta anonymt med populära AI-chattmodeller från tredje part. Dina chattar används inte för att träna AI.\nLäs mer Aktivera Duck.ai - Genvägar Webbläsarmeny Adressfält Assist-inställningar @@ -64,7 +63,6 @@ AI-funktioner DuckDuckGos AI-funktioner är privata och valfria.\nDina data används inte för att träna AI.\nLäs mer Duck.ai - Duck.ai-genvägar Inställningar för Search Assist Välj hur ofta du vill att AI-assisterade svar ska visas i dina sökningar \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values-tr/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-tr/strings-duckchat.xml index 0a6e193e9f60..dfed7b04b934 100644 --- a/duckchat/duckchat-impl/src/main/res/values-tr/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-tr/strings-duckchat.xml @@ -39,7 +39,6 @@ Duck.ai, popüler 3. taraf yapay zeka sohbet modelleriyle anonim olarak sohbet etmenizi sağlayan isteğe bağlı bir özelliktir. Sohbetler yapay zekayı eğitmek için kullanılmaz.\nDaha Fazla Bilgi Duck.ai\'ı etkinleştir - Kısayollar Tarayıcı menüsü Adres Çubuğu Assist Ayarları @@ -64,7 +63,6 @@ AI Özellikleri DuckDuckGo AI özellikleri gizli ve isteğe bağlıdır.\nVerileriniz yapay zekayı eğitmek için kullanılmaz.\nDaha Fazla Bilgi Duck.ai - Duck.ai Kısayolları Search Assist Ayarları Yapay zeka destekli yanıtların aramalarınızda ne sıklıkta görünmesini istediğinizi seçin \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values/strings-duckchat.xml index 4f2d9e0085f6..82a9ab68a64b 100644 --- a/duckchat/duckchat-impl/src/main/res/values/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values/strings-duckchat.xml @@ -38,11 +38,12 @@ Duck.ai is an optional feature that lets you chat anonymously with popular 3rd-party Al chat models. Your chats are not used to train AI.\nLearn More Enable Duck.ai - Shortcuts Browser Menu Address Bar Assist Settings Choose how often you want AI-assisted answers to appear in your searches + Duck.ai Shortcuts + Choose which Duck.ai shortcuts to display Search @@ -64,7 +65,6 @@ DuckDuckGo AI features are private and optional.\nYour data is not used to train AI.\nLearn More Duck.ai Chat privately with popular 3rd-party AI models - Duck.ai Shortcuts Search Assist Settings Choose how often you want AI-Assisted answers to appear in your searches \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/test/kotlin/com/duckduckgo/duckchat/impl/ui/settings/DuckAiShortcutSettingsViewModelTest.kt b/duckchat/duckchat-impl/src/test/kotlin/com/duckduckgo/duckchat/impl/ui/settings/DuckAiShortcutSettingsViewModelTest.kt new file mode 100644 index 000000000000..cfa5409cb2ee --- /dev/null +++ b/duckchat/duckchat-impl/src/test/kotlin/com/duckduckgo/duckchat/impl/ui/settings/DuckAiShortcutSettingsViewModelTest.kt @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2025 DuckDuckGo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.duckduckgo.duckchat.impl.ui.settings + +import app.cash.turbine.test +import com.duckduckgo.common.test.CoroutineTestRule +import com.duckduckgo.duckchat.impl.DuckChatInternal +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +class DuckAiShortcutSettingsViewModelTest { + + @get:Rule + @Suppress("unused") + val coroutineRule = CoroutineTestRule() + + private lateinit var testee: DuckAiShortcutSettingsViewModel + + private val duckChat: DuckChatInternal = mock() + + @Before + fun setUp() = runTest { + whenever(duckChat.observeShowInBrowserMenuUserSetting()).thenReturn(flowOf(false)) + whenever(duckChat.observeShowInAddressBarUserSetting()).thenReturn(flowOf(false)) + testee = DuckAiShortcutSettingsViewModel(duckChat) + } + + @Test + fun whenViewModelIsCreatedAndShowInBrowserIsEnabledThenEmitEnabled() = runTest { + whenever(duckChat.observeShowInBrowserMenuUserSetting()).thenReturn(flowOf(true)) + testee = DuckAiShortcutSettingsViewModel(duckChat) + + testee.viewState.test { + assertTrue(awaitItem().showInBrowserMenu) + } + } + + @Test + fun whenViewModelIsCreatedAndShowInBrowserIsDisabledThenEmitDisabled() = runTest { + whenever(duckChat.observeShowInBrowserMenuUserSetting()).thenReturn(flowOf(false)) + testee = DuckAiShortcutSettingsViewModel(duckChat) + + testee.viewState.test { + assertFalse(awaitItem().showInBrowserMenu) + } + } + + @Test + fun whenViewModelIsCreatedAndShowInAddressBarIsEnabledThenEmitEnabled() = runTest { + whenever(duckChat.observeShowInAddressBarUserSetting()).thenReturn(flowOf(true)) + testee = DuckAiShortcutSettingsViewModel(duckChat) + + testee.viewState.test { + assertTrue(awaitItem().showInAddressBar) + } + } + + @Test + fun whenViewModelIsCreatedAndShowInAddressBarIsDisabledThenEmitDisabled() = runTest { + whenever(duckChat.observeShowInAddressBarUserSetting()).thenReturn(flowOf(false)) + testee = DuckAiShortcutSettingsViewModel(duckChat) + + testee.viewState.test { + assertFalse(awaitItem().showInAddressBar) + } + } + + @Test + fun whenAddressBarEntryPointEnabledTogglesShown() = runTest { + whenever(duckChat.isAddressBarEntryPointEnabled()).thenReturn(true) + testee = DuckAiShortcutSettingsViewModel(duckChat) + + testee.viewState.test { + val state = awaitItem() + assertTrue(state.shouldShowAddressBarToggle) + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun whenAddressBarEntryPointDisabledThenToggleHidden() = runTest { + whenever(duckChat.isAddressBarEntryPointEnabled()).thenReturn(false) + testee = DuckAiShortcutSettingsViewModel(duckChat) + + testee.viewState.test { + val state = awaitItem() + assertFalse(state.shouldShowAddressBarToggle) + } + } +} diff --git a/duckchat/duckchat-impl/src/test/kotlin/com/duckduckgo/duckchat/impl/ui/DuckChatSettingsViewModelTest.kt b/duckchat/duckchat-impl/src/test/kotlin/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsViewModelTest.kt similarity index 69% rename from duckchat/duckchat-impl/src/test/kotlin/com/duckduckgo/duckchat/impl/ui/DuckChatSettingsViewModelTest.kt rename to duckchat/duckchat-impl/src/test/kotlin/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsViewModelTest.kt index 52dd1761b9c9..d81f6dc10c83 100644 --- a/duckchat/duckchat-impl/src/test/kotlin/com/duckduckgo/duckchat/impl/ui/DuckChatSettingsViewModelTest.kt +++ b/duckchat/duckchat-impl/src/test/kotlin/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsViewModelTest.kt @@ -14,16 +14,16 @@ * limitations under the License. */ -package com.duckduckgo.duckchat.impl.ui +package com.duckduckgo.duckchat.impl.ui.settings import app.cash.turbine.test import com.duckduckgo.app.statistics.pixels.Pixel import com.duckduckgo.common.test.CoroutineTestRule -import com.duckduckgo.common.ui.experiments.visual.store.ExperimentalThemingDataStore import com.duckduckgo.duckchat.impl.DuckChatInternal import com.duckduckgo.duckchat.impl.pixel.DuckChatPixelName -import com.duckduckgo.duckchat.impl.ui.DuckChatSettingsViewModel.Command.OpenLink -import com.duckduckgo.duckchat.impl.ui.DuckChatSettingsViewModel.Command.OpenLinkInNewTab +import com.duckduckgo.duckchat.impl.ui.settings.DuckChatSettingsViewModel.Command.OpenLink +import com.duckduckgo.duckchat.impl.ui.settings.DuckChatSettingsViewModel.Command.OpenLinkInNewTab +import com.duckduckgo.duckchat.impl.ui.settings.DuckChatSettingsViewModel.Command.OpenShortcutSettings import com.duckduckgo.subscriptions.api.SubscriptionRebrandingFeatureToggle import junit.framework.TestCase.assertEquals import kotlinx.coroutines.flow.flowOf @@ -47,7 +47,6 @@ class DuckChatSettingsViewModelTest { private val duckChat: DuckChatInternal = mock() private val mockPixel: Pixel = mock() - private val mockExperimentalThemingDataStore: ExperimentalThemingDataStore = mock() private val mockRebrandingFeatureToggle: SubscriptionRebrandingFeatureToggle = mock() @Before @@ -56,7 +55,7 @@ class DuckChatSettingsViewModelTest { whenever(duckChat.observeShowInBrowserMenuUserSetting()).thenReturn(flowOf(false)) whenever(duckChat.observeShowInAddressBarUserSetting()).thenReturn(flowOf(false)) whenever(duckChat.observeInputScreenUserSettingEnabled()).thenReturn(flowOf(false)) - testee = DuckChatSettingsViewModel(duckChat, mockPixel, mockExperimentalThemingDataStore, mockRebrandingFeatureToggle) + testee = DuckChatSettingsViewModel(duckChat, mockPixel, mockRebrandingFeatureToggle) } @Test @@ -107,78 +106,11 @@ class DuckChatSettingsViewModelTest { verify(duckChat).setInputScreenUserSetting(false) } - @Test - fun whenViewModelIsCreatedAndShowInBrowserIsEnabledThenEmitEnabled() = runTest { - whenever(duckChat.observeShowInBrowserMenuUserSetting()).thenReturn(flowOf(true)) - testee = DuckChatSettingsViewModel(duckChat, mockPixel, mockExperimentalThemingDataStore, mockRebrandingFeatureToggle) - - testee.viewState.test { - assertTrue(awaitItem().showInBrowserMenu) - } - } - - @Test - fun whenViewModelIsCreatedAndShowInBrowserIsDisabledThenEmitDisabled() = runTest { - whenever(duckChat.observeShowInBrowserMenuUserSetting()).thenReturn(flowOf(false)) - testee = DuckChatSettingsViewModel(duckChat, mockPixel, mockExperimentalThemingDataStore, mockRebrandingFeatureToggle) - - testee.viewState.test { - assertFalse(awaitItem().showInBrowserMenu) - } - } - - @Test - fun whenViewModelIsCreatedAndShowInAddressBarIsEnabledThenEmitEnabled() = runTest { - whenever(duckChat.observeShowInAddressBarUserSetting()).thenReturn(flowOf(true)) - testee = DuckChatSettingsViewModel(duckChat, mockPixel, mockExperimentalThemingDataStore, mockRebrandingFeatureToggle) - - testee.viewState.test { - assertTrue(awaitItem().showInAddressBar) - } - } - - @Test - fun whenViewModelIsCreatedAndShowInAddressBarIsDisabledThenEmitDisabled() = runTest { - whenever(duckChat.observeShowInAddressBarUserSetting()).thenReturn(flowOf(false)) - testee = DuckChatSettingsViewModel(duckChat, mockPixel, mockExperimentalThemingDataStore, mockRebrandingFeatureToggle) - - testee.viewState.test { - assertFalse(awaitItem().showInAddressBar) - } - } - - @Test - fun whenDuckChatEnabledAndAddressBarEntryPointEnabledThenBothSubTogglesShown() = runTest { - whenever(duckChat.observeEnableDuckChatUserSetting()).thenReturn(flowOf(true)) - whenever(duckChat.isAddressBarEntryPointEnabled()).thenReturn(true) - testee = DuckChatSettingsViewModel(duckChat, mockPixel, mockExperimentalThemingDataStore, mockRebrandingFeatureToggle) - - testee.viewState.test { - val state = awaitItem() - assertTrue(state.shouldShowBrowserMenuToggle) - assertTrue(state.shouldShowAddressBarToggle) - cancelAndIgnoreRemainingEvents() - } - } - - @Test - fun whenDuckChatEnabledAndAddressBarEntryPointDisabledThenOnlyBrowserToggleShown() = runTest { - whenever(duckChat.observeInputScreenUserSettingEnabled()).thenReturn(flowOf(false)) - whenever(duckChat.observeEnableDuckChatUserSetting()).thenReturn(flowOf(true)) - whenever(duckChat.isAddressBarEntryPointEnabled()).thenReturn(false) - testee = DuckChatSettingsViewModel(duckChat, mockPixel, mockExperimentalThemingDataStore, mockRebrandingFeatureToggle) - - testee.viewState.test { - val state = awaitItem() - assertTrue(state.shouldShowBrowserMenuToggle) - assertFalse(state.shouldShowAddressBarToggle) - } - } @Test fun `input screen - user preference enabled then set correct state`() = runTest { whenever(duckChat.observeInputScreenUserSettingEnabled()).thenReturn(flowOf(true)) - testee = DuckChatSettingsViewModel(duckChat, mockPixel, mockExperimentalThemingDataStore, mockRebrandingFeatureToggle) + testee = DuckChatSettingsViewModel(duckChat, mockPixel, mockRebrandingFeatureToggle) testee.viewState.test { assertTrue(awaitItem().isInputScreenEnabled) @@ -188,7 +120,7 @@ class DuckChatSettingsViewModelTest { @Test fun `input screen - user preference disabled then set correct state`() = runTest { whenever(duckChat.observeInputScreenUserSettingEnabled()).thenReturn(flowOf(false)) - testee = DuckChatSettingsViewModel(duckChat, mockPixel, mockExperimentalThemingDataStore, mockRebrandingFeatureToggle) + testee = DuckChatSettingsViewModel(duckChat, mockPixel, mockRebrandingFeatureToggle) testee.viewState.test { assertFalse(awaitItem().isInputScreenEnabled) @@ -199,7 +131,7 @@ class DuckChatSettingsViewModelTest { fun `input screen - when duck chat enabled and flag enabled, then emit enabled`() = runTest { whenever(duckChat.observeEnableDuckChatUserSetting()).thenReturn(flowOf(true)) whenever(duckChat.isInputScreenFeatureAvailable()).thenReturn(true) - testee = DuckChatSettingsViewModel(duckChat, mockPixel, mockExperimentalThemingDataStore, mockRebrandingFeatureToggle) + testee = DuckChatSettingsViewModel(duckChat, mockPixel, mockRebrandingFeatureToggle) testee.viewState.test { val state = awaitItem() @@ -211,7 +143,7 @@ class DuckChatSettingsViewModelTest { fun `input screen - when flag disabled, then emit disabled`() = runTest { whenever(duckChat.observeEnableDuckChatUserSetting()).thenReturn(flowOf(true)) whenever(duckChat.isInputScreenFeatureAvailable()).thenReturn(false) - testee = DuckChatSettingsViewModel(duckChat, mockPixel, mockExperimentalThemingDataStore, mockRebrandingFeatureToggle) + testee = DuckChatSettingsViewModel(duckChat, mockPixel, mockRebrandingFeatureToggle) testee.viewState.test { val state = awaitItem() @@ -222,14 +154,11 @@ class DuckChatSettingsViewModelTest { @Test fun whenDuckChatDisabledThenNoSubTogglesShown() = runTest { whenever(duckChat.observeEnableDuckChatUserSetting()).thenReturn(flowOf(false)) - whenever(duckChat.isAddressBarEntryPointEnabled()).thenReturn(true) whenever(duckChat.observeInputScreenUserSettingEnabled()).thenReturn(flowOf(true)) - testee = DuckChatSettingsViewModel(duckChat, mockPixel, mockExperimentalThemingDataStore, mockRebrandingFeatureToggle) + testee = DuckChatSettingsViewModel(duckChat, mockPixel, mockRebrandingFeatureToggle) testee.viewState.test { val state = awaitItem() - assertFalse(state.shouldShowBrowserMenuToggle) - assertFalse(state.shouldShowAddressBarToggle) assertFalse(state.shouldShowInputScreenToggle) } } @@ -319,4 +248,15 @@ class DuckChatSettingsViewModelTest { testee.onShowDuckChatInAddressBarToggled(false) verify(mockPixel).fire(DuckChatPixelName.DUCK_CHAT_SEARCHBAR_SETTING_OFF) } + + @Test + fun `when Duck ai shortcuts clicked, then dispatch launch command`() = runTest { + testee.onDuckAiShortcutsClicked() + + testee.commands.test { + val command = awaitItem() + assertTrue(command is OpenShortcutSettings) + cancelAndIgnoreRemainingEvents() + } + } } From 75f221ad8d314dcd8e0ba24da14f37bc76f4365d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 14 Aug 2025 14:03:16 +0200 Subject: [PATCH 3/9] update Input Screen settings toggle --- .../input_screen/input_screen_chat_mode.yaml | 4 +- .../input_screen_preference_management.yaml | 4 +- .../input_screen_search_mode.yaml | 4 +- .../res/values/design-experiments-theming.xml | 2 + .../main/res/values/design-system-colors.xml | 1 + .../ui/settings/DuckChatSettingsActivity.kt | 81 +++++++++++-- .../ui/settings/DuckChatSettingsViewModel.kt | 32 +++-- .../res/drawable/searchbox_background.xml | 24 ++++ .../drawable/searchbox_background_active.xml | 28 +++++ .../main/res/drawable/searchbox_withai.xml | 31 +++++ .../res/drawable/searchbox_withai_active.xml | 38 ++++++ .../main/res/drawable/searchbox_withoutai.xml | 38 ++++++ .../drawable/searchbox_withoutai_active.xml | 38 ++++++ .../layout/activity_duck_chat_settings.xml | 112 ++++++++++++++++-- .../main/res/values-bg/strings-duckchat.xml | 2 - .../main/res/values-cs/strings-duckchat.xml | 2 - .../main/res/values-da/strings-duckchat.xml | 2 - .../main/res/values-de/strings-duckchat.xml | 2 - .../main/res/values-el/strings-duckchat.xml | 2 - .../main/res/values-es/strings-duckchat.xml | 2 - .../main/res/values-et/strings-duckchat.xml | 2 - .../main/res/values-fi/strings-duckchat.xml | 2 - .../main/res/values-fr/strings-duckchat.xml | 2 - .../main/res/values-hr/strings-duckchat.xml | 2 - .../main/res/values-hu/strings-duckchat.xml | 2 - .../main/res/values-it/strings-duckchat.xml | 2 - .../main/res/values-lt/strings-duckchat.xml | 2 - .../main/res/values-lv/strings-duckchat.xml | 2 - .../main/res/values-nb/strings-duckchat.xml | 2 - .../main/res/values-nl/strings-duckchat.xml | 2 - .../main/res/values-pl/strings-duckchat.xml | 2 - .../main/res/values-pt/strings-duckchat.xml | 2 - .../main/res/values-ro/strings-duckchat.xml | 2 - .../main/res/values-ru/strings-duckchat.xml | 2 - .../main/res/values-sk/strings-duckchat.xml | 2 - .../main/res/values-sl/strings-duckchat.xml | 2 - .../main/res/values-sv/strings-duckchat.xml | 2 - .../src/main/res/values-sw600dp/dimens.xml | 19 +++ .../main/res/values-tr/strings-duckchat.xml | 2 - .../src/main/res/values/dimens.xml | 1 + .../src/main/res/values/strings-duckchat.xml | 5 +- .../settings/DuckChatSettingsViewModelTest.kt | 29 +++-- 42 files changed, 445 insertions(+), 94 deletions(-) create mode 100644 duckchat/duckchat-impl/src/main/res/drawable/searchbox_background.xml create mode 100644 duckchat/duckchat-impl/src/main/res/drawable/searchbox_background_active.xml create mode 100644 duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai.xml create mode 100644 duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_active.xml create mode 100644 duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai.xml create mode 100644 duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_active.xml create mode 100644 duckchat/duckchat-impl/src/main/res/values-sw600dp/dimens.xml diff --git a/.maestro/input_screen/input_screen_chat_mode.yaml b/.maestro/input_screen/input_screen_chat_mode.yaml index 9bb47b39c6a4..feb1f9c6e0d3 100644 --- a/.maestro/input_screen/input_screen_chat_mode.yaml +++ b/.maestro/input_screen/input_screen_chat_mode.yaml @@ -14,9 +14,7 @@ tags: # enable the Input Screen - runFlow: ../shared/open_ai_settings_screen.yaml - tapOn: - id: "trailingSwitch" - childOf: - id: "duckAiInputScreenEnabledToggle" + id: "duckAiInputScreenToggleWithAiImage" - action: back - action: back diff --git a/.maestro/input_screen/input_screen_preference_management.yaml b/.maestro/input_screen/input_screen_preference_management.yaml index 9d4e82a240b3..2b9844dca081 100644 --- a/.maestro/input_screen/input_screen_preference_management.yaml +++ b/.maestro/input_screen/input_screen_preference_management.yaml @@ -20,9 +20,7 @@ tags: # enable the Input Screen - runFlow: ../shared/open_ai_settings_screen.yaml - tapOn: - id: "trailingSwitch" - childOf: - id: "duckAiInputScreenEnabledToggle" + id: "duckAiInputScreenToggleWithAiImage" - action: back - action: back diff --git a/.maestro/input_screen/input_screen_search_mode.yaml b/.maestro/input_screen/input_screen_search_mode.yaml index a9148cd59132..77312593f355 100644 --- a/.maestro/input_screen/input_screen_search_mode.yaml +++ b/.maestro/input_screen/input_screen_search_mode.yaml @@ -14,9 +14,7 @@ tags: # enable the Input Screen - runFlow: ../shared/open_ai_settings_screen.yaml - tapOn: - id: "trailingSwitch" - childOf: - id: "duckAiInputScreenEnabledToggle" + id: "duckAiInputScreenToggleWithAiImage" - action: back - action: back diff --git a/common/common-ui/src/main/res/values/design-experiments-theming.xml b/common/common-ui/src/main/res/values/design-experiments-theming.xml index 694d1e0a58e0..e102c73a0266 100644 --- a/common/common-ui/src/main/res/values/design-experiments-theming.xml +++ b/common/common-ui/src/main/res/values/design-experiments-theming.xml @@ -40,6 +40,7 @@ @color/controls_fill_primary_dark @color/controls_fill_secondary_dark @color/controls_fill_tertiary_dark + @color/controls_decoration_tertiary_dark ?attr/daxColorBackground @@ -83,6 +84,7 @@ @color/controls_fill_primary_light @color/controls_fill_secondary_light @color/controls_fill_tertiary_light + @color/controls_decoration_tertiary_light ?attr/daxColorBackground diff --git a/common/common-ui/src/main/res/values/design-system-colors.xml b/common/common-ui/src/main/res/values/design-system-colors.xml index 3c6e025e93a6..50a6a0dbaa6c 100644 --- a/common/common-ui/src/main/res/values/design-system-colors.xml +++ b/common/common-ui/src/main/res/values/design-system-colors.xml @@ -74,6 +74,7 @@ + diff --git a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt index 8089daf6e521..5daf8db7407e 100644 --- a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt +++ b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt @@ -61,11 +61,6 @@ class DuckChatSettingsActivity : DuckDuckGoActivity() { viewModel.onDuckChatUserEnabledToggled(isChecked) } - private val inputScreenToggleListener = - CompoundButton.OnCheckedChangeListener { _, isChecked -> - viewModel.onDuckAiInputScreenToggled(isChecked) - } - @Inject lateinit var globalActivityStarter: GlobalActivityStarter @@ -135,18 +130,38 @@ class DuckChatSettingsActivity : DuckDuckGoActivity() { ), ) - binding.duckAiInputScreenEnabledToggle.apply { - isVisible = viewState.shouldShowInputScreenToggle - quietlySetIsChecked(viewState.isInputScreenEnabled, inputScreenToggleListener) - } + binding.duckAiInputScreenToggleContainer.isVisible = viewState.shouldShowInputScreenToggle + configureInputScreenToggle( + withoutAi = InputScreenToggleButton.WithoutAi(isActive = !viewState.isInputScreenEnabled), + withAi = InputScreenToggleButton.WithAi(isActive = viewState.isInputScreenEnabled), + ) + + binding.duckAiInputScreenDescription.isVisible = viewState.shouldShowInputScreenToggle + binding.duckAiInputScreenDescription.addClickableSpan( + textSequence = getText(R.string.input_screen_user_pref_description), + spans = listOf( + "share_feedback" to object : DuckDuckGoClickableSpan() { + override fun onClick(widget: View) { + viewModel.duckAiInputScreenShareFeedbackClicked() + } + }, + ), + ) binding.duckAiShortcuts.isVisible = viewState.shouldShowShortcuts binding.duckAiShortcuts.setOnClickListener { viewModel.onDuckAiShortcutsClicked() } + binding.showDuckChatSearchSettingsLink.setOnClickListener { viewModel.duckChatSearchAISettingsClicked() } + binding.duckAiInputScreenWithoutAiContainer.setOnClickListener { + viewModel.onDuckAiInputScreenWithoutAiSelected() + } + binding.duckAiInputScreenWithAiContainer.setOnClickListener { + viewModel.onDuckAiInputScreenWithAiSelected() + } } private fun processCommand(command: DuckChatSettingsViewModel.Command) { @@ -168,6 +183,54 @@ class DuckChatSettingsActivity : DuckDuckGoActivity() { val intent = Intent(this, DuckAiShortcutSettingsActivity::class.java) startActivity(intent) } + + is DuckChatSettingsViewModel.Command.LaunchFeedback -> { + globalActivityStarter.start(this, FeedbackActivityWithEmptyParams) + } + } + } + + private fun configureInputScreenToggle( + withoutAi: InputScreenToggleButton, + withAi: InputScreenToggleButton, + ) = with(binding) { + val context = this@DuckChatSettingsActivity + duckAiInputScreenToggleWithoutAiImage.setImageDrawable(ContextCompat.getDrawable(context, withoutAi.imageRes)) + duckAiInputScreenToggleWithoutAiImage.setBackgroundResource(withoutAi.backgroundRes) + duckAiInputScreenToggleWithoutAiCheck.setImageDrawable(ContextCompat.getDrawable(context, withoutAi.checkRes)) + + duckAiInputScreenToggleWithAiImage.setImageDrawable(ContextCompat.getDrawable(context, withAi.imageRes)) + duckAiInputScreenToggleWithAiImage.setBackgroundResource(withAi.backgroundRes) + duckAiInputScreenToggleWithAiCheck.setImageDrawable(ContextCompat.getDrawable(context, withAi.checkRes)) + } + + private sealed class InputScreenToggleButton(isActive: Boolean) { + abstract val imageRes: Int + val backgroundRes: Int = if (isActive) { + R.drawable.searchbox_background_active + } else { + R.drawable.searchbox_background + } + val checkRes: Int = if (isActive) { + CommonR.drawable.ic_check_blue_round_24 + } else { + CommonR.drawable.ic_shape_circle_24 + } + + class WithoutAi(isActive: Boolean): InputScreenToggleButton(isActive) { + override val imageRes: Int = if (isActive) { + R.drawable.searchbox_withoutai_active + } else { + R.drawable.searchbox_withoutai + } + } + + class WithAi(isActive: Boolean): InputScreenToggleButton(isActive) { + override val imageRes: Int = if (isActive) { + R.drawable.searchbox_withai_active + } else { + R.drawable.searchbox_withai + } } } } diff --git a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsViewModel.kt b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsViewModel.kt index d0c55884ff30..2a8ec919d589 100644 --- a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsViewModel.kt +++ b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsViewModel.kt @@ -71,6 +71,7 @@ class DuckChatSettingsViewModel @Inject constructor( data class OpenLink(val link: String) : Command() data class OpenLinkInNewTab(val link: String) : Command() data object OpenShortcutSettings : Command() + data object LaunchFeedback : Command() } fun onDuckChatUserEnabledToggled(checked: Boolean) { @@ -84,17 +85,6 @@ class DuckChatSettingsViewModel @Inject constructor( } } - fun onDuckAiInputScreenToggled(checked: Boolean) { - viewModelScope.launch { - if (checked) { - pixel.fire(DuckChatPixelName.DUCK_CHAT_EXPERIMENTAL_ADDRESS_BAR_SETTING_ON) - } else { - pixel.fire(DuckChatPixelName.DUCK_CHAT_EXPERIMENTAL_ADDRESS_BAR_SETTING_OFF) - } - duckChat.setInputScreenUserSetting(checked) - } - } - fun onShowDuckChatInMenuToggled(checked: Boolean) { viewModelScope.launch { if (checked) { @@ -136,6 +126,26 @@ class DuckChatSettingsViewModel @Inject constructor( } } + fun onDuckAiInputScreenWithoutAiSelected() { + viewModelScope.launch { + pixel.fire(DuckChatPixelName.DUCK_CHAT_EXPERIMENTAL_ADDRESS_BAR_SETTING_OFF) + duckChat.setInputScreenUserSetting(enabled = false) + } + } + + fun onDuckAiInputScreenWithAiSelected() { + viewModelScope.launch { + pixel.fire(DuckChatPixelName.DUCK_CHAT_EXPERIMENTAL_ADDRESS_BAR_SETTING_ON) + duckChat.setInputScreenUserSetting(enabled = true) + } + } + + fun duckAiInputScreenShareFeedbackClicked() { + viewModelScope.launch { + commandChannel.send(Command.LaunchFeedback) + } + } + companion object { const val DUCK_CHAT_LEARN_MORE_LINK = "https://duckduckgo.com/duckduckgo-help-pages/aichat/" const val DUCK_CHAT_SEARCH_AI_SETTINGS_LINK = "https://duckduckgo.com/settings?ko=-1#aifeatures" diff --git a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_background.xml b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_background.xml new file mode 100644 index 000000000000..92e9b8608745 --- /dev/null +++ b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_background.xml @@ -0,0 +1,24 @@ + + + + + + + + + \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_background_active.xml b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_background_active.xml new file mode 100644 index 000000000000..0fa50d58b7ff --- /dev/null +++ b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_background_active.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai.xml b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai.xml new file mode 100644 index 000000000000..ec49ef7b558b --- /dev/null +++ b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai.xml @@ -0,0 +1,31 @@ + + + + + + + diff --git a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_active.xml b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_active.xml new file mode 100644 index 000000000000..00336913a387 --- /dev/null +++ b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_active.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + diff --git a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai.xml b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai.xml new file mode 100644 index 000000000000..a03ae10c531f --- /dev/null +++ b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + diff --git a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_active.xml b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_active.xml new file mode 100644 index 000000000000..4c001cf046be --- /dev/null +++ b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_active.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + diff --git a/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml b/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml index dabaf6511d24..11fc28969026 100644 --- a/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml +++ b/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml @@ -19,7 +19,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".ui.DuckChatSettingsActivity"> + tools:context=".ui.settings.DuckChatSettingsActivity"> - + android:layout_marginTop="@dimen/keyline_4" + android:layout_marginHorizontal="@dimen/keyline_4"> + + + + + + + + + + + + + + + + + + + + + + + + Търсене или въвеждане на адрес Duck.ai Попитай Duck.ai - Експериментална адресна лента - Потърсете в мрежата или попитайте Duck.ai директно от адресната лента Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-cs/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-cs/strings-duckchat.xml index 01a920ffd2ea..5ef8d96db45e 100644 --- a/duckchat/duckchat-impl/src/main/res/values-cs/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-cs/strings-duckchat.xml @@ -49,8 +49,6 @@ Vyhledejte nebo zadejte adresu Duck.ai Zeptej se Duck.ai - Experimentální adresní řádek - Hledej na webu nebo se zeptej Duck.ai přímo v adresním řádku. Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-da/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-da/strings-duckchat.xml index 32023ee913f0..da48fa695fe5 100644 --- a/duckchat/duckchat-impl/src/main/res/values-da/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-da/strings-duckchat.xml @@ -49,8 +49,6 @@ Søg eller indtast adresse Duck.ai Spørg Duck.ai - Eksperimentel adresselinje - Søg på nettet eller spørg Duck.ai direkte fra adresselinjen Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-de/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-de/strings-duckchat.xml index 5d644a211902..6f47e9c615bc 100644 --- a/duckchat/duckchat-impl/src/main/res/values-de/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-de/strings-duckchat.xml @@ -49,8 +49,6 @@ Adresse suchen oder eingeben Duck.ai Frag Duck.ai - Experimentelle Adressleiste - Suche im Web oder frag Duck.ai direkt über die Adressleiste Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-el/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-el/strings-duckchat.xml index b821f998196e..f9dfe1e6fe78 100644 --- a/duckchat/duckchat-impl/src/main/res/values-el/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-el/strings-duckchat.xml @@ -49,8 +49,6 @@ Αναζήτηση ή εισαγωγή διεύθυνσης Duck.ai Ρωτήστε το Duck.ai - Πειραματική γραμμή διευθύνσεων - Κάντε αναζήτηση στο διαδίκτυο ή ρωτήστε το Duck.ai απευθείας από τη Γραμμή διευθύνσεων Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-es/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-es/strings-duckchat.xml index 534a58bc1222..07b538032318 100644 --- a/duckchat/duckchat-impl/src/main/res/values-es/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-es/strings-duckchat.xml @@ -49,8 +49,6 @@ Buscar o introducir dirección Duck.ai Pregúntale a Duck.ai - Barra de direcciones experimental - Busca en la web o pregúntale a Duck.ai directamente desde la barra de direcciones Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-et/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-et/strings-duckchat.xml index 3847ae24b6ed..0f5c674e2233 100644 --- a/duckchat/duckchat-impl/src/main/res/values-et/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-et/strings-duckchat.xml @@ -49,8 +49,6 @@ Otsi või sisesta aadress Duck.ai Küsi Duck.ai käest - Eksperimentaalne aadressiriba - Otsi veebist või küsi Duck.ai-lt otse aadressiribal Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-fi/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-fi/strings-duckchat.xml index 229a5afb3ebb..ff2966177f6f 100644 --- a/duckchat/duckchat-impl/src/main/res/values-fi/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-fi/strings-duckchat.xml @@ -49,8 +49,6 @@ Hae tai anna osoite Duck.ai Kysy Duck.ai:lta - Kokeellinen osoitekenttä - Hae verkosta tai kysy Duck.ai:lta kirjoittamalla suoraan osoiteriville Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-fr/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-fr/strings-duckchat.xml index e5eefc386859..3b7956d3a77b 100644 --- a/duckchat/duckchat-impl/src/main/res/values-fr/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-fr/strings-duckchat.xml @@ -49,8 +49,6 @@ Rechercher ou saisir une adresse Duck.ai Demandez à Duck.ai - Barre d\'adresse expérimentale - Effectuez une recherche sur le Web ou interrogez Duck.ai directement à partir de la barre d’adresse Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-hr/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-hr/strings-duckchat.xml index ed89d1ef95ed..8b716c3fab42 100644 --- a/duckchat/duckchat-impl/src/main/res/values-hr/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-hr/strings-duckchat.xml @@ -49,8 +49,6 @@ Pretraži ili unesi adresu Duck.ai Pitaj Duck.ai - Eksperimentalna adresna traka - Pretraži mrežu ili pitaj Duck.ai izravno iz adresne trake Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-hu/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-hu/strings-duckchat.xml index 0e047a79ed8f..2ce86c4e1f6f 100644 --- a/duckchat/duckchat-impl/src/main/res/values-hu/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-hu/strings-duckchat.xml @@ -49,8 +49,6 @@ Keresés vagy cím megadása Duck.ai Duck.ai kérdezése - Kísérleti címsor - Keresés a weben vagy a Duck.ai megkérdezése közvetlenül a címsorból Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-it/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-it/strings-duckchat.xml index dfa527fae3c0..2efad85de650 100644 --- a/duckchat/duckchat-impl/src/main/res/values-it/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-it/strings-duckchat.xml @@ -49,8 +49,6 @@ Cerca o digita l\'indirizzo Duck.ai Chiedi a Duck.ai - Barra degli indirizzi sperimentale - Cerca sul web o chiedi a Duck.ai direttamente dalla barra degli indirizzi Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-lt/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-lt/strings-duckchat.xml index 5cbe75429a37..6e2e71c86755 100644 --- a/duckchat/duckchat-impl/src/main/res/values-lt/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-lt/strings-duckchat.xml @@ -49,8 +49,6 @@ Ieškoti arba įvesti adresą Duck.ai Paklausk „Duck.ai“ - Eksperimentinė adreso juosta - Ieškok internete arba klausk „Duck.ai“ tiesiai iš adreso juostos Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-lv/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-lv/strings-duckchat.xml index cc00b090cfd5..e9434cc1bcf5 100644 --- a/duckchat/duckchat-impl/src/main/res/values-lv/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-lv/strings-duckchat.xml @@ -49,8 +49,6 @@ Meklē vai ievadi adresi Duck.ai Pajautā Duck.ai - Eksperimentālā adreses josla - Meklē tīmeklī vai jautā Duck.ai tieši adrešu joslā Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-nb/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-nb/strings-duckchat.xml index 60780367b59e..cb89f9793bd6 100644 --- a/duckchat/duckchat-impl/src/main/res/values-nb/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-nb/strings-duckchat.xml @@ -49,8 +49,6 @@ Søk eller skriv inn adresse Duck.ai Spør Duck.ai - Eksperimentell adresselinje - Søk på nettet eller spør Duck.ai direkte fra adressefeltet Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-nl/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-nl/strings-duckchat.xml index d6a58a9fd35f..f03d8a563bf5 100644 --- a/duckchat/duckchat-impl/src/main/res/values-nl/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-nl/strings-duckchat.xml @@ -49,8 +49,6 @@ Zoek of voer een adres in Duck.ai Vraag stellen aan Duck.ai - Experimentele adresbalk - Zoeken op het web of direct een vraag stellen aan Duck.ai vanuit de adresbalk Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-pl/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-pl/strings-duckchat.xml index 80b607932cf7..93ce8c3afe11 100644 --- a/duckchat/duckchat-impl/src/main/res/values-pl/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-pl/strings-duckchat.xml @@ -49,8 +49,6 @@ Wyszukaj lub wprowadź adres Duck.ai Zapytaj Duck.ai - Eksperymentalny Pasek Adresu - Wyszukaj w Internecie lub zapytaj Duck.ai bezpośrednio z paska adresu Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-pt/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-pt/strings-duckchat.xml index ed4bfa522b76..7b5cc8ecb1f6 100644 --- a/duckchat/duckchat-impl/src/main/res/values-pt/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-pt/strings-duckchat.xml @@ -49,8 +49,6 @@ Pesquisar ou inserir endereço Duck.ai Pergunta ao Duck.ai - Barra de endereços experimental - Pesquise na web ou pergunte diretamente ao Duck.ai na barra de endereços Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-ro/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-ro/strings-duckchat.xml index 573992401727..802af54372ab 100644 --- a/duckchat/duckchat-impl/src/main/res/values-ro/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-ro/strings-duckchat.xml @@ -49,8 +49,6 @@ Caută sau introdu adresa Duck.ai Întreabă Duck.ai - Bară de adrese experimentală - Caută pe web sau întreabă Duck.ai direct din bara de adrese Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-ru/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-ru/strings-duckchat.xml index 6de77a8d2c56..9ad4a742345d 100644 --- a/duckchat/duckchat-impl/src/main/res/values-ru/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-ru/strings-duckchat.xml @@ -49,8 +49,6 @@ Введите поисковый запрос или адрес сайта Duck.ai Спросить у Duck.ai - Пробная адресная строка - Выполнить поиск в интернете или задать вопрос ИИ-ассистенту Duck.ai можно прямо из адресной строки. Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-sk/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-sk/strings-duckchat.xml index 107b8d166bbc..052f7286a283 100644 --- a/duckchat/duckchat-impl/src/main/res/values-sk/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-sk/strings-duckchat.xml @@ -49,8 +49,6 @@ Vyhľadajte alebo zadajte adresu Duck.ai Spýtaj sa Duck.ai - Experimentálny riadok adresy - Vyhľadaj na webe alebo sa opýtaj Duck.ai priamo z riadku pre adresu Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-sl/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-sl/strings-duckchat.xml index b9d21a550bc6..0157be7f17e8 100644 --- a/duckchat/duckchat-impl/src/main/res/values-sl/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-sl/strings-duckchat.xml @@ -49,8 +49,6 @@ Poišči ali vnesi naslov Duck.ai Vprašajte Duck.ai - Eksperimentalna naslovna vrstica - Išči po spletu ali vprašaj Duck.ai neposredno iz naslovne vrstice Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-sv/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-sv/strings-duckchat.xml index 860559aeb74d..cabcab2935e4 100644 --- a/duckchat/duckchat-impl/src/main/res/values-sv/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-sv/strings-duckchat.xml @@ -49,8 +49,6 @@ Sök eller ange adress Duck.ai Fråga Duck.ai - Experimentell adressfält - Sök på webben eller fråga Duck.ai direkt i adressfältet Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values-sw600dp/dimens.xml b/duckchat/duckchat-impl/src/main/res/values-sw600dp/dimens.xml new file mode 100644 index 000000000000..440a2c1ae035 --- /dev/null +++ b/duckchat/duckchat-impl/src/main/res/values-sw600dp/dimens.xml @@ -0,0 +1,19 @@ + + + + 160dp + diff --git a/duckchat/duckchat-impl/src/main/res/values-tr/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values-tr/strings-duckchat.xml index dfed7b04b934..29d7fbfee455 100644 --- a/duckchat/duckchat-impl/src/main/res/values-tr/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values-tr/strings-duckchat.xml @@ -49,8 +49,6 @@ Adres ara veya gir Duck.ai Duck.ai\'a sor - Deneysel Adres Çubuğu - Web\'de arama yapın veya doğrudan Adres Çubuğundan Duck.ai\'a sorun Duck.ai diff --git a/duckchat/duckchat-impl/src/main/res/values/dimens.xml b/duckchat/duckchat-impl/src/main/res/values/dimens.xml index 1d31b9523d65..67f1d03b2f99 100644 --- a/duckchat/duckchat-impl/src/main/res/values/dimens.xml +++ b/duckchat/duckchat-impl/src/main/res/values/dimens.xml @@ -19,4 +19,5 @@ 34dp 2dp 5dp + 16dp \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/values/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values/strings-duckchat.xml index 82a9ab68a64b..d98184690982 100644 --- a/duckchat/duckchat-impl/src/main/res/values/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values/strings-duckchat.xml @@ -50,8 +50,9 @@ Search or enter address Duck.ai Ask Duck.ai - Experimental Address Bar - Search the web or ask Duck.ai directly from the Address Bar + Search Only\n(Default) + Search & Duck.ai\n(Experimental) + Search the web or ask Duck.ai directly from the Address Bar. Share Feedback Duck.ai diff --git a/duckchat/duckchat-impl/src/test/kotlin/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsViewModelTest.kt b/duckchat/duckchat-impl/src/test/kotlin/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsViewModelTest.kt index d81f6dc10c83..cae2b4136ae3 100644 --- a/duckchat/duckchat-impl/src/test/kotlin/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsViewModelTest.kt +++ b/duckchat/duckchat-impl/src/test/kotlin/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsViewModelTest.kt @@ -19,8 +19,10 @@ package com.duckduckgo.duckchat.impl.ui.settings import app.cash.turbine.test import com.duckduckgo.app.statistics.pixels.Pixel import com.duckduckgo.common.test.CoroutineTestRule +import com.duckduckgo.common.ui.experiments.visual.store.ExperimentalThemingDataStore import com.duckduckgo.duckchat.impl.DuckChatInternal import com.duckduckgo.duckchat.impl.pixel.DuckChatPixelName +import com.duckduckgo.duckchat.impl.ui.settings.DuckChatSettingsViewModel.Command.LaunchFeedback import com.duckduckgo.duckchat.impl.ui.settings.DuckChatSettingsViewModel.Command.OpenLink import com.duckduckgo.duckchat.impl.ui.settings.DuckChatSettingsViewModel.Command.OpenLinkInNewTab import com.duckduckgo.duckchat.impl.ui.settings.DuckChatSettingsViewModel.Command.OpenShortcutSettings @@ -95,14 +97,14 @@ class DuckChatSettingsViewModelTest { } @Test - fun `when onDuckAiInputScreen enabled then set user setting`() = runTest { - testee.onDuckAiInputScreenToggled(true) + fun `when onDuckAiInputScreenWithAiSelected selected then set user setting`() = runTest { + testee.onDuckAiInputScreenWithAiSelected() verify(duckChat).setInputScreenUserSetting(true) } @Test - fun `when onDuckAiInputScreen disabled then set user setting`() = runTest { - testee.onDuckAiInputScreenToggled(false) + fun `when onDuckAiInputScreenWithoutAiSelected selected then set user setting`() = runTest { + testee.onDuckAiInputScreenWithoutAiSelected() verify(duckChat).setInputScreenUserSetting(false) } @@ -214,14 +216,14 @@ class DuckChatSettingsViewModelTest { } @Test - fun `when onDuckAiInputScreenToggled true then on pixel fired`() = runTest { - testee.onDuckAiInputScreenToggled(true) + fun `when onDuckAiInputScreenWithAiSelected true then on pixel fired`() = runTest { + testee.onDuckAiInputScreenWithAiSelected() verify(mockPixel).fire(DuckChatPixelName.DUCK_CHAT_EXPERIMENTAL_ADDRESS_BAR_SETTING_ON) } @Test - fun `when onDuckAiInputScreenToggled false then off pixel fired`() = runTest { - testee.onDuckAiInputScreenToggled(false) + fun `when onDuckAiInputScreenWithoutAiSelected false then off pixel fired`() = runTest { + testee.onDuckAiInputScreenWithoutAiSelected() verify(mockPixel).fire(DuckChatPixelName.DUCK_CHAT_EXPERIMENTAL_ADDRESS_BAR_SETTING_OFF) } @@ -259,4 +261,15 @@ class DuckChatSettingsViewModelTest { cancelAndIgnoreRemainingEvents() } } + + @Test + fun `when input toggle share feedback clicked, then dispatch launch command`() = runTest { + testee.duckAiInputScreenShareFeedbackClicked() + + testee.commands.test { + val command = awaitItem() + assertTrue(command is LaunchFeedback) + cancelAndIgnoreRemainingEvents() + } + } } From d4b845536e04ddc65061deaed32d3366b5745577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 14 Aug 2025 14:25:16 +0200 Subject: [PATCH 4/9] lint fixes --- .../impl/ui/settings/DuckAiShortcutSettingsViewModel.kt | 9 --------- .../impl/ui/settings/DuckChatSettingsActivity.kt | 6 +++--- .../duckchat-impl/src/main/res/drawable/ic_ai_128.xml | 4 ++-- .../impl/ui/settings/DuckChatSettingsViewModelTest.kt | 2 -- 4 files changed, 5 insertions(+), 16 deletions(-) diff --git a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckAiShortcutSettingsViewModel.kt b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckAiShortcutSettingsViewModel.kt index c7040a71315d..b311c74fcab5 100644 --- a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckAiShortcutSettingsViewModel.kt +++ b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckAiShortcutSettingsViewModel.kt @@ -19,20 +19,11 @@ package com.duckduckgo.duckchat.impl.ui.settings import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.duckduckgo.anvil.annotations.ContributesViewModel -import com.duckduckgo.app.statistics.pixels.Pixel -import com.duckduckgo.common.ui.experiments.visual.store.ExperimentalThemingDataStore import com.duckduckgo.di.scopes.ActivityScope import com.duckduckgo.duckchat.impl.DuckChatInternal -import com.duckduckgo.duckchat.impl.pixel.DuckChatPixelName -import com.duckduckgo.duckchat.impl.ui.settings.DuckChatSettingsViewModel.Command.OpenLink -import com.duckduckgo.duckchat.impl.ui.settings.DuckChatSettingsViewModel.Command.OpenLinkInNewTab -import com.duckduckgo.subscriptions.api.SubscriptionRebrandingFeatureToggle import javax.inject.Inject -import kotlinx.coroutines.channels.BufferOverflow.DROP_OLDEST -import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch diff --git a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt index 5daf8db7407e..06cdae501dc1 100644 --- a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt +++ b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt @@ -43,11 +43,11 @@ import com.duckduckgo.duckchat.impl.R import com.duckduckgo.duckchat.impl.databinding.ActivityDuckChatSettingsBinding import com.duckduckgo.duckchat.impl.pixel.DuckChatPixelName.DUCK_CHAT_SETTINGS_DISPLAYED import com.duckduckgo.duckchat.impl.ui.settings.DuckChatSettingsViewModel.ViewState +import com.duckduckgo.mobile.android.R as CommonR import com.duckduckgo.navigation.api.GlobalActivityStarter import javax.inject.Inject import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import com.duckduckgo.mobile.android.R as CommonR @InjectWith(ActivityScope::class) @ContributeToActivityStarter(DuckChatSettingsNoParams::class, screenName = "duckai.settings") @@ -217,7 +217,7 @@ class DuckChatSettingsActivity : DuckDuckGoActivity() { CommonR.drawable.ic_shape_circle_24 } - class WithoutAi(isActive: Boolean): InputScreenToggleButton(isActive) { + class WithoutAi(isActive: Boolean) : InputScreenToggleButton(isActive) { override val imageRes: Int = if (isActive) { R.drawable.searchbox_withoutai_active } else { @@ -225,7 +225,7 @@ class DuckChatSettingsActivity : DuckDuckGoActivity() { } } - class WithAi(isActive: Boolean): InputScreenToggleButton(isActive) { + class WithAi(isActive: Boolean) : InputScreenToggleButton(isActive) { override val imageRes: Int = if (isActive) { R.drawable.searchbox_withai_active } else { diff --git a/duckchat/duckchat-impl/src/main/res/drawable/ic_ai_128.xml b/duckchat/duckchat-impl/src/main/res/drawable/ic_ai_128.xml index be9e62673d9f..e25a2f97b39c 100644 --- a/duckchat/duckchat-impl/src/main/res/drawable/ic_ai_128.xml +++ b/duckchat/duckchat-impl/src/main/res/drawable/ic_ai_128.xml @@ -53,7 +53,7 @@ - - Date: Tue, 19 Aug 2025 11:04:32 +0200 Subject: [PATCH 5/9] update radio buttons description copy --- duckchat/duckchat-impl/src/main/res/values/strings-duckchat.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/duckchat/duckchat-impl/src/main/res/values/strings-duckchat.xml b/duckchat/duckchat-impl/src/main/res/values/strings-duckchat.xml index d98184690982..a9e4102e8c2f 100644 --- a/duckchat/duckchat-impl/src/main/res/values/strings-duckchat.xml +++ b/duckchat/duckchat-impl/src/main/res/values/strings-duckchat.xml @@ -52,7 +52,7 @@ Ask Duck.ai Search Only\n(Default) Search & Duck.ai\n(Experimental) - Search the web or ask Duck.ai directly from the Address Bar. Share Feedback + Try our experimental option to ask Duck.ai directly from the Address Bar. Share Feedback Duck.ai From de79e0c165d4b3ba667e9691a07a19b1d7dfdac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Tue, 19 Aug 2025 12:19:28 +0200 Subject: [PATCH 6/9] update pictograms to use integrated backgrounds --- .../ui/settings/DuckChatSettingsActivity.kt | 38 +++++----- .../res/drawable/searchbox_background.xml | 24 ------- .../drawable/searchbox_background_active.xml | 28 -------- .../main/res/drawable/searchbox_withai.xml | 31 -------- .../res/drawable/searchbox_withai_active.xml | 69 +++++++++--------- .../drawable/searchbox_withai_active_dark.xml | 43 ++++++++++++ .../drawable/searchbox_withai_inactive.xml | 67 ++++++++++++++++++ .../searchbox_withai_inactive_dark.xml | 70 +++++++++++++++++++ .../main/res/drawable/searchbox_withoutai.xml | 38 ---------- .../drawable/searchbox_withoutai_active.xml | 66 ++++++++--------- .../searchbox_withoutai_active_dark.xml | 39 +++++++++++ .../drawable/searchbox_withoutai_inactive.xml | 41 +++++++++++ .../searchbox_withoutai_inactive_dark.xml | 46 ++++++++++++ .../layout/activity_duck_chat_settings.xml | 12 +--- 14 files changed, 395 insertions(+), 217 deletions(-) delete mode 100644 duckchat/duckchat-impl/src/main/res/drawable/searchbox_background.xml delete mode 100644 duckchat/duckchat-impl/src/main/res/drawable/searchbox_background_active.xml delete mode 100644 duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai.xml create mode 100644 duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_active_dark.xml create mode 100644 duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_inactive.xml create mode 100644 duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_inactive_dark.xml delete mode 100644 duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai.xml create mode 100644 duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_active_dark.xml create mode 100644 duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_inactive.xml create mode 100644 duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_inactive_dark.xml diff --git a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt index 06cdae501dc1..1fdf1c0dea45 100644 --- a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt +++ b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt @@ -33,6 +33,7 @@ import com.duckduckgo.browser.api.ui.BrowserScreens.FeedbackActivityWithEmptyPar import com.duckduckgo.browser.api.ui.BrowserScreens.WebViewActivityWithParams import com.duckduckgo.common.ui.DuckDuckGoActivity import com.duckduckgo.common.ui.spans.DuckDuckGoClickableSpan +import com.duckduckgo.common.ui.store.AppTheme import com.duckduckgo.common.ui.view.addClickableSpan import com.duckduckgo.common.ui.view.gone import com.duckduckgo.common.ui.view.show @@ -70,6 +71,9 @@ class DuckChatSettingsActivity : DuckDuckGoActivity() { @Inject lateinit var pixel: Pixel + @Inject + lateinit var appTheme: AppTheme + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -132,8 +136,8 @@ class DuckChatSettingsActivity : DuckDuckGoActivity() { binding.duckAiInputScreenToggleContainer.isVisible = viewState.shouldShowInputScreenToggle configureInputScreenToggle( - withoutAi = InputScreenToggleButton.WithoutAi(isActive = !viewState.isInputScreenEnabled), - withAi = InputScreenToggleButton.WithAi(isActive = viewState.isInputScreenEnabled), + withoutAi = InputScreenToggleButton.WithoutAi(isActive = !viewState.isInputScreenEnabled, appTheme.isLightModeEnabled()), + withAi = InputScreenToggleButton.WithAi(isActive = viewState.isInputScreenEnabled, appTheme.isLightModeEnabled()), ) binding.duckAiInputScreenDescription.isVisible = viewState.shouldShowInputScreenToggle @@ -196,40 +200,36 @@ class DuckChatSettingsActivity : DuckDuckGoActivity() { ) = with(binding) { val context = this@DuckChatSettingsActivity duckAiInputScreenToggleWithoutAiImage.setImageDrawable(ContextCompat.getDrawable(context, withoutAi.imageRes)) - duckAiInputScreenToggleWithoutAiImage.setBackgroundResource(withoutAi.backgroundRes) duckAiInputScreenToggleWithoutAiCheck.setImageDrawable(ContextCompat.getDrawable(context, withoutAi.checkRes)) duckAiInputScreenToggleWithAiImage.setImageDrawable(ContextCompat.getDrawable(context, withAi.imageRes)) - duckAiInputScreenToggleWithAiImage.setBackgroundResource(withAi.backgroundRes) duckAiInputScreenToggleWithAiCheck.setImageDrawable(ContextCompat.getDrawable(context, withAi.checkRes)) } private sealed class InputScreenToggleButton(isActive: Boolean) { abstract val imageRes: Int - val backgroundRes: Int = if (isActive) { - R.drawable.searchbox_background_active - } else { - R.drawable.searchbox_background - } + val checkRes: Int = if (isActive) { CommonR.drawable.ic_check_blue_round_24 } else { CommonR.drawable.ic_shape_circle_24 } - class WithoutAi(isActive: Boolean) : InputScreenToggleButton(isActive) { - override val imageRes: Int = if (isActive) { - R.drawable.searchbox_withoutai_active - } else { - R.drawable.searchbox_withoutai + class WithoutAi(isActive: Boolean, isLightMode: Boolean) : InputScreenToggleButton(isActive) { + override val imageRes: Int = when { + isActive && isLightMode -> R.drawable.searchbox_withoutai_active + isActive && !isLightMode -> R.drawable.searchbox_withoutai_active_dark + !isActive && isLightMode -> R.drawable.searchbox_withoutai_inactive + else -> R.drawable.searchbox_withoutai_inactive_dark } } - class WithAi(isActive: Boolean) : InputScreenToggleButton(isActive) { - override val imageRes: Int = if (isActive) { - R.drawable.searchbox_withai_active - } else { - R.drawable.searchbox_withai + class WithAi(isActive: Boolean, isLightMode: Boolean) : InputScreenToggleButton(isActive) { + override val imageRes: Int = when { + isActive && isLightMode -> R.drawable.searchbox_withai_active + isActive && !isLightMode -> R.drawable.searchbox_withai_active_dark + !isActive && isLightMode -> R.drawable.searchbox_withai_inactive + else -> R.drawable.searchbox_withai_inactive_dark } } } diff --git a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_background.xml b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_background.xml deleted file mode 100644 index 92e9b8608745..000000000000 --- a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_background.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_background_active.xml b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_background_active.xml deleted file mode 100644 index 0fa50d58b7ff..000000000000 --- a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_background_active.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai.xml b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai.xml deleted file mode 100644 index ec49ef7b558b..000000000000 --- a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - diff --git a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_active.xml b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_active.xml index 00336913a387..0b17064478f7 100644 --- a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_active.xml +++ b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_active.xml @@ -1,38 +1,41 @@ - - - - + android:width="160dp" + android:height="88dp" + android:viewportWidth="160" + android:viewportHeight="88"> - + android:pathData="M0,0h160v88H0z"/> + + + + + + + + + + + + + - diff --git a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_active_dark.xml b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_active_dark.xml new file mode 100644 index 000000000000..8ca722a7cc17 --- /dev/null +++ b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_active_dark.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + diff --git a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_inactive.xml b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_inactive.xml new file mode 100644 index 000000000000..3c548419585f --- /dev/null +++ b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_inactive.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_inactive_dark.xml b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_inactive_dark.xml new file mode 100644 index 000000000000..caba46f7a00b --- /dev/null +++ b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withai_inactive_dark.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai.xml b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai.xml deleted file mode 100644 index a03ae10c531f..000000000000 --- a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - diff --git a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_active.xml b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_active.xml index 4c001cf046be..d1131427e889 100644 --- a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_active.xml +++ b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_active.xml @@ -1,38 +1,38 @@ - - - - + android:width="160dp" + android:height="88dp" + android:viewportWidth="160" + android:viewportHeight="88"> - + android:pathData="M0,0h160v88H0z"/> + + + + + + + + + + + + - diff --git a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_active_dark.xml b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_active_dark.xml new file mode 100644 index 000000000000..08c42a5f0e41 --- /dev/null +++ b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_active_dark.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + diff --git a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_inactive.xml b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_inactive.xml new file mode 100644 index 000000000000..7b31f00c4752 --- /dev/null +++ b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_inactive.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + diff --git a/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_inactive_dark.xml b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_inactive_dark.xml new file mode 100644 index 000000000000..fafb85ee5911 --- /dev/null +++ b/duckchat/duckchat-impl/src/main/res/drawable/searchbox_withoutai_inactive_dark.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + diff --git a/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml b/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml index 11fc28969026..f6f8c2d4574c 100644 --- a/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml +++ b/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml @@ -115,11 +115,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="fitCenter" - android:background="@drawable/searchbox_background_active" - android:paddingStart="16dp" - android:paddingTop="16dp" - android:paddingEnd="16dp" - android:paddingBottom="1dp" android:src="@drawable/searchbox_withoutai_active" /> + android:src="@drawable/searchbox_withai_inactive" /> Date: Tue, 19 Aug 2025 13:41:16 +0200 Subject: [PATCH 7/9] update the used check icon --- .../main/res/drawable/ic_check_accent_24.xml | 28 +++++++++++++++++++ .../drawable/ic_shape_circle_disabled_24.xml | 10 +++++++ .../res/values/design-experiments-colors.xml | 6 ++++ .../main/res/values/design-system-colors.xml | 2 ++ .../main/res/values/design-system-theming.xml | 2 ++ .../ui/settings/DuckChatSettingsActivity.kt | 4 +-- .../layout/activity_duck_chat_settings.xml | 2 +- 7 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 common/common-ui/src/main/res/drawable/ic_check_accent_24.xml create mode 100644 common/common-ui/src/main/res/drawable/ic_shape_circle_disabled_24.xml diff --git a/common/common-ui/src/main/res/drawable/ic_check_accent_24.xml b/common/common-ui/src/main/res/drawable/ic_check_accent_24.xml new file mode 100644 index 000000000000..2bbf0cf41b5a --- /dev/null +++ b/common/common-ui/src/main/res/drawable/ic_check_accent_24.xml @@ -0,0 +1,28 @@ + + + + + + diff --git a/common/common-ui/src/main/res/drawable/ic_shape_circle_disabled_24.xml b/common/common-ui/src/main/res/drawable/ic_shape_circle_disabled_24.xml new file mode 100644 index 000000000000..9e1cde8e666e --- /dev/null +++ b/common/common-ui/src/main/res/drawable/ic_shape_circle_disabled_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/common/common-ui/src/main/res/values/design-experiments-colors.xml b/common/common-ui/src/main/res/values/design-experiments-colors.xml index 9a1da601e848..3a8554671e45 100644 --- a/common/common-ui/src/main/res/values/design-experiments-colors.xml +++ b/common/common-ui/src/main/res/values/design-experiments-colors.xml @@ -21,6 +21,9 @@ + + @color/blue80 + #27282A #333538 @@ -47,6 +50,9 @@ #B8F9F9F9 + + @color/white + #F2F2F2 #F9F9F9 diff --git a/common/common-ui/src/main/res/values/design-system-colors.xml b/common/common-ui/src/main/res/values/design-system-colors.xml index 50a6a0dbaa6c..7ad9847e9c6c 100644 --- a/common/common-ui/src/main/res/values/design-system-colors.xml +++ b/common/common-ui/src/main/res/values/design-system-colors.xml @@ -60,6 +60,7 @@ + @@ -192,6 +193,7 @@ #243969EF #2B55CA #1E42A4 + #14307E #D6000000 #99000000 diff --git a/common/common-ui/src/main/res/values/design-system-theming.xml b/common/common-ui/src/main/res/values/design-system-theming.xml index b9652a4ea36e..bfeadbe25b27 100644 --- a/common/common-ui/src/main/res/values/design-system-theming.xml +++ b/common/common-ui/src/main/res/values/design-system-theming.xml @@ -181,6 +181,7 @@ @color/white9 @color/blue30 @color/yellow50 + @color/accent_content_primary_dark @color/white12 @color/white @color/blue30_20 @@ -289,6 +290,7 @@ @color/black9 @color/blue50 @color/yellow50 + @color/accent_content_primary_light @color/black6 @color/gray85 @color/blue50_20 diff --git a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt index 1fdf1c0dea45..e51374c0749f 100644 --- a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt +++ b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt @@ -210,9 +210,9 @@ class DuckChatSettingsActivity : DuckDuckGoActivity() { abstract val imageRes: Int val checkRes: Int = if (isActive) { - CommonR.drawable.ic_check_blue_round_24 + CommonR.drawable.ic_check_accent_24 } else { - CommonR.drawable.ic_shape_circle_24 + CommonR.drawable.ic_shape_circle_disabled_24 } class WithoutAi(isActive: Boolean, isLightMode: Boolean) : InputScreenToggleButton(isActive) { diff --git a/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml b/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml index f6f8c2d4574c..84813cff8954 100644 --- a/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml +++ b/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml @@ -131,7 +131,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="6dp" - android:src="@drawable/ic_check_blue_round_24" /> + android:src="@drawable/ic_check_accent_24" /> From 7d045b264ed38986fe2171f0ccae6421c2d6cd02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Tue, 19 Aug 2025 15:07:22 +0200 Subject: [PATCH 8/9] align content with main Duck.ai toggle --- .../ui/settings/DuckChatSettingsActivity.kt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt index e51374c0749f..28cd6736cc84 100644 --- a/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt +++ b/duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/ui/settings/DuckChatSettingsActivity.kt @@ -17,11 +17,13 @@ package com.duckduckgo.duckchat.impl.ui.settings import android.content.Intent +import android.content.res.Configuration import android.os.Bundle import android.view.View import android.widget.CompoundButton import androidx.core.content.ContextCompat import androidx.core.view.isVisible +import androidx.core.view.updatePadding import androidx.lifecycle.Lifecycle import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope @@ -108,6 +110,20 @@ class DuckChatSettingsActivity : DuckDuckGoActivity() { binding.userEnabledDuckChatToggleRebranding.show() binding.showDuckChatSearchSettingsLink.setPrimaryText(getString(R.string.duck_chat_assist_settings_title_rebranding)) binding.showDuckChatSearchSettingsLink.setSecondaryText(getString(R.string.duck_chat_assist_settings_description_rebranding)) + + // align content with the main Duck.ai toggle's text + val offset = resources.getDimensionPixelSize(CommonR.dimen.listItemImageContainerSize) + + resources.getDimensionPixelSize(CommonR.dimen.keyline_4) + val orientation = resources.configuration.orientation + binding.duckAiInputScreenToggleContainer.updatePadding( + left = if (orientation == Configuration.ORIENTATION_LANDSCAPE) { + 0 + } else { + offset + }, + ) + binding.duckAiInputScreenDescription.updatePadding(left = offset) + binding.duckAiShortcuts.updatePadding(left = offset) } else { binding.includeToolbar.toolbar.title = getString(R.string.duck_ai_paid_settings_title) binding.duckChatSettingsIcon.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.chat_private_128)) @@ -117,6 +133,11 @@ class DuckChatSettingsActivity : DuckDuckGoActivity() { binding.userEnabledDuckChatToggleRebranding.gone() binding.showDuckChatSearchSettingsLink.setPrimaryText(getString(R.string.duck_chat_assist_settings_title)) binding.showDuckChatSearchSettingsLink.setSecondaryText(getString(R.string.duck_chat_assist_settings_description)) + + val offset = 0 + binding.duckAiInputScreenToggleContainer.updatePadding(left = offset) + binding.duckAiInputScreenDescription.updatePadding(left = offset) + binding.duckAiShortcuts.updatePadding(left = offset) } binding.duckChatSettingsText.addClickableSpan( From 4d96b04f4cf181eb9a8cc0589187ce09b17c5bd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Tue, 19 Aug 2025 16:39:31 +0200 Subject: [PATCH 9/9] update text type --- .../src/main/res/layout/activity_duck_chat_settings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml b/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml index 84813cff8954..329910efbc6a 100644 --- a/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml +++ b/duckchat/duckchat-impl/src/main/res/layout/activity_duck_chat_settings.xml @@ -64,6 +64,7 @@ android:layout_marginBottom="@dimen/keyline_6" android:text="@string/duck_chat_settings_activity_description" android:gravity="center" + app:textType="secondary" app:typography="body2"/>