Bug 1864709 - Add tab tools and tab counter UI

fenix/123.0
Noah Bond 6 months ago committed by mergify[bot]
parent 639a105db3
commit 13b5a80e5b

@ -0,0 +1,215 @@
/* 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.debugsettings.tabs
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.lib.state.ext.observeAsState
import org.mozilla.fenix.R
import org.mozilla.fenix.compose.Divider
import org.mozilla.fenix.compose.annotation.LightDarkPreview
import org.mozilla.fenix.ext.maxActiveTime
import org.mozilla.fenix.tabstray.ext.isNormalTabInactive
import org.mozilla.fenix.theme.FirefoxTheme
import org.mozilla.fenix.utils.Settings
/**
* Tab Tools UI for [DebugDrawer] that displays the tab counts and allows easy bulk-opening of tabs.
*
* @param store [BrowserStore] used to obtain the tab counts and fire any tab creation actions.
* @param settings Used to obtain whether the inactive tabs feature is enabled.
*/
@Composable
fun TabTools(
store: BrowserStore,
settings: Settings,
) {
val inactiveTabsEnabled = settings.inactiveTabsAreEnabled
val tabs by store.observeAsState(initialValue = emptyList()) { state -> state.tabs }
val totalTabCount = remember(tabs) { tabs.size }
val privateTabCount = remember(tabs) { tabs.filter { it.content.private }.size }
val inactiveTabCount = remember(tabs) {
if (inactiveTabsEnabled) {
tabs.filter { it.isNormalTabInactive(maxActiveTime) }.size
} else {
0
}
}
val activeTabCount = remember(tabs) { totalTabCount - privateTabCount - inactiveTabCount }
TabToolsContent(
activeTabCount = activeTabCount,
inactiveTabCount = inactiveTabCount,
privateTabCount = privateTabCount,
totalTabCount = totalTabCount,
inactiveTabsEnabled = inactiveTabsEnabled,
)
}
@Composable
private fun TabToolsContent(
activeTabCount: Int,
inactiveTabCount: Int,
privateTabCount: Int,
totalTabCount: Int,
inactiveTabsEnabled: Boolean,
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(all = 16.dp),
) {
TabCounter(
activeTabCount = activeTabCount,
inactiveTabCount = inactiveTabCount,
privateTabCount = privateTabCount,
totalTabCount = totalTabCount,
inactiveTabsEnabled = inactiveTabsEnabled,
)
}
}
@Composable
private fun TabCounter(
activeTabCount: Int,
inactiveTabCount: Int,
privateTabCount: Int,
totalTabCount: Int,
inactiveTabsEnabled: Boolean,
) {
Column {
Text(
text = stringResource(R.string.debug_drawer_tab_tools_tab_count_title),
color = FirefoxTheme.colors.textPrimary,
style = FirefoxTheme.typography.headline5,
)
Spacer(modifier = Modifier.height(16.dp))
TabCountRow(
tabType = stringResource(R.string.debug_drawer_tab_tools_tab_count_normal),
count = activeTabCount.toString(),
)
if (inactiveTabsEnabled) {
TabCountRow(
tabType = stringResource(R.string.debug_drawer_tab_tools_tab_count_inactive),
count = inactiveTabCount.toString(),
)
}
TabCountRow(
tabType = stringResource(R.string.debug_drawer_tab_tools_tab_count_private),
count = privateTabCount.toString(),
)
Spacer(modifier = Modifier.height(8.dp))
Divider()
Spacer(modifier = Modifier.height(8.dp))
TabCountRow(
tabType = stringResource(R.string.debug_drawer_tab_tools_tab_count_total),
count = totalTabCount.toString(),
)
}
}
@Composable
private fun TabCountRow(
tabType: String,
count: String,
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(start = 16.dp),
horizontalArrangement = Arrangement.SpaceBetween,
) {
Text(
text = tabType,
color = FirefoxTheme.colors.textSecondary,
style = FirefoxTheme.typography.headline6,
)
Text(
text = count,
color = FirefoxTheme.colors.textSecondary,
style = FirefoxTheme.typography.headline6,
)
}
}
private data class TabToolsPreviewModel(
val activeTabCount: Int = 0,
val inactiveTabCount: Int = 0,
val privateTabCount: Int = 0,
val inactiveTabsEnabled: Boolean = true,
) {
val totalTabCount = activeTabCount + inactiveTabCount + privateTabCount
}
private class TabToolsPreviewParameterProvider : PreviewParameterProvider<TabToolsPreviewModel> {
override val values: Sequence<TabToolsPreviewModel>
get() = sequenceOf(
TabToolsPreviewModel(
activeTabCount = 5,
inactiveTabCount = 7,
privateTabCount = 10,
inactiveTabsEnabled = true,
),
TabToolsPreviewModel(
activeTabCount = 25,
inactiveTabsEnabled = false,
),
TabToolsPreviewModel(
activeTabCount = 50,
inactiveTabCount = 700,
privateTabCount = 10,
inactiveTabsEnabled = true,
),
)
}
@Composable
@LightDarkPreview
private fun TabToolsPreview(
@PreviewParameter(TabToolsPreviewParameterProvider::class) model: TabToolsPreviewModel,
) {
with(model) {
FirefoxTheme {
Box(
modifier = Modifier.background(color = FirefoxTheme.colors.layer1),
) {
TabToolsContent(
activeTabCount = activeTabCount,
inactiveTabCount = inactiveTabCount,
privateTabCount = privateTabCount,
totalTabCount = totalTabCount,
inactiveTabsEnabled = inactiveTabsEnabled,
)
}
}
}
}

@ -2304,4 +2304,18 @@
<string name="download_languages_item_content_description_not_downloaded_state">Download</string>
<!-- Content description (not visible, for screen readers etc.): For a language list item that is selected. -->
<string name="download_languages_item_content_description_selected_state">Selected</string>
<!-- Debug drawer -->
<!-- The title of the Tab Tools feature in the Debug Drawer. -->
<string name="debug_drawer_tab_tools_title" tools:ignore="UnusedResources">Tab Tools</string>
<!-- The title of the tab count section in Tab Tools. -->
<string name="debug_drawer_tab_tools_tab_count_title">Tab count</string>
<!-- The active tab count category in the tab count section in Tab Tools. -->
<string name="debug_drawer_tab_tools_tab_count_normal">Active</string>
<!-- The inactive tab count category in the tab count section in Tab Tools. -->
<string name="debug_drawer_tab_tools_tab_count_inactive">Inactive</string>
<!-- The private tab count category in the tab count section in Tab Tools. -->
<string name="debug_drawer_tab_tools_tab_count_private">Private</string>
<!-- The total tab count category in the tab count section in Tab Tools. -->
<string name="debug_drawer_tab_tools_tab_count_total">Total</string>
</resources>

Loading…
Cancel
Save