Skip to content
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

Update Settings design: Add new SettingsListItem #5318

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ import com.duckduckgo.autofill.api.AutofillScreens.AutofillSettingsScreen
import com.duckduckgo.autofill.api.AutofillSettingsLaunchSource
import com.duckduckgo.common.ui.DuckDuckGoActivity
import com.duckduckgo.common.ui.view.gone
import com.duckduckgo.common.ui.view.listitem.CheckListItem
import com.duckduckgo.common.ui.view.listitem.TwoLineListItem
import com.duckduckgo.common.ui.view.show
import com.duckduckgo.common.ui.viewbinding.viewBinding
Expand Down Expand Up @@ -204,7 +203,6 @@ class NewSettingsActivity : DuckDuckGoActivity() {
updateDefaultBrowserViewVisibility(it)
updateDeviceShieldSettings(
it.appTrackingProtectionEnabled,
it.appTrackingProtectionOnboardingShown,
)
updateEmailSubtitle(it.emailAddress)
updateAutofill(it.showAutofill)
Expand Down Expand Up @@ -247,13 +245,7 @@ class NewSettingsActivity : DuckDuckGoActivity() {
}

private fun updateEmailSubtitle(emailAddress: String?) {
if (emailAddress.isNullOrEmpty()) {
viewsPrivacy.emailSetting.setSecondaryText(getString(com.duckduckgo.app.browser.R.string.settingsEmailProtectionSubtitle))
viewsPrivacy.emailSetting.setItemStatus(CheckListItem.CheckItemStatus.DISABLED)
} else {
viewsPrivacy.emailSetting.setSecondaryText(emailAddress)
viewsPrivacy.emailSetting.setItemStatus(CheckListItem.CheckItemStatus.ENABLED)
}
viewsPrivacy.emailSetting.setStatus(isOn = !emailAddress.isNullOrEmpty())
}

private fun updateSyncSetting(visible: Boolean) {
Expand All @@ -263,15 +255,7 @@ class NewSettingsActivity : DuckDuckGoActivity() {
}

private fun updateAutoconsent(enabled: Boolean) {
if (enabled) {
viewsPrivacy.cookiePopupProtectionSetting.setSecondaryText(getString(com.duckduckgo.app.browser.R.string.cookiePopupProtectionEnabled))
viewsPrivacy.cookiePopupProtectionSetting.setItemStatus(CheckListItem.CheckItemStatus.ENABLED)
} else {
viewsPrivacy.cookiePopupProtectionSetting.setSecondaryText(
getString(com.duckduckgo.app.browser.R.string.cookiePopupProtectionDescription),
)
viewsPrivacy.cookiePopupProtectionSetting.setItemStatus(CheckListItem.CheckItemStatus.DISABLED)
}
viewsPrivacy.cookiePopupProtectionSetting.setStatus(isOn = enabled)
}

private fun processCommand(it: Command?) {
Expand Down Expand Up @@ -302,38 +286,16 @@ class NewSettingsActivity : DuckDuckGoActivity() {
private fun updateDefaultBrowserViewVisibility(it: NewSettingsViewModel.ViewState) {
with(viewsPrivacy.setAsDefaultBrowserSetting) {
visibility = if (it.showDefaultBrowserSetting) {
if (it.isAppDefaultBrowser) {
setItemStatus(CheckListItem.CheckItemStatus.ENABLED)
setSecondaryText(getString(com.duckduckgo.app.browser.R.string.settingsDefaultBrowserSetDescription))
} else {
setItemStatus(CheckListItem.CheckItemStatus.DISABLED)
setSecondaryText(getString(com.duckduckgo.app.browser.R.string.settingsDefaultBrowserNotSetDescription))
}
setStatus(isOn = it.isAppDefaultBrowser)
View.VISIBLE
} else {
View.GONE
}
}
}

private fun updateDeviceShieldSettings(
appTPEnabled: Boolean,
appTrackingProtectionOnboardingShown: Boolean,
) {
with(viewsPrivacy) {
if (appTPEnabled) {
vpnSetting.setSecondaryText(getString(com.duckduckgo.app.browser.R.string.atp_SettingsDeviceShieldEnabled))
vpnSetting.setItemStatus(CheckListItem.CheckItemStatus.ENABLED)
} else {
if (appTrackingProtectionOnboardingShown) {
vpnSetting.setSecondaryText(getString(com.duckduckgo.app.browser.R.string.atp_SettingsDeviceShieldDisabled))
vpnSetting.setItemStatus(CheckListItem.CheckItemStatus.WARNING)
} else {
vpnSetting.setSecondaryText(getString(com.duckduckgo.app.browser.R.string.atp_SettingsDeviceShieldNeverEnabled))
vpnSetting.setItemStatus(CheckListItem.CheckItemStatus.DISABLED)
}
}
}
private fun updateDeviceShieldSettings(appTPEnabled: Boolean) {
viewsPrivacy.vpnSetting.setStatus(isOn = appTPEnabled)
}

private fun launchDefaultAppScreen() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,22 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.duckduckgo.anvil.annotations.ContributesViewModel
import com.duckduckgo.app.browser.defaultbrowsing.DefaultBrowserDetector
import com.duckduckgo.app.pixels.AppPixelName.*
import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_ABOUT_PRESSED
import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_ACCESSIBILITY_PRESSED
import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_APPEARANCE_PRESSED
import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_APPTP_PRESSED
import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_COOKIE_POPUP_PROTECTION_PRESSED
import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_DEFAULT_BROWSER_PRESSED
import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_EMAIL_PROTECTION_PRESSED
import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_FIRE_BUTTON_PRESSED
import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_GENERAL_PRESSED
import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_MAC_APP_PRESSED
import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_OPENED
import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_PERMISSIONS_PRESSED
import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_PRIVATE_SEARCH_PRESSED
import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_SYNC_PRESSED
import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_WEB_TRACKING_PROTECTION_PRESSED
import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_WINDOWS_APP_PRESSED
import com.duckduckgo.app.settings.NewSettingsViewModel.Command.LaunchAboutScreen
import com.duckduckgo.app.settings.NewSettingsViewModel.Command.LaunchAccessibilitySettings
import com.duckduckgo.app.settings.NewSettingsViewModel.Command.LaunchAddHomeScreenWidget
Expand Down Expand Up @@ -86,7 +101,6 @@ class NewSettingsViewModel @Inject constructor(
data class ViewState(
val showDefaultBrowserSetting: Boolean = false,
val isAppDefaultBrowser: Boolean = false,
val appTrackingProtectionOnboardingShown: Boolean = false,
val appTrackingProtectionEnabled: Boolean = false,
val emailAddress: String? = null,
val showAutofill: Boolean = false,
Expand Down Expand Up @@ -147,7 +161,6 @@ class NewSettingsViewModel @Inject constructor(
currentViewState().copy(
isAppDefaultBrowser = defaultBrowserAlready,
showDefaultBrowserSetting = defaultWebBrowserCapability.deviceSupportsDefaultBrowserConfiguration(),
appTrackingProtectionOnboardingShown = appTrackingProtection.isOnboarded(),
appTrackingProtectionEnabled = appTrackingProtection.isRunning(),
emailAddress = emailManager.getEmailAddress(),
showAutofill = autofillCapabilityChecker.canAccessCredentialManagementScreen(),
Expand All @@ -170,7 +183,6 @@ class NewSettingsViewModel @Inject constructor(
val isDeviceShieldEnabled = appTrackingProtection.isRunning()
val currentState = currentViewState()
viewState.value = currentState.copy(
appTrackingProtectionOnboardingShown = appTrackingProtection.isOnboarded(),
appTrackingProtectionEnabled = isDeviceShieldEnabled,
isPrivacyProEnabled = subscriptions.isEligible(),
)
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/layout/activity_settings_new.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@

<include
android:id="@+id/includeSettings"
layout="@layout/content_settings" />
layout="@layout/content_settings_new" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>
68 changes: 68 additions & 0 deletions app/src/main/res/layout/content_settings_new.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (c) 2017 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.
-->

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:ignore="Overdraw">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="20dp">

<include
android:id="@+id/contentSettingsPrivacy"
layout="@layout/content_settings_new_privacy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/keyline_4" />

<LinearLayout
android:id="@+id/settingsSectionPro"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.duckduckgo.common.ui.view.divider.HorizontalDivider
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>

<include
android:id="@+id/contentSettingsSettings"
layout="@layout/content_settings_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<include
android:id="@+id/contentSettingsMore"
layout="@layout/content_settings_other"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<include
android:id="@+id/contentSettingsInternal"
layout="@layout/content_settings_internal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

</LinearLayout>

</ScrollView>
75 changes: 75 additions & 0 deletions app/src/main/res/layout/content_settings_new_privacy.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (c) 2018 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.
-->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/settingsSectionPrivacy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<com.duckduckgo.common.ui.view.listitem.SectionHeaderListItem
android:id="@+id/settingsPrivacyTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:primaryText="@string/settingsHeadingPrivacy" />

<com.duckduckgo.common.ui.view.listitem.SettingsListItem
android:id="@+id/setAsDefaultBrowserSetting"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:leadingIcon="@drawable/ic_default_browser_mobile_color_24"
app:primaryText="@string/settingsDefaultBrowserTitle" />

<com.duckduckgo.common.ui.view.listitem.SettingsListItem
android:id="@+id/privateSearchSetting"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:isOn="true"
app:leadingIcon="@drawable/ic_find_search_color_24"
app:primaryText="@string/settingsPrivateSearchTitle" />

<com.duckduckgo.common.ui.view.listitem.SettingsListItem
android:id="@+id/webTrackingProtectionSetting"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:isOn="true"
app:leadingIcon="@drawable/ic_shield_color_24"
app:primaryText="@string/settingsWebTrackingProtectionTitle" />

<com.duckduckgo.common.ui.view.listitem.SettingsListItem
android:id="@+id/cookiePopupProtectionSetting"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:leadingIcon="@drawable/ic_cookie_color_24"
app:primaryText="@string/cookiePopupProtectionTitle" />

<com.duckduckgo.common.ui.view.listitem.SettingsListItem
android:id="@+id/vpnSetting"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:leadingIcon="@drawable/ic_lock_color_24"
app:primaryText="@string/atp_SettingsTitle" />

<com.duckduckgo.common.ui.view.listitem.SettingsListItem
android:id="@+id/emailSetting"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:leadingIcon="@drawable/ic_email_protection_color_24"
app:primaryText="@string/settingsEmailProtectionTitle"
app:showBetaPill="true" />

</LinearLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,6 @@ enum class Component {
SECTION_HEADER_LIST_ITEM,
SINGLE_LINE_LIST_ITEM,
TWO_LINE_LIST_ITEM,
SETTINGS_LIST_ITEM,
SECTION_DIVIDER,
}
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,9 @@ sealed class ComponentViewHolder(val view: View) : RecyclerView.ViewHolder(view)
}
}

class SettingsListItemComponentViewHolder(parent: ViewGroup) :
ComponentViewHolder(inflate(parent, R.layout.component_settings))

companion object {
fun create(
parent: ViewGroup,
Expand All @@ -408,6 +411,7 @@ sealed class ComponentViewHolder(val view: View) : RecyclerView.ViewHolder(view)
Component.SECTION_DIVIDER -> DividerComponentViewHolder(parent)
Component.CARD -> CardComponentViewHolder(parent)
Component.EXPANDABLE_LAYOUT -> ExpandableComponentViewHolder(parent)
Component.SETTINGS_LIST_ITEM -> SettingsListItemComponentViewHolder(parent)
else -> {
TODO()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ import com.duckduckgo.common.ui.themepreview.ui.component.Component
import com.duckduckgo.common.ui.themepreview.ui.component.Component.MENU_ITEM
import com.duckduckgo.common.ui.themepreview.ui.component.Component.POPUP_MENU_ITEM
import com.duckduckgo.common.ui.themepreview.ui.component.Component.SECTION_HEADER_LIST_ITEM
import com.duckduckgo.common.ui.themepreview.ui.component.Component.SETTINGS_LIST_ITEM
import com.duckduckgo.common.ui.themepreview.ui.component.Component.SINGLE_LINE_LIST_ITEM
import com.duckduckgo.common.ui.themepreview.ui.component.Component.TWO_LINE_LIST_ITEM
import com.duckduckgo.common.ui.themepreview.ui.component.ComponentFragment

class ComponentListItemsElementsFragment : ComponentFragment() {
override fun getComponents(): List<Component> {
return listOf(SECTION_HEADER_LIST_ITEM, SINGLE_LINE_LIST_ITEM, TWO_LINE_LIST_ITEM, MENU_ITEM, POPUP_MENU_ITEM)
return listOf(SECTION_HEADER_LIST_ITEM, SINGLE_LINE_LIST_ITEM, TWO_LINE_LIST_ITEM, SETTINGS_LIST_ITEM, MENU_ITEM, POPUP_MENU_ITEM)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2024 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.common.ui.view

import android.content.Context
import android.util.AttributeSet
import android.widget.LinearLayout
import com.duckduckgo.common.ui.viewbinding.viewBinding
import com.duckduckgo.mobile.android.databinding.ViewStatusIndicatorBinding

class StatusIndicator @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
) : LinearLayout(context, attrs, defStyleAttr) {

private val binding: ViewStatusIndicatorBinding by viewBinding()

fun setStatus(isOn: Boolean) {
if (isOn) {
binding.icon.isEnabled = true
// TODO copy changes
binding.label.text = "On"
} else {
binding.icon.isEnabled = false
// TODO copy changes
binding.label.text = "Off"
}
}
}
Loading
Loading