-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add duck.ai entry point pixel #9550
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -41,6 +41,7 @@ import androidx.activity.result.contract.ActivityResultContracts | |
| import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult | ||
| import androidx.activity.viewModels | ||
| import androidx.annotation.VisibleForTesting | ||
| import androidx.core.net.toUri | ||
| import androidx.core.view.isVisible | ||
| import androidx.core.view.postDelayed | ||
| import androidx.lifecycle.Lifecycle | ||
|
|
@@ -60,7 +61,10 @@ import com.duckduckgo.app.browser.databinding.IncludeOmnibarToolbarMockupBinding | |
| import com.duckduckgo.app.browser.databinding.IncludeOmnibarToolbarMockupBottomBinding | ||
| import com.duckduckgo.app.browser.defaultbrowsing.prompts.ui.DefaultBrowserBottomSheetDialog | ||
| import com.duckduckgo.app.browser.defaultbrowsing.prompts.ui.DefaultBrowserBottomSheetDialog.EventListener | ||
| import com.duckduckgo.app.browser.mode.AppShortcutDuckAi | ||
| import com.duckduckgo.app.browser.mode.BrowserLaunchSource | ||
| import com.duckduckgo.app.browser.mode.DuckAiPinShortcut | ||
| import com.duckduckgo.app.browser.mode.SearchWidgetDuckAi | ||
| import com.duckduckgo.app.browser.omnibar.OmnibarEntryConverter | ||
| import com.duckduckgo.app.browser.omnibar.OmnibarType | ||
| import com.duckduckgo.app.browser.omnibar.applyAddressBarRebrandRadius | ||
|
|
@@ -126,6 +130,7 @@ import com.duckduckgo.di.scopes.ActivityScope | |
| import com.duckduckgo.downloads.api.DownloadsScreens.DownloadsScreenNoParams | ||
| import com.duckduckgo.duckchat.api.DuckAiFeatureState | ||
| import com.duckduckgo.duckchat.api.DuckChat | ||
| import com.duckduckgo.duckchat.api.DuckChatEntryPoint | ||
| import com.duckduckgo.duckchat.api.viewmodel.DuckChatSharedViewModel | ||
| import com.duckduckgo.feedback.api.FeedbackScreenNoParams | ||
| import com.duckduckgo.navigation.api.GlobalActivityStarter | ||
|
|
@@ -151,6 +156,12 @@ import logcat.logcat | |
| import javax.inject.Inject | ||
| import com.duckduckgo.mobile.android.R as CommonR | ||
|
|
||
| private fun BrowserLaunchSource.toDuckChatEntryPoint(): DuckChatEntryPoint? = when (this) { | ||
| AppShortcutDuckAi, DuckAiPinShortcut -> DuckChatEntryPoint.ICON_SHORTCUT | ||
| SearchWidgetDuckAi -> DuckChatEntryPoint.WIDGET_QUICK_ACTIONS | ||
| else -> null | ||
| } | ||
|
|
||
| // open class so that we can test BrowserApplicationStateInfo | ||
| @HasMemberInjections | ||
| @InjectWith(ActivityScope::class) | ||
|
|
@@ -812,6 +823,11 @@ open class BrowserActivity : DuckDuckGoActivity() { | |
|
|
||
| if (intent.getBooleanExtra(OPEN_DUCK_CHAT, false)) { | ||
| val sourceTabId = intent.getStringExtra(SOURCE_TAB_ID_EXTRA) | ||
| intent.getStringExtra(DUCK_CHAT_ENTRY_POINT_EXTRA)?.let { source -> | ||
| runCatching { DuckChatEntryPoint.valueOf(source) } | ||
| .getOrNull() | ||
| ?.let { duckChat.reportDuckChatEntry(it, opensNewTab = true, hasPrompt = false) } | ||
| } | ||
| launchDuckAi(url = intent.getStringExtra(DUCK_CHAT_URL), sourceTabId = sourceTabId) | ||
| return | ||
| } | ||
|
|
@@ -837,6 +853,13 @@ open class BrowserActivity : DuckDuckGoActivity() { | |
| lifecycleScope.launch { viewModel.onOpenShortcut(sharedText) } | ||
| } else if (intent.getBooleanExtra(LAUNCH_FROM_FAVORITES_WIDGET, false)) { | ||
| logcat { "Favorite clicked from widget $sharedText" } | ||
| if (duckChat.isDuckChatUrl(sharedText.toUri())) { | ||
| duckChat.reportDuckChatEntry( | ||
| DuckChatEntryPoint.WIDGET_FAVORITE, | ||
| opensNewTab = true, | ||
| hasPrompt = hasAutoSubmittedPrompt(sharedText), | ||
| ) | ||
| } | ||
| lifecycleScope.launch { viewModel.onOpenFavoriteFromWidget(query = sharedText) } | ||
| } else if (intent.getBooleanExtra(OPEN_IN_CURRENT_TAB_EXTRA, false)) { | ||
| logcat(WARN) { "open in current tab requested" } | ||
|
|
@@ -853,6 +876,13 @@ open class BrowserActivity : DuckDuckGoActivity() { | |
| } else { | ||
| val isExternal = intent.getBooleanExtra(LAUNCH_FROM_EXTERNAL_EXTRA, false) | ||
| val interstitialScreen = intent.getBooleanExtra(LAUNCH_FROM_INTERSTITIAL_EXTRA, false) | ||
| if (isExternal && duckChat.isDuckChatUrl(sharedText.toUri())) { | ||
| duckChat.reportDuckChatEntry( | ||
| DuckChatEntryPoint.DEEP_LINK_OTHER, | ||
| opensNewTab = true, | ||
| hasPrompt = hasAutoSubmittedPrompt(sharedText), | ||
| ) | ||
| } | ||
| logcat(WARN) { "opening in new tab requested for $sharedText isExternal $isExternal interstitial $interstitialScreen" } | ||
| if (!interstitialScreen) { | ||
| logcat(WARN) { "not launching from interstitial screen" } | ||
|
|
@@ -1061,6 +1091,11 @@ open class BrowserActivity : DuckDuckGoActivity() { | |
| } | ||
| } | ||
|
|
||
| private fun hasAutoSubmittedPrompt(url: String): Boolean = runCatching { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: this is the third copy of the prompt check (BrowserTabViewModel has the same function, BrowserWebViewClient inlines it), and this one hardcodes q and prompt while RealDuckChat owns those constants. shouldn't it live in duckchat next to PROMPT_QUERY_NAME so the three can't drift?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn’t think it’s worth doing an API for this. But if you prefer it living in duck chat then sure it’s a small change.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Created follow up task: https://app.asana.com/1/137249556945/task/1217730703035452?focus=true |
||
| val uri = url.toUri() | ||
| uri.getQueryParameter("prompt") == "1" && !uri.getQueryParameter("q").isNullOrBlank() | ||
| }.getOrDefault(false) | ||
|
|
||
| fun closeDuckChatFullScreen() { | ||
| isDuckChatVisible = false | ||
| currentTab?.closeCurrentTab() | ||
|
|
@@ -1146,6 +1181,11 @@ open class BrowserActivity : DuckDuckGoActivity() { | |
| finish() | ||
| } | ||
| is NewUserBrowserOnboardingViewModel.Command.OpenDuckAiOnboardingDemo -> { | ||
| duckChat.reportDuckChatEntry( | ||
| DuckChatEntryPoint.ONBOARDING, | ||
| opensNewTab = true, | ||
| hasPrompt = hasAutoSubmittedPrompt(command.url), | ||
| ) | ||
| launchDuckAi(url = command.url) | ||
| } | ||
| } | ||
|
|
@@ -1252,6 +1292,7 @@ open class BrowserActivity : DuckDuckGoActivity() { | |
| intent.putExtra(LAUNCH_FROM_INTERSTITIAL_EXTRA, interstitialScreen) | ||
| intent.putExtra(OPEN_EXISTING_TAB_ID_EXTRA, openExistingTabId) | ||
| intent.putExtra(OPEN_DUCK_CHAT, openDuckChat) | ||
| intent.putExtra(DUCK_CHAT_ENTRY_POINT_EXTRA, launchSource.toDuckChatEntryPoint()?.name) | ||
| intent.putExtra(CLOSE_DUCK_CHAT, closeDuckChat) | ||
| intent.putExtra(DUCK_CHAT_URL, duckChatUrl) | ||
| intent.putExtra(DUCK_CHAT_SESSION_ACTIVE, duckChatSessionActive) | ||
|
|
@@ -1287,6 +1328,7 @@ open class BrowserActivity : DuckDuckGoActivity() { | |
| const val LAUNCH_SOURCE_PIXEL_VALUE = "LAUNCH_SOURCE_PIXEL_VALUE" | ||
|
|
||
| private const val OPEN_DUCK_CHAT = "OPEN_DUCK_CHAT_EXTRA" | ||
| private const val DUCK_CHAT_ENTRY_POINT_EXTRA = "DUCK_CHAT_ENTRY_POINT_EXTRA" | ||
| private const val CLOSE_DUCK_CHAT = "CLOSE_DUCK_CHAT_EXTRA" | ||
| private const val DUCK_CHAT_URL = "DUCK_CHAT_URL" | ||
| private const val DUCK_CHAT_SESSION_ACTIVE = "DUCK_CHAT_SESSION_ACTIVE" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fast-follow: duck_ai_enabled just above is still type string with a true/false enum, which the pixel rules say should be a boolean with no enum. since we're already editing these two entries, can we fix it in passing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do