mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-09 19:10:42 +00:00
For #3360 - Adds empty state for TP Exceptions
This commit is contained in:
parent
7588251f8b
commit
9b5baa2358
@ -35,6 +35,7 @@ import mozilla.components.support.utils.SafeIntent
|
||||
import org.mozilla.fenix.components.FenixSnackbar
|
||||
import org.mozilla.fenix.components.isSentryEnabled
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.exceptions.ExceptionsFragmentDirections
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.getRootView
|
||||
import org.mozilla.fenix.ext.nav
|
||||
@ -230,15 +231,21 @@ open class HomeActivity : AppCompatActivity(), ShareFragment.TabsSharedCallback
|
||||
}
|
||||
BrowserDirection.FromSearch -> {
|
||||
fragmentId = R.id.searchFragment
|
||||
SearchFragmentDirections.actionSearchFragmentToBrowserFragment(customTabSessionId)
|
||||
SearchFragmentDirections.actionSearchFragmentToBrowserFragment(
|
||||
customTabSessionId
|
||||
)
|
||||
}
|
||||
BrowserDirection.FromSettings -> {
|
||||
fragmentId = R.id.settingsFragment
|
||||
SettingsFragmentDirections.actionSettingsFragmentToBrowserFragment(customTabSessionId)
|
||||
SettingsFragmentDirections.actionSettingsFragmentToBrowserFragment(
|
||||
customTabSessionId
|
||||
)
|
||||
}
|
||||
BrowserDirection.FromBookmarks -> {
|
||||
fragmentId = R.id.bookmarkFragment
|
||||
BookmarkFragmentDirections.actionBookmarkFragmentToBrowserFragment(customTabSessionId)
|
||||
BookmarkFragmentDirections.actionBookmarkFragmentToBrowserFragment(
|
||||
customTabSessionId
|
||||
)
|
||||
}
|
||||
BrowserDirection.FromBookmarksFolderSelect -> {
|
||||
fragmentId = R.id.bookmarkSelectFolderFragment
|
||||
@ -247,7 +254,9 @@ open class HomeActivity : AppCompatActivity(), ShareFragment.TabsSharedCallback
|
||||
}
|
||||
BrowserDirection.FromHistory -> {
|
||||
fragmentId = R.id.historyFragment
|
||||
HistoryFragmentDirections.actionHistoryFragmentToBrowserFragment(customTabSessionId)
|
||||
HistoryFragmentDirections.actionHistoryFragmentToBrowserFragment(
|
||||
customTabSessionId
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -259,7 +268,12 @@ open class HomeActivity : AppCompatActivity(), ShareFragment.TabsSharedCallback
|
||||
}
|
||||
}
|
||||
|
||||
private fun load(searchTermOrURL: String, newTab: Boolean, engine: SearchEngine?, forceSearch: Boolean) {
|
||||
private fun load(
|
||||
searchTermOrURL: String,
|
||||
newTab: Boolean,
|
||||
engine: SearchEngine?,
|
||||
forceSearch: Boolean
|
||||
) {
|
||||
val isPrivate = this.browsingModeManager.isPrivate
|
||||
|
||||
val loadUrlUseCase = if (newTab) {
|
||||
@ -273,7 +287,13 @@ open class HomeActivity : AppCompatActivity(), ShareFragment.TabsSharedCallback
|
||||
val searchUseCase: (String) -> Unit = { searchTerms ->
|
||||
if (newTab) {
|
||||
components.useCases.searchUseCases.newTabSearch
|
||||
.invoke(searchTerms, Session.Source.USER_ENTERED, true, isPrivate, searchEngine = engine)
|
||||
.invoke(
|
||||
searchTerms,
|
||||
Session.Source.USER_ENTERED,
|
||||
true,
|
||||
isPrivate,
|
||||
searchEngine = engine
|
||||
)
|
||||
} else components.useCases.searchUseCases.defaultSearch.invoke(searchTerms, engine)
|
||||
}
|
||||
|
||||
@ -377,5 +397,5 @@ open class HomeActivity : AppCompatActivity(), ShareFragment.TabsSharedCallback
|
||||
|
||||
enum class BrowserDirection {
|
||||
FromGlobal, FromHome, FromSearch, FromSettings, FromBookmarks,
|
||||
FromBookmarksFolderSelect, FromHistory
|
||||
FromBookmarksFolderSelect, FromHistory, FromExceptions
|
||||
}
|
||||
|
@ -5,13 +5,13 @@
|
||||
package org.mozilla.fenix.exceptions
|
||||
|
||||
import android.view.ViewGroup
|
||||
import org.mozilla.fenix.mvi.ViewState
|
||||
import org.mozilla.fenix.mvi.Change
|
||||
import org.mozilla.fenix.mvi.Action
|
||||
import org.mozilla.fenix.mvi.ActionBusFactory
|
||||
import org.mozilla.fenix.mvi.Change
|
||||
import org.mozilla.fenix.mvi.UIComponent
|
||||
import org.mozilla.fenix.mvi.UIComponentViewModelBase
|
||||
import org.mozilla.fenix.mvi.UIComponentViewModelProvider
|
||||
import org.mozilla.fenix.mvi.ViewState
|
||||
import org.mozilla.fenix.test.Mockable
|
||||
|
||||
data class ExceptionsItem(val url: String)
|
||||
@ -38,6 +38,7 @@ class ExceptionsComponent(
|
||||
data class ExceptionsState(val items: List<ExceptionsItem>) : ViewState
|
||||
|
||||
sealed class ExceptionsAction : Action {
|
||||
object LearnMore : ExceptionsAction()
|
||||
sealed class Delete : ExceptionsAction() {
|
||||
object All : Delete()
|
||||
data class One(val item: ExceptionsItem) : Delete()
|
||||
|
@ -17,11 +17,14 @@ import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.mozilla.fenix.BrowserDirection
|
||||
import org.mozilla.fenix.FenixViewModelProvider
|
||||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.mvi.ActionBusFactory
|
||||
import org.mozilla.fenix.mvi.getAutoDisposeObservable
|
||||
import org.mozilla.fenix.mvi.getManagedEmitter
|
||||
import org.mozilla.fenix.settings.SupportUtils
|
||||
|
||||
class ExceptionsFragment : Fragment() {
|
||||
private lateinit var exceptionsComponent: ExceptionsComponent
|
||||
@ -56,6 +59,14 @@ class ExceptionsFragment : Fragment() {
|
||||
getAutoDisposeObservable<ExceptionsAction>()
|
||||
.subscribe {
|
||||
when (it) {
|
||||
is ExceptionsAction.LearnMore -> {
|
||||
(activity as HomeActivity).openToBrowserAndLoad(
|
||||
searchTermOrURL = SupportUtils.getGenericSumoURLForTopic
|
||||
(SupportUtils.SumoTopic.TRACKING_PROTECTION),
|
||||
newTab = true,
|
||||
from = BrowserDirection.FromExceptions
|
||||
)
|
||||
}
|
||||
is ExceptionsAction.Delete.All -> viewLifecycleOwner.lifecycleScope.launch(IO) {
|
||||
val domains = ExceptionDomains.load(context!!)
|
||||
ExceptionDomains.remove(context!!, domains)
|
||||
|
@ -4,10 +4,15 @@
|
||||
|
||||
package org.mozilla.fenix.exceptions
|
||||
|
||||
import android.text.SpannableString
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.text.style.ClickableSpan
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Observer
|
||||
import io.reactivex.functions.Consumer
|
||||
@ -20,20 +25,45 @@ class ExceptionsUIView(
|
||||
actionEmitter: Observer<ExceptionsAction>,
|
||||
changesObservable: Observable<ExceptionsChange>
|
||||
) :
|
||||
UIView<ExceptionsState, ExceptionsAction, ExceptionsChange>(container, actionEmitter, changesObservable) {
|
||||
UIView<ExceptionsState, ExceptionsAction, ExceptionsChange>(
|
||||
container,
|
||||
actionEmitter,
|
||||
changesObservable
|
||||
) {
|
||||
|
||||
override val view: RecyclerView = LayoutInflater.from(container.context)
|
||||
override val view: FrameLayout = LayoutInflater.from(container.context)
|
||||
.inflate(R.layout.component_exceptions, container, true)
|
||||
.findViewById(R.id.exceptions_list)
|
||||
.findViewById(R.id.exceptions_wrapper)
|
||||
|
||||
init {
|
||||
view.exceptions_list.apply {
|
||||
adapter = ExceptionsAdapter(actionEmitter)
|
||||
layoutManager = LinearLayoutManager(container.context)
|
||||
}
|
||||
val descriptionText = String
|
||||
.format(
|
||||
view.exceptions_empty_view.text.toString(),
|
||||
System.getProperty("line.separator")
|
||||
)
|
||||
val linkStartIndex = descriptionText.indexOf("\n\n") + 2
|
||||
val linkAction = object : ClickableSpan() {
|
||||
override fun onClick(widget: View?) {
|
||||
actionEmitter.onNext(ExceptionsAction.LearnMore)
|
||||
}
|
||||
}
|
||||
val textWithLink = SpannableString(descriptionText).apply {
|
||||
setSpan(linkAction, linkStartIndex, descriptionText.length, 0)
|
||||
val colorSpan = ForegroundColorSpan(view.exceptions_empty_view.currentTextColor)
|
||||
setSpan(colorSpan, linkStartIndex, descriptionText.length, 0)
|
||||
}
|
||||
|
||||
view.exceptions_empty_view.movementMethod = LinkMovementMethod.getInstance()
|
||||
view.exceptions_empty_view.text = textWithLink
|
||||
}
|
||||
|
||||
override fun updateView() = Consumer<ExceptionsState> {
|
||||
view.exceptions_empty_view.visibility = if (it.items.isEmpty()) View.VISIBLE else View.GONE
|
||||
view.exceptions_list.visibility = if (it.items.isEmpty()) View.GONE else View.VISIBLE
|
||||
(view.exceptions_list.adapter as ExceptionsAdapter).updateData(it.items)
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,8 @@ object SupportUtils {
|
||||
) {
|
||||
HELP("faq-android"),
|
||||
PRIVATE_BROWSING_MYTHS("common-myths-about-private-browsing"),
|
||||
YOUR_RIGHTS("your-rights")
|
||||
YOUR_RIGHTS("your-rights"),
|
||||
TRACKING_PROTECTION("tracking-protection-firefox-preview")
|
||||
}
|
||||
|
||||
fun getSumoURLForTopic(context: Context, topic: SumoTopic): String {
|
||||
|
@ -11,7 +11,6 @@ import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.SwitchPreference
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.exceptions.ExceptionDomains
|
||||
import org.mozilla.fenix.ext.getPreferenceKey
|
||||
import org.mozilla.fenix.ext.requireComponents
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
@ -34,7 +33,8 @@ class TrackingProtectionFragment : PreferenceFragmentCompat() {
|
||||
preferenceTP?.isChecked = Settings.getInstance(context!!).shouldUseTrackingProtection
|
||||
preferenceTP?.onPreferenceChangeListener =
|
||||
Preference.OnPreferenceChangeListener { _, newValue ->
|
||||
Settings.getInstance(requireContext()).setTrackingProtection(newValue = newValue as Boolean)
|
||||
Settings.getInstance(requireContext())
|
||||
.setTrackingProtection(newValue = newValue as Boolean)
|
||||
with(requireComponents) {
|
||||
val policy = core.createTrackingProtectionPolicy(newValue)
|
||||
useCases.settingsUseCases.updateTrackingProtection.invoke(policy)
|
||||
@ -43,20 +43,16 @@ class TrackingProtectionFragment : PreferenceFragmentCompat() {
|
||||
true
|
||||
}
|
||||
|
||||
context?.let {
|
||||
val exceptionsEmpty = ExceptionDomains.load(it).isEmpty()
|
||||
val exceptions =
|
||||
it.getPreferenceKey(R.string.pref_key_tracking_protection_exceptions)
|
||||
val preferenceExceptions = findPreference<Preference>(exceptions)
|
||||
preferenceExceptions?.shouldDisableView = true
|
||||
preferenceExceptions?.isEnabled = !exceptionsEmpty
|
||||
preferenceExceptions?.onPreferenceClickListener = getClickListenerForExceptions()
|
||||
}
|
||||
val exceptions =
|
||||
context!!.getPreferenceKey(R.string.pref_key_tracking_protection_exceptions)
|
||||
val preferenceExceptions = findPreference<Preference>(exceptions)
|
||||
preferenceExceptions?.onPreferenceClickListener = getClickListenerForExceptions()
|
||||
}
|
||||
|
||||
private fun getClickListenerForExceptions(): Preference.OnPreferenceClickListener {
|
||||
return Preference.OnPreferenceClickListener {
|
||||
val directions = TrackingProtectionFragmentDirections.actionTrackingProtectionFragmentToExceptionsFragment()
|
||||
val directions =
|
||||
TrackingProtectionFragmentDirections.actionTrackingProtectionFragmentToExceptionsFragment()
|
||||
Navigation.findNavController(view!!).navigate(directions)
|
||||
true
|
||||
}
|
||||
|
@ -2,10 +2,27 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/exceptions_wrapper"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:visibility="gone"
|
||||
android:id="@+id/exceptions_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:listitem="@layout/exception_item"/>
|
||||
tools:listitem="@layout/exception_item" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/exceptions_empty_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top"
|
||||
android:layout_margin="12dp"
|
||||
android:text="@string/exceptions_empty_message"
|
||||
android:textColor="?secondaryText"
|
||||
android:textSize="16sp"
|
||||
android:visibility="visible" />
|
||||
</FrameLayout>
|
||||
|
@ -375,11 +375,17 @@
|
||||
<fragment
|
||||
android:id="@+id/deleteBrowsingDataFragment"
|
||||
android:name="org.mozilla.fenix.settings.DeleteBrowsingDataFragment"
|
||||
android:label="@string/preferences_delete_browsing_data"/>
|
||||
android:label="@string/preferences_delete_browsing_data" />
|
||||
<fragment
|
||||
android:id="@+id/exceptionsFragment"
|
||||
android:name="org.mozilla.fenix.exceptions.ExceptionsFragment"
|
||||
android:label="@string/preference_exceptions" />
|
||||
android:label="@string/preference_exceptions">
|
||||
<action
|
||||
android:id="@+id/action_exceptionsFragment_to_browserFragment"
|
||||
app:destination="@id/browserFragment"
|
||||
app:popUpTo="@id/settingsFragment"
|
||||
app:popUpToInclusive="true" />
|
||||
</fragment>
|
||||
<dialog
|
||||
android:id="@+id/createCollectionFragment"
|
||||
android:name="org.mozilla.fenix.collections.CreateCollectionFragment"
|
||||
|
@ -197,6 +197,8 @@
|
||||
<string name="preferences_tracking_protection_exceptions_description">Tracking Protection is off for these websites</string>
|
||||
<!-- Button in Exceptions Preference to turn on tracking protection for all sites (remove all exceptions) -->
|
||||
<string name="preferences_tracking_protection_exceptions_turn_on_for_all">Turn on for all sites</string>
|
||||
<!-- Text displayed when there are no exceptions, includes a learn more link that brings users to a tracking protection SUMO page -->
|
||||
<string name="exceptions_empty_message">Exceptions let you disable tracking protection for selected sites.\n\nLearn more</string>
|
||||
<!-- Description in Quick Settings that tells user tracking protection is off globally for all sites, and links to Settings to turn it on -->
|
||||
<string name="preferences_tracking_protection_turned_off_globally">Turned off globally, go to Settings to turn it on.</string>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user