Skip to content

Commit d6fd524

Browse files
authored
Support Bottom Address Bar in the Input Screen (#6849)
Task/Issue URL: https://app.asana.com/1/137249556945/project/1208671518894266/task/1211468322303336?focus=true ### Description Adds bottom omnibar support to the Input Screen. To achieve this, the PR: - Introduces top and bottom containers for the `InputModeWidget` and injects it into the right position after evaluating the current status of the browser screen's omnibar and the feature flag. - Extracts the control buttons (voice, new line, submit) to a new class that can be reused across top and bottom configurations: - If top configuration is used, the backgrounds and shadows are transformed to look like floating buttons and placed directly into the `InputScreenFragment`. - If bottom configuration is used, the buttons remain flat and are placed inside of the `InputModeWidget`. This PR also introduces content separator between scrolalble autocomplete or new tab content. This is a lightly colored line instead of the previously used gradient. You might notice a lot of unrelated changes in the PR, specifically in 6dd61f5 and 0013b95 commits. This is a side-effect of recent ratchet-based code formatting update. ### Steps to test this PR - [x] Enable Input Screen. - [x] Verify that opening the Input Screen happens with a slide transition. - [x] Verify that Dax is in sync when transitioning. - [x] Verify that buttons are placed near the keyboard and have floating shadows and circular backgrounds. - [x] Verify that closing the Input Screen (with a back button/arrow) happens with a slide transition. - [x] Go to settings and change the appearance to use bottom omnibar. - [x] Verify that opening the Input Screen happens with a fade transition. - [x] Verify that buttons are borderless and without shadows (besides the blue submit button). - [x] Verify that autocomplete arrows point down for editing. - [x] Verify there's no blur covering bottom of autocomplete results and that they can be scrolled all the way up. - [x] Verify that when there are no action buttons available, the view collapses tom hide the empty line. - [x] Verify that creating new lines in Duck.ai mode expands the text view up. - [x] Verify that closing the Input Screen (with a back button/arrow) happens with a fade transition. - [x] Add favorites. - [x] Verify that favorites are in sync when opening/closing the Input Screen. - [x] Go to internal Feature Flag Inventory and disable the `inputScreenBottomBarSupport` flag. - [x] Restart the app. - [x] Verify that even though the bottom omnibar is set, when opening the Input Screen the bar is at the top. - [x] Verify that favorites are in sync when opening/closing the Input Screen. ### UI changes | focus | autocomplete | duck-ai | favorites | multiline | |-------|--------------|---------|-----------|-----------| | <img width="960" height="2142" alt="focus" src="https://github.com/user-attachments/assets/3ae4782e-4c45-4fb6-8eea-d900cd27ae45" /> | <img width="960" height="2142" alt="autocomplete" src="https://github.com/user-attachments/assets/9070c7d1-8c90-49e4-a717-79219219527d" /> | <img width="960" height="2142" alt="duck-ai" src="https://github.com/user-attachments/assets/04fbb8c7-c918-4c1e-8f0f-0ebfbe1b2420" /> | <img width="960" height="2142" alt="favorites" src="https://github.com/user-attachments/assets/98ef041c-1359-4572-9905-876ea4a511c7" /> | <img width="960" height="2142" alt="multiline" src="https://github.com/user-attachments/assets/086ba507-bd25-4ad8-b46d-a98138952284" /> | https://github.com/user-attachments/assets/57d98124-54a0-4f1a-993a-157e5ce0f0d9 https://github.com/user-attachments/assets/a95c0b3f-e9aa-44de-bf40-c4d3e7b4169c https://github.com/user-attachments/assets/402bc03a-1b6d-41fb-8067-08a90bcdd581
1 parent 4e50395 commit d6fd524

32 files changed

+1298
-478
lines changed

app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,10 +1117,10 @@ class BrowserTabFragment :
11171117
val intent =
11181118
globalActivityStarter.startIntent(
11191119
requireContext(),
1120-
InputScreenActivityParams(query = query),
1120+
InputScreenActivityParams(query = query, isTopOmnibar = omnibar.omnibarPosition == TOP),
11211121
)
1122-
val enterTransition = browserAndInputScreenTransitionProvider.getInputScreenEnterAnimation()
1123-
val exitTransition = browserAndInputScreenTransitionProvider.getBrowserExitAnimation()
1122+
val enterTransition = browserAndInputScreenTransitionProvider.getInputScreenEnterAnimation(omnibar.omnibarPosition == TOP)
1123+
val exitTransition = browserAndInputScreenTransitionProvider.getBrowserExitAnimation(omnibar.omnibarPosition == TOP)
11241124
val options =
11251125
ActivityOptionsCompat.makeCustomAnimation(
11261126
requireActivity(),
@@ -1638,8 +1638,10 @@ class BrowserTabFragment :
16381638
val result = downloadsFileActions.openFile(it, File(command.filePath))
16391639
if (!result) {
16401640
view
1641-
.makeSnackbarWithNoBottomInset(getString(R.string.downloadsCannotOpenFileErrorMessage), Snackbar.LENGTH_LONG)
1642-
.show()
1641+
.makeSnackbarWithNoBottomInset(
1642+
text = getString(R.string.downloadsCannotOpenFileErrorMessage),
1643+
duration = Snackbar.LENGTH_LONG,
1644+
).show()
16431645
}
16441646
}
16451647
}

