diff --git a/app/src/main/java/org/mozilla/fenix/BrowsingModeManager.kt b/app/src/main/java/org/mozilla/fenix/BrowsingModeManager.kt new file mode 100644 index 000000000..6e219951e --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/BrowsingModeManager.kt @@ -0,0 +1,51 @@ +/* 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/. */ + +package org.mozilla.fenix + +import android.preference.PreferenceManager + +interface BrowsingModeManager { + enum class Mode { + Normal, Private + } +} + +var temporaryModeStorage: BrowsingModeManager.Mode? = null +class DefaultBrowsingModeManager(private val homeActivity: HomeActivity) : BrowsingModeManager { + val isPrivate: Boolean + get() = mode == BrowsingModeManager.Mode.Private + var mode: BrowsingModeManager.Mode + get() = temporaryModeStorage!! + set(value) { + temporaryModeStorage = value + updateTheme(value) + setPreference() + } + + private fun updateTheme(mode: BrowsingModeManager.Mode) { + homeActivity.themeManager.apply { + val newTheme = when (mode) { + BrowsingModeManager.Mode.Normal -> ThemeManager.Theme.Light + BrowsingModeManager.Mode.Private -> ThemeManager.Theme.Private + } + setTheme(newTheme) + } + } + + private fun setPreference() { + PreferenceManager.getDefaultSharedPreferences(homeActivity) + .edit().putBoolean(homeActivity.getString(R.string.pref_key_private_mode), isPrivate).apply() + } + + init { + if (temporaryModeStorage == null) { + mode = when (PreferenceManager.getDefaultSharedPreferences(homeActivity) + .getBoolean(homeActivity.getString(R.string.pref_key_private_mode), false)) { + true -> BrowsingModeManager.Mode.Private + false -> BrowsingModeManager.Mode.Normal + } + } + } +} diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index bd75862ef..a9ccbef11 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -29,8 +29,12 @@ open class HomeActivity : AppCompatActivity() { } } + lateinit var browsingModeManager: DefaultBrowsingModeManager + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + browsingModeManager = DefaultBrowsingModeManager(this) + setContentView(R.layout.activity_home) setTheme(themeManager.currentTheme) @@ -85,7 +89,7 @@ open class HomeActivity : AppCompatActivity() { private fun openToBrowser() { val sessionId = SafeIntent(intent).getStringExtra(IntentProcessor.ACTIVE_SESSION_ID) val host = supportFragmentManager.findFragmentById(R.id.container) as NavHostFragment - val directions = NavGraphDirections.actionGlobalBrowser(sessionId) + val directions = NavGraphDirections.actionGlobalBrowser(sessionId, browsingModeManager.isPrivate) host.navController.navigate(directions) } diff --git a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt index 51834a96a..41feda56a 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt @@ -8,7 +8,6 @@ import android.annotation.SuppressLint import android.content.Context import android.content.Intent import android.os.Bundle -import android.preference.PreferenceManager import android.view.Gravity import android.view.LayoutInflater import android.view.View @@ -31,6 +30,7 @@ import mozilla.components.feature.session.SessionFeature import mozilla.components.feature.session.SessionUseCases import mozilla.components.support.base.feature.BackHandler import mozilla.components.support.base.feature.ViewBoundFeatureWrapper +import org.mozilla.fenix.BrowsingModeManager import org.mozilla.fenix.DefaultThemeManager import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R @@ -56,6 +56,7 @@ class BrowserFragment : Fragment(), BackHandler { private val findInPageIntegration = ViewBoundFeatureWrapper() private val customTabsToolbarFeature = ViewBoundFeatureWrapper() private val toolbarIntegration = ViewBoundFeatureWrapper() + private var isPrivate = false var sessionId: String? = null override fun onCreateView( @@ -63,12 +64,16 @@ class BrowserFragment : Fragment(), BackHandler { container: ViewGroup?, savedInstanceState: Bundle? ): View? { + require(arguments != null) sessionId = BrowserFragmentArgs.fromBundle(arguments!!).sessionId + isPrivate = BrowserFragmentArgs.fromBundle(arguments!!).isPrivateTab + val view = inflater.inflate(R.layout.fragment_browser, container, false) toolbarComponent = ToolbarComponent( view.browserLayout, ActionBusFactory.get(this), sessionId, + isPrivate, SearchState("", isEditing = false) ) @@ -105,7 +110,8 @@ class BrowserFragment : Fragment(), BackHandler { when (it) { is SearchAction.ToolbarTapped -> Navigation.findNavController(toolbar) .navigate(BrowserFragmentDirections.actionBrowserFragmentToSearchFragment( - requireComponents.core.sessionManager.selectedSession?.id + requireComponents.core.sessionManager.selectedSession?.id, + (activity as HomeActivity).browsingModeManager.isPrivate )) is SearchAction.ToolbarMenuItemTapped -> handleToolbarItemInteraction(it) } @@ -224,12 +230,11 @@ class BrowserFragment : Fragment(), BackHandler { ToolbarMenu.Item.Share -> requireComponents.core.sessionManager .selectedSession?.url?.apply { requireContext().share(this) } ToolbarMenu.Item.NewPrivateTab -> { - PreferenceManager.getDefaultSharedPreferences(context) - .edit().putBoolean( - context!!.getString(R.string.pref_key_private_mode), - !PreferenceManager.getDefaultSharedPreferences(context) - .getBoolean(context!!.getString(R.string.pref_key_private_mode), false) - ).apply() + val directions = BrowserFragmentDirections + .actionBrowserFragmentToSearchFragment(requireComponents.core.sessionManager.selectedSession?.id, + (activity as HomeActivity).browsingModeManager.isPrivate) + Navigation.findNavController(view!!).navigate(directions) + (activity as HomeActivity).browsingModeManager.mode = BrowsingModeManager.Mode.Private } ToolbarMenu.Item.FindInPage -> FindInPageIntegration.launch?.invoke() ToolbarMenu.Item.ReportIssue -> requireComponents.core.sessionManager @@ -241,9 +246,11 @@ class BrowserFragment : Fragment(), BackHandler { // TODO Help } ToolbarMenu.Item.NewTab -> { - val directions = - BrowserFragmentDirections.actionBrowserFragmentToSearchFragment(null) + val directions = BrowserFragmentDirections + .actionBrowserFragmentToSearchFragment(null, + (activity as HomeActivity).browsingModeManager.isPrivate) Navigation.findNavController(view!!).navigate(directions) + (activity as HomeActivity).browsingModeManager.mode = BrowsingModeManager.Mode.Normal } } } diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarComponent.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarComponent.kt index fd6593e46..82d6bdee9 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarComponent.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarComponent.kt @@ -21,6 +21,7 @@ class ToolbarComponent( private val container: ViewGroup, bus: ActionBusFactory, private val sessionId: String?, + private val isPrivate: Boolean, override var initialState: SearchState = SearchState("", false) ) : UIComponent( @@ -34,7 +35,7 @@ class ToolbarComponent( } } - override fun initView() = ToolbarUIView(sessionId, container, actionEmitter, changesObservable) + override fun initView() = ToolbarUIView(sessionId, isPrivate, container, actionEmitter, changesObservable) init { render(reducer) applyTheme() diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt index 030571d86..a125648e7 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt @@ -9,6 +9,7 @@ import android.graphics.PorterDuff import androidx.core.content.ContextCompat import androidx.navigation.Navigation import mozilla.components.browser.domains.autocomplete.DomainAutocompleteProvider +import mozilla.components.browser.session.Session import mozilla.components.browser.session.SessionManager import mozilla.components.browser.session.runWithSession import mozilla.components.browser.toolbar.BrowserToolbar @@ -28,7 +29,8 @@ class ToolbarIntegration( domainAutocompleteProvider: DomainAutocompleteProvider, historyStorage: HistoryStorage, sessionManager: SessionManager, - sessionId: String? = null + sessionId: String? = null, + isPrivate: Boolean ) : LifecycleAwareFeature { init { toolbar.setMenuBuilder(toolbarMenu.menuBuilder) @@ -68,10 +70,15 @@ class ToolbarIntegration( toolbar, context.components.core.sessionManager, if (sessionId == null) { - context.components.useCases.tabsUseCases.addTab + if (isPrivate) { + context.components.useCases.tabsUseCases.addPrivateTab + } else { + context.components.useCases.tabsUseCases.addTab + } } else context.components.useCases.sessionUseCases.loadUrl, { searchTerms -> if (sessionId == null) { - context.components.useCases.searchUseCases.newTabSearch.invoke(searchTerms) + context.components.useCases.searchUseCases.newTabSearch + .invoke(searchTerms, Session.Source.USER_ENTERED, true, isPrivate) } else context.components.useCases.searchUseCases.defaultSearch.invoke(searchTerms) }, sessionId ) diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarUIView.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarUIView.kt index 9fe92d9ac..201f14d33 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarUIView.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarUIView.kt @@ -19,6 +19,7 @@ import org.mozilla.fenix.mvi.UIView class ToolbarUIView( sessionId: String?, + isPrivate: Boolean, container: ViewGroup, actionEmitter: Observer, changesObservable: Observable @@ -72,7 +73,8 @@ class ToolbarUIView( ShippedDomainsProvider().also { it.initialize(this) }, components.core.historyStorage, components.core.sessionManager, - sessionId + sessionId, + isPrivate ) } } diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index 2d43bb5ea..62ced7646 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -21,9 +21,9 @@ import mozilla.components.browser.menu.BrowserMenu import mozilla.components.browser.session.Session import mozilla.components.browser.session.SessionManager import org.mozilla.fenix.DefaultThemeManager +import org.mozilla.fenix.BrowsingModeManager import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R -import org.mozilla.fenix.ThemeManager import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.home.sessions.SessionsComponent import org.mozilla.fenix.home.tabs.TabsAction @@ -47,8 +47,9 @@ class HomeFragment : Fragment() { savedInstanceState: Bundle? ): View? { val view = inflater.inflate(R.layout.fragment_home, container, false) - TabsComponent(view.homeLayout, bus, TabsState(requireComponents.core.sessionManager.sessions)) - SessionsComponent(view.homeLayout, bus) + TabsComponent(view.homeLayout, bus, (activity as HomeActivity).browsingModeManager.isPrivate, + TabsState(requireComponents.core.sessionManager.sessions)) + SessionsComponent(view.homeLayout, bus, (activity as HomeActivity).browsingModeManager.isPrivate) layoutComponents(view) ActionBusFactory.get(this).logMergedObservables() val activity = activity as HomeActivity @@ -68,7 +69,8 @@ class HomeFragment : Fragment() { when (it) { is TabsAction.Select -> { requireComponents.core.sessionManager.select(it.session) - val directions = HomeFragmentDirections.actionHomeFragmentToBrowserFragment(it.session.id) + val directions = HomeFragmentDirections.actionHomeFragmentToBrowserFragment(it.session.id, + (activity as HomeActivity).browsingModeManager.isPrivate) Navigation.findNavController(view).navigate(directions) } is TabsAction.Close -> { @@ -90,8 +92,9 @@ class HomeFragment : Fragment() { view.toolbar.setCompoundDrawablesWithIntrinsicBounds(searchIcon, null, null, null) val roundToInt = (toolbarPaddingDp * Resources.getSystem().displayMetrics.density).roundToInt() view.toolbar.compoundDrawablePadding = roundToInt - view.toolbar.setOnClickListener { - val directions = HomeFragmentDirections.actionHomeFragmentToSearchFragment(null) + view.toolbar.setOnClickListener { it -> + val directions = HomeFragmentDirections.actionHomeFragmentToSearchFragment(null, + (activity as HomeActivity).browsingModeManager.isPrivate) Navigation.findNavController(it).navigate(directions) } @@ -129,14 +132,10 @@ class HomeFragment : Fragment() { .isPrivate() privateBrowsingButton.setOnClickListener { - // When we build out private mode we will want to handle this logic elsewhere. - (requireActivity() as HomeActivity).themeManager.apply { - val newTheme = when (this.currentTheme) { - ThemeManager.Theme.Light -> ThemeManager.Theme.Private - ThemeManager.Theme.Private -> ThemeManager.Theme.Light - } - - setTheme(newTheme) + val browsingModeManager = (activity as HomeActivity).browsingModeManager + browsingModeManager.mode = when (browsingModeManager.mode) { + BrowsingModeManager.Mode.Normal -> BrowsingModeManager.Mode.Private + BrowsingModeManager.Mode.Private -> BrowsingModeManager.Mode.Normal } } } @@ -144,6 +143,7 @@ class HomeFragment : Fragment() { override fun onResume() { super.onResume() sessionObserver = subscribeToSessions() + sessionObserver?.onSessionsRestored() } override fun onPause() { @@ -170,31 +170,36 @@ class HomeFragment : Fragment() { override fun onSessionAdded(session: Session) { super.onSessionAdded(session) getManagedEmitter().onNext( - TabsChange.Changed(requireComponents.core.sessionManager.sessions)) + TabsChange.Changed(requireComponents.core.sessionManager.sessions + .filter { (activity as HomeActivity).browsingModeManager.isPrivate == it.private })) } override fun onSessionRemoved(session: Session) { super.onSessionRemoved(session) getManagedEmitter().onNext( - TabsChange.Changed(requireComponents.core.sessionManager.sessions)) + TabsChange.Changed(requireComponents.core.sessionManager.sessions + .filter { (activity as HomeActivity).browsingModeManager.isPrivate == it.private })) } override fun onSessionSelected(session: Session) { super.onSessionSelected(session) getManagedEmitter().onNext( - TabsChange.Changed(requireComponents.core.sessionManager.sessions)) + TabsChange.Changed(requireComponents.core.sessionManager.sessions + .filter { (activity as HomeActivity).browsingModeManager.isPrivate == it.private })) } override fun onSessionsRestored() { super.onSessionsRestored() getManagedEmitter().onNext( - TabsChange.Changed(requireComponents.core.sessionManager.sessions)) + TabsChange.Changed(requireComponents.core.sessionManager.sessions + .filter { (activity as HomeActivity).browsingModeManager.isPrivate == it.private })) } override fun onAllSessionsRemoved() { super.onAllSessionsRemoved() getManagedEmitter().onNext( - TabsChange.Changed(requireComponents.core.sessionManager.sessions)) + TabsChange.Changed(requireComponents.core.sessionManager.sessions + .filter { (activity as HomeActivity).browsingModeManager.isPrivate == it.private })) } } requireComponents.core.sessionManager.register(observer) diff --git a/app/src/main/java/org/mozilla/fenix/home/sessions/SessionsAdapter.kt b/app/src/main/java/org/mozilla/fenix/home/sessions/SessionsAdapter.kt index 01ed6d104..2acd56e88 100644 --- a/app/src/main/java/org/mozilla/fenix/home/sessions/SessionsAdapter.kt +++ b/app/src/main/java/org/mozilla/fenix/home/sessions/SessionsAdapter.kt @@ -4,6 +4,10 @@ package org.mozilla.fenix.home.sessions +import android.content.Context +import android.text.SpannableString +import android.text.style.ClickableSpan +import android.text.style.ForegroundColorSpan import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -12,38 +16,70 @@ import androidx.recyclerview.widget.RecyclerView import org.mozilla.fenix.R class SessionsAdapter : RecyclerView.Adapter() { + var isPrivate = false + var context: Context? = null + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false) return when (viewType) { HeaderViewHolder.LAYOUT_ID -> HeaderViewHolder(view) EmptyListViewHolder.LAYOUT_ID -> EmptyListViewHolder(view) + PrivateEmptyListViewHolder.LAYOUT_ID -> PrivateEmptyListViewHolder(view) else -> EmptyListViewHolder(view) } } override fun getItemViewType(position: Int) = when (position) { 0 -> HeaderViewHolder.LAYOUT_ID - 1 -> EmptyListViewHolder.LAYOUT_ID + 1 -> if (isPrivate) PrivateEmptyListViewHolder.LAYOUT_ID else EmptyListViewHolder.LAYOUT_ID else -> -1 } override fun getItemCount(): Int = 2 override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - if (holder is HeaderViewHolder) { - holder.headerText.text = "Today" + when (holder) { + is HeaderViewHolder -> if (isPrivate) { + holder.headerText.text = "Private Session" + } else { + holder.headerText.text = "Today" + } + is PrivateEmptyListViewHolder -> { + // Format the description text to include a hyperlink + val descriptionText = String + .format(holder.description.text.toString(), System.getProperty("line.separator")) + val linkStartIndex = descriptionText.indexOf("\n\n") + 2 + val linkAction = object : ClickableSpan() { + override fun onClick(widget: View?) { + // TODO Go to SUMO page + } + } + val textWithLink = SpannableString(descriptionText).apply { + setSpan(linkAction, linkStartIndex, descriptionText.length, 0) + + val colorSpan = ForegroundColorSpan(holder.description.currentTextColor) + setSpan(colorSpan, linkStartIndex, descriptionText.length, 0) + } + holder.description.text = textWithLink + } } } private class HeaderViewHolder(private val view: View) : RecyclerView.ViewHolder(view) { val headerText = view.findViewById(R.id.header_text) - companion object { const val LAYOUT_ID = R.layout.session_list_header } } + private class PrivateEmptyListViewHolder(private val view: View) : RecyclerView.ViewHolder(view) { + val description = view.findViewById(R.id.session_description) + companion object { + const val LAYOUT_ID = R.layout.session_list_empty_private + } + } + private class EmptyListViewHolder(private val view: View) : RecyclerView.ViewHolder(view) { companion object { const val LAYOUT_ID = R.layout.session_list_empty diff --git a/app/src/main/java/org/mozilla/fenix/home/sessions/SessionsComponent.kt b/app/src/main/java/org/mozilla/fenix/home/sessions/SessionsComponent.kt index 0468070b4..818ab0e71 100644 --- a/app/src/main/java/org/mozilla/fenix/home/sessions/SessionsComponent.kt +++ b/app/src/main/java/org/mozilla/fenix/home/sessions/SessionsComponent.kt @@ -15,6 +15,7 @@ import org.mozilla.fenix.mvi.ViewState class SessionsComponent( private val container: ViewGroup, bus: ActionBusFactory, + private val isPrivate: Boolean, override var initialState: SessionsState = SessionsState(emptyList()) ) : UIComponent( @@ -28,19 +29,19 @@ class SessionsComponent( } } - override fun initView() = SessionsUIView(container, actionEmitter, changesObservable) + override fun initView() = SessionsUIView(container, actionEmitter, isPrivate, changesObservable) init { render(reducer) } } -data class SessionsState(val sessions: List) : ViewState +data class SessionsState(val sessions: List, val isPrivate: Boolean = false) : ViewState sealed class SessionsAction : Action { object Select : SessionsAction() } sealed class SessionsChange : Change { - object Changed : SessionsChange() + data class Changed(val isPrivate: Boolean) : SessionsChange() } diff --git a/app/src/main/java/org/mozilla/fenix/home/sessions/SessionsUIView.kt b/app/src/main/java/org/mozilla/fenix/home/sessions/SessionsUIView.kt index 37d752bae..c3b36f223 100644 --- a/app/src/main/java/org/mozilla/fenix/home/sessions/SessionsUIView.kt +++ b/app/src/main/java/org/mozilla/fenix/home/sessions/SessionsUIView.kt @@ -17,6 +17,7 @@ import org.mozilla.fenix.mvi.UIView class SessionsUIView( container: ViewGroup, actionEmitter: Observer, + isPrivate: Boolean, changesObservable: Observable ) : UIView(container, actionEmitter, changesObservable) { @@ -30,6 +31,8 @@ class SessionsUIView( init { view.apply { layoutManager = LinearLayoutManager(container.context) + sessionsAdapter.isPrivate = isPrivate + sessionsAdapter.context = context adapter = sessionsAdapter } } diff --git a/app/src/main/java/org/mozilla/fenix/home/tabs/TabsComponent.kt b/app/src/main/java/org/mozilla/fenix/home/tabs/TabsComponent.kt index e17c733e7..bb11d25d1 100644 --- a/app/src/main/java/org/mozilla/fenix/home/tabs/TabsComponent.kt +++ b/app/src/main/java/org/mozilla/fenix/home/tabs/TabsComponent.kt @@ -15,6 +15,7 @@ import org.mozilla.fenix.mvi.ViewState class TabsComponent( private val container: ViewGroup, bus: ActionBusFactory, + private val isPrivate: Boolean, override var initialState: TabsState = TabsState(listOf()) ) : UIComponent( @@ -28,7 +29,7 @@ class TabsComponent( } } - override fun initView() = TabsUIView(container, actionEmitter, changesObservable) + override fun initView() = TabsUIView(container, actionEmitter, isPrivate, changesObservable) init { render(reducer) diff --git a/app/src/main/java/org/mozilla/fenix/home/tabs/TabsUIView.kt b/app/src/main/java/org/mozilla/fenix/home/tabs/TabsUIView.kt index cd4afe841..a24621363 100644 --- a/app/src/main/java/org/mozilla/fenix/home/tabs/TabsUIView.kt +++ b/app/src/main/java/org/mozilla/fenix/home/tabs/TabsUIView.kt @@ -28,6 +28,7 @@ import org.mozilla.fenix.mvi.UIView class TabsUIView( container: ViewGroup, actionEmitter: Observer, + isPrivate: Boolean, changesObservable: Observable ) : UIView(container, actionEmitter, changesObservable) { @@ -50,7 +51,8 @@ class TabsUIView( } header.add_tab_button.increaseTapArea(HomeFragment.addTabButtonIncreaseDps) header.add_tab_button.setOnClickListener { - val directions = HomeFragmentDirections.actionHomeFragmentToSearchFragment(null) + val directions = HomeFragmentDirections.actionHomeFragmentToSearchFragment(null, + isPrivate) Navigation.findNavController(it).navigate(directions) } header.tabs_overflow_button.increaseTapArea(HomeFragment.overflowButtonIncreaseDps) diff --git a/app/src/main/java/org/mozilla/fenix/library/history/HistoryFragment.kt b/app/src/main/java/org/mozilla/fenix/library/history/HistoryFragment.kt index a34c6c352..8bbc174d1 100644 --- a/app/src/main/java/org/mozilla/fenix/library/history/HistoryFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/library/history/HistoryFragment.kt @@ -21,6 +21,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.launch +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.mvi.ActionBusFactory @@ -57,7 +58,8 @@ class HistoryFragment : Fragment(), CoroutineScope { if (it is HistoryAction.Select) { Navigation.findNavController(requireActivity(), R.id.container).apply { navigate( - HistoryFragmentDirections.actionGlobalBrowser(null), + HistoryFragmentDirections.actionGlobalBrowser(null, + (activity as HomeActivity).browsingModeManager.isPrivate), NavOptions.Builder().setPopUpTo(R.id.homeFragment, false).build() ) } diff --git a/app/src/main/java/org/mozilla/fenix/search/SearchFragment.kt b/app/src/main/java/org/mozilla/fenix/search/SearchFragment.kt index 4e4d04792..108fe8db0 100644 --- a/app/src/main/java/org/mozilla/fenix/search/SearchFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/search/SearchFragment.kt @@ -13,6 +13,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.navigation.Navigation import kotlinx.android.synthetic.main.fragment_search.view.* +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.mvi.ActionBusFactory import org.mozilla.fenix.mvi.getManagedEmitter @@ -36,11 +37,13 @@ class SearchFragment : Fragment() { savedInstanceState: Bundle? ): View? { val sessionId = SearchFragmentArgs.fromBundle(arguments!!).sessionId + val isPrivate = SearchFragmentArgs.fromBundle(arguments!!).isPrivateTab val view = inflater.inflate(R.layout.fragment_search, container, false) toolbarComponent = ToolbarComponent( view.toolbar_wrapper, ActionBusFactory.get(this), sessionId, + isPrivate, SearchState("", isEditing = true) ) awesomeBarComponent = AwesomeBarComponent( @@ -83,7 +86,9 @@ class SearchFragment : Fragment() { private fun transitionToBrowser() { val sessionId = SearchFragmentArgs.fromBundle(arguments!!).sessionId - val directions = SearchFragmentDirections.actionSearchFragmentToBrowserFragment(sessionId) + val directions = SearchFragmentDirections.actionSearchFragmentToBrowserFragment(sessionId, + (activity as HomeActivity).browsingModeManager.isPrivate) + Navigation.findNavController(view!!.search_layout).navigate(directions) } } diff --git a/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt index 2cc085f38..6e1f1021b 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt @@ -88,7 +88,7 @@ class SettingsFragment : PreferenceFragmentCompat() { Navigation.findNavController(it) .navigate( SettingsFragmentDirections.actionGlobalBrowser( - null + null, false ) ) } diff --git a/app/src/main/res/drawable/session_background.xml b/app/src/main/res/drawable/session_background.xml new file mode 100644 index 000000000..827143d2c --- /dev/null +++ b/app/src/main/res/drawable/session_background.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/session_border.xml b/app/src/main/res/drawable/session_border.xml new file mode 100644 index 000000000..6b8aed892 --- /dev/null +++ b/app/src/main/res/drawable/session_border.xml @@ -0,0 +1,13 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/session_list_empty_private.xml b/app/src/main/res/layout/session_list_empty_private.xml new file mode 100644 index 000000000..61e817f7e --- /dev/null +++ b/app/src/main/res/layout/session_list_empty_private.xml @@ -0,0 +1,24 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/session_list_header.xml b/app/src/main/res/layout/session_list_header.xml index e4dfa0e36..8e8a421bb 100644 --- a/app/src/main/res/layout/session_list_header.xml +++ b/app/src/main/res/layout/session_list_header.xml @@ -5,8 +5,8 @@ diff --git a/app/src/main/res/layout/tab_list_header.xml b/app/src/main/res/layout/tab_list_header.xml index 27d487388..212dd5e04 100644 --- a/app/src/main/res/layout/tab_list_header.xml +++ b/app/src/main/res/layout/tab_list_header.xml @@ -16,7 +16,7 @@ android:layout_height="wrap_content" android:text="@string/tabs_header_title" android:textSize="24sp" - android:textColor="@android:color/black" + android:textColor="?attr/toolbarTextColor" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"/> @@ -33,6 +34,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="8dp" + android:tint="?attr/toolbarTextColor" android:src="@drawable/ic_menu" android:baselineAlignBottom="true" app:layout_constraintBaseline_toBaselineOf="@id/header_text" diff --git a/app/src/main/res/layout/tab_list_row.xml b/app/src/main/res/layout/tab_list_row.xml index 410d13ef2..44a513197 100644 --- a/app/src/main/res/layout/tab_list_row.xml +++ b/app/src/main/res/layout/tab_list_row.xml @@ -8,9 +8,11 @@ android:layout_marginBottom="8dp" android:padding="10dp" android:elevation="5dp" - app:cardCornerRadius="10dp"> + app:cardCornerRadius="10dp" + android:clipChildren="true"> + + diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 6053700f2..0996454ae 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -23,6 +23,7 @@ + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index b57ea833c..9139c7820 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -21,6 +21,7 @@ #f9f9fa #E9E9ED #20233E + #2f26c1 #1A665BFD #544CD9 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 067846743..04afe5dc3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -21,7 +21,8 @@ Fenix clears your search and browsing history when you close all Private Sessions tabs. While this doesn\'t make you anonymous to websites or your internet service provider, - it makes it easier to keep what you do online private from anyone else who uses this device. + it makes it easier to keep what you do online private from anyone else who uses this device.\n\nCommon myths + about private browsing Delete Session diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 7cc50b199..6683c69da 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -24,6 +24,7 @@ @drawable/home_search_background_light @color/search_text @color/photonGrey30 + @color/session_border_color @color/off_white @@ -64,6 +65,7 @@ @drawable/home_search_background_private @color/off_white @color/search_private_background + @color/private_browsing_primary @color/private_browsing_bottom_gradient