app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,6 @@ import kotlinx.coroutines.flow.launchIn
380380
import kotlinx.coroutines.flow.map
381381
import kotlinx.coroutines.flow.onEach
382382
import kotlinx.coroutines.flow.stateIn
383-
import kotlinx.coroutines.flow.update
384383
import kotlinx.coroutines.launch
385384
import kotlinx.coroutines.withContext
386385
import logcat.LogPriority.ERROR

app/src/main/java/com/duckduckgo/app/browser/omnibar/SingleOmnibarLayout.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ import com.duckduckgo.common.ui.view.toPx
4040
import com.duckduckgo.di.scopes.FragmentScope
4141
import com.duckduckgo.navigation.api.GlobalActivityStarter
4242
import com.google.android.material.card.MaterialCardView
43-
import com.google.android.material.color.MaterialColors.*
4443
import dagger.android.support.AndroidSupportInjection
4544
import javax.inject.Inject
4645
import com.duckduckgo.mobile.android.R as CommonR

app/src/main/java/com/duckduckgo/app/systemsearch/SystemSearchActivity.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ import com.duckduckgo.common.ui.view.KeyboardAwareEditText
7878
import com.duckduckgo.common.ui.view.addBottomShadow
7979
import com.duckduckgo.common.ui.view.dialog.TextAlertDialogBuilder
8080
import com.duckduckgo.common.ui.view.hideKeyboard
81-
import com.duckduckgo.common.ui.view.show
8281
import com.duckduckgo.common.ui.view.showKeyboard
8382
import com.duckduckgo.common.ui.viewbinding.viewBinding
8483
import com.duckduckgo.common.utils.KeyboardVisibilityUtil

duckchat/duckchat-api/src/main/java/com/duckduckgo/duckchat/api/inputscreen/BrowserAndInputScreenTransitionProvider.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,11 @@ package com.duckduckgo.duckchat.api.inputscreen
2020
* Provides animation resources for activity transitions between browser and input screen.
2121
*/
2222
interface BrowserAndInputScreenTransitionProvider {
23+
fun getBrowserEnterAnimation(isTopOmnibar: Boolean): Int
2324

24-
fun getBrowserEnterAnimation(): Int
25+
fun getBrowserExitAnimation(isTopOmnibar: Boolean): Int
2526

26-
fun getBrowserExitAnimation(): Int
27+
fun getInputScreenEnterAnimation(isTopOmnibar: Boolean): Int
2728

28-
fun getInputScreenEnterAnimation(): Int
29-
30-
fun getInputScreenExitAnimation(): Int
29+
fun getInputScreenExitAnimation(isTopOmnibar: Boolean): Int
3130
}

duckchat/duckchat-api/src/main/java/com/duckduckgo/duckchat/api/inputscreen/InputScreenActivityParams.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ import com.duckduckgo.navigation.api.GlobalActivityStarter
2424
* Parameters for launching the Input Screen activity.
2525
*
2626
* @param query The initial query text to pre-populate in the input field
27+
* @param isTopOmnibar whether the omnibar is positioned at the top of the screen
2728
*/
2829
data class InputScreenActivityParams(
2930
val query: String,
31+
val isTopOmnibar: Boolean,
3032
) : GlobalActivityStarter.ActivityParams
3133

3234
/**
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="utf-8"?><!--
2+
~ Copyright (c) 2025 DuckDuckGo
3+
~
4+
~ Licensed under the Apache License, Version 2.0 (the "License");
5+
~ you may not use this file except in compliance with the License.
6+
~ You may obtain a copy of the License at
7+
~
8+
~ http://www.apache.org/licenses/LICENSE-2.0
9+
~
10+
~ Unless required by applicable law or agreed to in writing, software
11+
~ distributed under the License is distributed on an "AS IS" BASIS,
12+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
~ See the License for the specific language governing permissions and
14+
~ limitations under the License.
15+
-->
16+
17+
<set xmlns:android="http://schemas.android.com/apk/res/android"
18+
android:backdropColor="@color/background_background_dark"
19+
android:duration="@integer/input_screen_slide_animation_duration_ms"
20+
android:showBackdrop="true">
21+
22+
<alpha
23+
android:fromAlpha="0.0"
24+
android:interpolator="@android:anim/decelerate_interpolator"
25+
android:toAlpha="1.0" />
26+
27+
</set>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="utf-8"?><!--
2+
~ Copyright (c) 2025 DuckDuckGo
3+
~
4+
~ Licensed under the Apache License, Version 2.0 (the "License");
5+
~ you may not use this file except in compliance with the License.
6+
~ You may obtain a copy of the License at
7+
~
8+
~ http://www.apache.org/licenses/LICENSE-2.0
9+
~
10+
~ Unless required by applicable law or agreed to in writing, software
11+
~ distributed under the License is distributed on an "AS IS" BASIS,
12+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
~ See the License for the specific language governing permissions and
14+
~ limitations under the License.
15+
-->
16+
17+
<set xmlns:android="http://schemas.android.com/apk/res/android"
18+
android:backdropColor="@color/background_background_light"
19+
android:duration="@integer/input_screen_slide_animation_duration_ms"
20+
android:showBackdrop="true">
21+
22+
<alpha
23+
android:fromAlpha="0.0"
24+
android:interpolator="@android:anim/decelerate_interpolator"
25+
android:toAlpha="1.0" />
26+
27+
</set>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="utf-8"?><!--
2+
~ Copyright (c) 2025 DuckDuckGo
3+
~
4+
~ Licensed under the Apache License, Version 2.0 (the "License");
5+
~ you may not use this file except in compliance with the License.
6+
~ You may obtain a copy of the License at
7+
~
8+
~ http://www.apache.org/licenses/LICENSE-2.0
9+
~
10+
~ Unless required by applicable law or agreed to in writing, software
11+
~ distributed under the License is distributed on an "AS IS" BASIS,
12+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
~ See the License for the specific language governing permissions and
14+
~ limitations under the License.
15+
-->
16+
17+
<set xmlns:android="http://schemas.android.com/apk/res/android"
18+
android:backdropColor="@color/background_background_dark"
19+
android:duration="@integer/input_screen_slide_animation_duration_ms"
20+
android:showBackdrop="true">
21+
22+
<alpha
23+
android:fromAlpha="1.0"
24+
android:interpolator="@android:anim/decelerate_interpolator"
25+
android:toAlpha="0.0" />
26+
27+
</set>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="utf-8"?><!--
2+
~ Copyright (c) 2025 DuckDuckGo
3+
~
4+
~ Licensed under the Apache License, Version 2.0 (the "License");
5+
~ you may not use this file except in compliance with the License.
6+
~ You may obtain a copy of the License at
7+
~
8+
~ http://www.apache.org/licenses/LICENSE-2.0
9+
~
10+
~ Unless required by applicable law or agreed to in writing, software
11+
~ distributed under the License is distributed on an "AS IS" BASIS,
12+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
~ See the License for the specific language governing permissions and
14+
~ limitations under the License.
15+
-->
16+
17+
<set xmlns:android="http://schemas.android.com/apk/res/android"
18+
android:backdropColor="@color/background_background_light"
19+
android:duration="@integer/input_screen_slide_animation_duration_ms"
20+
android:showBackdrop="true">
21+
22+
<alpha
23+
android:fromAlpha="1.0"
24+
android:interpolator="@android:anim/decelerate_interpolator"
25+
android:toAlpha="0.0" />
26+
27+
</set>

0 commit comments

Comments
 (0)