mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-07-30 08:09:21 +00:00
feat: custom bottom nav in parity with tv icons
This commit is contained in:
parent
ed03cee241
commit
28674704eb
10 changed files with 301 additions and 56 deletions
|
|
@ -8,5 +8,6 @@ import androidx.compose.ui.unit.dp
|
|||
|
||||
internal actual val nuvioPlatformExtraTopPadding: Dp = 0.dp
|
||||
internal actual val nuvioPlatformExtraBottomPadding: Dp = 0.dp
|
||||
internal actual val nuvioBottomNavigationExtraVerticalPadding: Dp = 6.dp
|
||||
@Composable
|
||||
internal actual fun nuvioBottomNavigationBarInsets(): WindowInsets = WindowInsets.navigationBars
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M18.5,3H16C15.7239,3 15.5,3.22386 15.5,3.5V3.55891L19,6.35891V3.5C19,3.22386 18.7762,3 18.5,3Z"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M10.75,9.5C10.75,8.80964 11.3097,8.25 12,8.25C12.6904,8.25 13.25,8.80964 13.25,9.5C13.25,10.1904 12.6904,10.75 12,10.75C11.3097,10.75 10.75,10.1904 10.75,9.5Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M20.75,10.9605L21.5315,11.5857C21.855,11.8444 22.3269,11.792 22.5857,11.4685C22.8444,11.1451 22.792,10.6731 22.4685,10.4143L14.3426,3.91362C12.9731,2.81796 11.027,2.81796 9.65742,3.91362L1.53151,10.4143C1.20806,10.6731 1.15562,11.1451 1.41438,11.4685C1.67313,11.792 2.1451,11.8444 2.46855,11.5857L3.25003,10.9605V21.25H2.00003C1.58581,21.25 1.25003,21.5858 1.25003,22C1.25003,22.4142 1.58581,22.75 2.00003,22.75H22C22.4142,22.75 22.75,22.4142 22.75,22C22.75,21.5858 22.4142,21.25 22,21.25H20.75V10.9605ZM9.25003,9.5C9.25003,7.98122 10.4812,6.75 12,6.75C13.5188,6.75 14.75,7.98122 14.75,9.5C14.75,11.0188 13.5188,12.25 12,12.25C10.4812,12.25 9.25003,11.0188 9.25003,9.5ZM12.0494,13.25C12.7143,13.25 13.2871,13.2499 13.7459,13.3116C14.2375,13.3777 14.7088,13.5268 15.091,13.909C15.4733,14.2913 15.6223,14.7625 15.6884,15.2542C15.7462,15.6842 15.7498,16.2146 15.75,16.827C15.75,16.8679 15.75,16.9091 15.75,16.9506L15.75,21.25H14.25V17C14.25,16.2717 14.2484,15.8009 14.2018,15.454C14.1581,15.1287 14.0875,15.0268 14.0304,14.9697C13.9733,14.9126 13.8713,14.842 13.546,14.7982C13.1991,14.7516 12.7283,14.75 12,14.75C11.2717,14.75 10.8009,14.7516 10.4541,14.7982C10.1288,14.842 10.0268,14.9126 9.9697,14.9697C9.9126,15.0268 9.84199,15.1287 9.79826,15.454C9.75162,15.8009 9.75003,16.2717 9.75003,17V21.25H8.25003L8.25003,16.9506C8.24999,16.2858 8.24996,15.7129 8.31163,15.2542C8.37773,14.7625 8.52679,14.2913 8.90904,13.909C9.29128,13.5268 9.76255,13.3777 10.2542,13.3116C10.7129,13.2499 11.2858,13.25 11.9507,13.25H12.0494Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M8.50989,2.00001H15.49C15.7225,1.99995 15.9007,1.99991 16.0565,2.01515C17.1643,2.12352 18.0711,2.78958 18.4556,3.68678H5.54428C5.92879,2.78958 6.83555,2.12352 7.94337,2.01515C8.09917,1.99991 8.27741,1.99995 8.50989,2.00001Z"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M6.31052,4.72312C4.91989,4.72312 3.77963,5.56287 3.3991,6.67691C3.39117,6.70013 3.38356,6.72348 3.37629,6.74693C3.77444,6.62636 4.18881,6.54759 4.60827,6.49382C5.68865,6.35531 7.05399,6.35538 8.64002,6.35547L8.75846,6.35547L15.5321,6.35547C17.1181,6.35538 18.4835,6.35531 19.5639,6.49382C19.9833,6.54759 20.3977,6.62636 20.7958,6.74693C20.7886,6.72348 20.781,6.70013 20.773,6.67691C20.3925,5.56287 19.2522,4.72312 17.8616,4.72312H6.31052Z"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M8.67239,7.54204H15.3276C18.7024,7.54204 20.3898,7.54204 21.3377,8.52887C22.2855,9.5157 22.0625,11.0403 21.6165,14.0896L21.1935,16.9811C20.8437,19.3724 20.6689,20.568 19.7717,21.284C18.8745,22 17.5512,22 14.9046,22H9.09536C6.44881,22 5.12553,22 4.22834,21.284C3.33115,20.568 3.15626,19.3724 2.80648,16.9811L2.38351,14.0896C1.93748,11.0403 1.71447,9.5157 2.66232,8.52887C3.61017,7.54204 5.29758,7.54204 8.67239,7.54204ZM8,18.0001C8,17.5859 8.3731,17.2501 8.83333,17.2501H15.1667C15.6269,17.2501 16,17.5859 16,18.0001C16,18.4144 15.6269,18.7502 15.1667,18.7502H8.83333C8.3731,18.7502 8,18.4144 8,18.0001Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="20dp"
|
||||
android:height="20dp"
|
||||
android:viewportWidth="20"
|
||||
android:viewportHeight="20">
|
||||
<path
|
||||
android:pathData="M4,9a5,5 0,1 1,10 0A5,5 0,0 1,4 9zm5,-7a7,7 0,1 0,4.2 12.6 0.999,0.999 0,0 0,0.093 0.107l3,3a1,1 0,0 0,1.414 -1.414l-3,-3a0.999,0.999 0,0 0,-0.107 -0.093A7,7 0,0 0,9 2z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M14.2788,2.15224C13.9085,2 13.439,2 12.5,2C11.561,2 11.0915,2 10.7212,2.15224C10.2274,2.35523 9.83509,2.74458 9.63056,3.23463C9.53719,3.45834 9.50065,3.7185 9.48635,4.09799C9.46534,4.65568 9.17716,5.17189 8.69017,5.45093C8.20318,5.72996 7.60864,5.71954 7.11149,5.45876C6.77318,5.2813 6.52789,5.18262 6.28599,5.15102C5.75609,5.08178 5.22018,5.22429 4.79616,5.5472C4.47814,5.78938 4.24339,6.1929 3.7739,6.99993C3.30441,7.80697 3.06967,8.21048 3.01735,8.60491C2.94758,9.1308 3.09118,9.66266 3.41655,10.0835C3.56506,10.2756 3.77377,10.437 4.0977,10.639C4.57391,10.936 4.88032,11.4419 4.88029,12C4.88026,12.5581 4.57386,13.0639 4.0977,13.3608C3.77372,13.5629 3.56497,13.7244 3.41645,13.9165C3.09108,14.3373 2.94749,14.8691 3.01725,15.395C3.06957,15.7894 3.30432,16.193 3.7738,17C4.24329,17.807 4.47804,18.2106 4.79606,18.4527C5.22008,18.7756 5.75599,18.9181 6.28589,18.8489C6.52778,18.8173 6.77305,18.7186 7.11133,18.5412C7.60852,18.2804 8.2031,18.27 8.69012,18.549C9.17714,18.8281 9.46533,19.3443 9.48635,19.9021C9.50065,20.2815 9.53719,20.5417 9.63056,20.7654C9.83509,21.2554 10.2274,21.6448 10.7212,21.8478C11.0915,22 11.561,22 12.5,22C13.439,22 13.9085,22 14.2788,21.8478C14.7726,21.6448 15.1649,21.2554 15.3694,20.7654C15.4628,20.5417 15.4994,20.2815 15.5137,19.902C15.5347,19.3443 15.8228,18.8281 16.3098,18.549C16.7968,18.2699 17.3914,18.2804 17.8886,18.5412C18.2269,18.7186 18.4721,18.8172 18.714,18.8488C19.2439,18.9181 19.7798,18.7756 20.2038,18.4527C20.5219,18.2105 20.7566,17.807 21.2261,16.9999C21.6956,16.1929 21.9303,15.7894 21.9827,15.395C22.0524,14.8691 21.9088,14.3372 21.5835,13.9164C21.4349,13.7243 21.2262,13.5628 20.9022,13.3608C20.4261,13.0639 20.1197,12.558 20.1197,11.9999C20.1197,11.4418 20.4261,10.9361 20.9022,10.6392C21.2263,10.4371 21.435,10.2757 21.5836,10.0835C21.9089,9.66273 22.0525,9.13087 21.9828,8.60497C21.9304,8.21055 21.6957,7.80703 21.2262,7C20.7567,6.19297 20.522,5.78945 20.2039,5.54727C19.7799,5.22436 19.244,5.08185 18.7141,5.15109C18.4722,5.18269 18.2269,5.28136 17.8887,5.4588C17.3915,5.71959 16.7969,5.73002 16.3099,5.45096C15.8229,5.17191 15.5347,4.65566 15.5136,4.09794C15.4993,3.71848 15.4628,3.45833 15.3694,3.23463C15.1649,2.74458 14.7726,2.35523 14.2788,2.15224ZM12.5,15C14.1695,15 15.5228,13.6569 15.5228,12C15.5228,10.3431 14.1695,9 12.5,9C10.8305,9 9.47716,10.3431 9.47716,12C9.47716,13.6569 10.8305,15 12.5,15Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
|
|
@ -27,9 +27,7 @@ import androidx.compose.foundation.layout.size
|
|||
import androidx.compose.foundation.layout.statusBars
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.Home
|
||||
import androidx.compose.material.icons.rounded.Search
|
||||
import androidx.compose.material.icons.rounded.VideoLibrary
|
||||
import androidx.compose.material.icons.filled.Home
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.remember
|
||||
|
|
@ -37,9 +35,7 @@ import androidx.compose.runtime.rememberCoroutineScope
|
|||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.NavigationBar
|
||||
import androidx.compose.material3.NavigationBarItem
|
||||
import androidx.compose.material3.NavigationBarItemDefaults
|
||||
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
|
|
@ -75,7 +71,7 @@ import com.nuvio.app.core.auth.AuthState
|
|||
import com.nuvio.app.core.deeplink.AppDeepLink
|
||||
import com.nuvio.app.core.deeplink.AppDeepLinkRepository
|
||||
import com.nuvio.app.core.sync.SyncManager
|
||||
import com.nuvio.app.core.ui.nuvioBottomNavigationBarInsets
|
||||
import com.nuvio.app.core.ui.NuvioNavigationBar
|
||||
import com.nuvio.app.core.ui.NuvioPosterActionSheet
|
||||
import com.nuvio.app.core.ui.PlatformBackHandler
|
||||
import com.nuvio.app.core.ui.TraktListPickerDialog
|
||||
|
|
@ -145,6 +141,9 @@ import kotlinx.coroutines.launch
|
|||
import kotlinx.serialization.Serializable
|
||||
import nuvio.composeapp.generated.resources.Res
|
||||
import nuvio.composeapp.generated.resources.app_logo_wordmark
|
||||
import nuvio.composeapp.generated.resources.sidebar_library
|
||||
import nuvio.composeapp.generated.resources.sidebar_search
|
||||
import org.jetbrains.compose.resources.DrawableResource
|
||||
import org.jetbrains.compose.resources.painterResource
|
||||
|
||||
@Serializable
|
||||
|
|
@ -556,52 +555,36 @@ private fun MainAppContent(
|
|||
contentWindowInsets = WindowInsets(0),
|
||||
bottomBar = {
|
||||
if (!isTabletLayout) {
|
||||
val navigationItemColors = NavigationBarItemDefaults.colors(
|
||||
selectedIconColor = MaterialTheme.colorScheme.onPrimaryContainer,
|
||||
selectedTextColor = MaterialTheme.colorScheme.onPrimaryContainer,
|
||||
indicatorColor = MaterialTheme.colorScheme.primaryContainer,
|
||||
unselectedIconColor = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
unselectedTextColor = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
NavigationBar(
|
||||
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
windowInsets = nuvioBottomNavigationBarInsets(),
|
||||
) {
|
||||
NavigationBarItem(
|
||||
NuvioNavigationBar {
|
||||
NavItem(
|
||||
selected = selectedTab == AppScreenTab.Home,
|
||||
onClick = { selectedTab = AppScreenTab.Home },
|
||||
icon = { Icon(Icons.Rounded.Home, contentDescription = null) },
|
||||
label = { Text("Home") },
|
||||
colors = navigationItemColors,
|
||||
icon = Icons.Filled.Home,
|
||||
contentDescription = "Home",
|
||||
)
|
||||
NavigationBarItem(
|
||||
NavItem(
|
||||
selected = selectedTab == AppScreenTab.Search,
|
||||
onClick = { selectedTab = AppScreenTab.Search },
|
||||
icon = { Icon(Icons.Rounded.Search, contentDescription = null) },
|
||||
label = { Text("Search") },
|
||||
colors = navigationItemColors,
|
||||
icon = Res.drawable.sidebar_search,
|
||||
contentDescription = "Search",
|
||||
)
|
||||
NavigationBarItem(
|
||||
NavItem(
|
||||
selected = selectedTab == AppScreenTab.Library,
|
||||
onClick = { selectedTab = AppScreenTab.Library },
|
||||
icon = { Icon(Icons.Rounded.VideoLibrary, contentDescription = null) },
|
||||
label = { Text("Library") },
|
||||
colors = navigationItemColors,
|
||||
icon = Res.drawable.sidebar_library,
|
||||
contentDescription = "Library",
|
||||
)
|
||||
NavigationBarItem(
|
||||
NavItem(
|
||||
selected = selectedTab == AppScreenTab.Settings,
|
||||
onClick = { selectedTab = AppScreenTab.Settings },
|
||||
icon = {
|
||||
ProfileSwitcherTab(
|
||||
selected = selectedTab == AppScreenTab.Settings,
|
||||
onClick = { selectedTab = AppScreenTab.Settings },
|
||||
onProfileSelected = onProfileSelected,
|
||||
onAddProfileRequested = onSwitchProfile,
|
||||
)
|
||||
},
|
||||
label = { Text("Profile") },
|
||||
colors = navigationItemColors,
|
||||
)
|
||||
) {
|
||||
ProfileSwitcherTab(
|
||||
selected = selectedTab == AppScreenTab.Settings,
|
||||
onClick = { selectedTab = AppScreenTab.Settings },
|
||||
onProfileSelected = onProfileSelected,
|
||||
onAddProfileRequested = onSwitchProfile,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -1430,9 +1413,14 @@ private fun TabletFloatingTopBar(
|
|||
onClick = { onTabSelected(AppScreenTab.Home) },
|
||||
icon = {
|
||||
Icon(
|
||||
imageVector = Icons.Rounded.Home,
|
||||
contentDescription = null,
|
||||
imageVector = Icons.Filled.Home,
|
||||
contentDescription = "Home",
|
||||
modifier = Modifier.size(18.dp),
|
||||
tint = if (selectedTab == AppScreenTab.Home) {
|
||||
MaterialTheme.colorScheme.onPrimaryContainer
|
||||
} else {
|
||||
MaterialTheme.colorScheme.onSurfaceVariant
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
|
|
@ -1442,9 +1430,14 @@ private fun TabletFloatingTopBar(
|
|||
onClick = { onTabSelected(AppScreenTab.Search) },
|
||||
icon = {
|
||||
Icon(
|
||||
imageVector = Icons.Rounded.Search,
|
||||
contentDescription = null,
|
||||
painter = painterResource(Res.drawable.sidebar_search),
|
||||
contentDescription = "Search",
|
||||
modifier = Modifier.size(18.dp),
|
||||
tint = if (selectedTab == AppScreenTab.Search) {
|
||||
MaterialTheme.colorScheme.onPrimaryContainer
|
||||
} else {
|
||||
MaterialTheme.colorScheme.onSurfaceVariant
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
|
|
@ -1454,9 +1447,14 @@ private fun TabletFloatingTopBar(
|
|||
onClick = { onTabSelected(AppScreenTab.Library) },
|
||||
icon = {
|
||||
Icon(
|
||||
imageVector = Icons.Rounded.VideoLibrary,
|
||||
contentDescription = null,
|
||||
painter = painterResource(Res.drawable.sidebar_library),
|
||||
contentDescription = "Library",
|
||||
modifier = Modifier.size(18.dp),
|
||||
tint = if (selectedTab == AppScreenTab.Library) {
|
||||
MaterialTheme.colorScheme.onPrimaryContainer
|
||||
} else {
|
||||
MaterialTheme.colorScheme.onSurfaceVariant
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,178 @@
|
|||
package com.nuvio.app.core.ui
|
||||
|
||||
import androidx.compose.animation.animateColorAsState
|
||||
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.asPaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.foundation.selection.selectable
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.semantics.Role
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.jetbrains.compose.resources.DrawableResource
|
||||
import org.jetbrains.compose.resources.painterResource
|
||||
|
||||
@Composable
|
||||
fun NuvioNavigationBar(
|
||||
modifier: Modifier = Modifier,
|
||||
content: @Composable NuvioNavigationBarScope.() -> Unit,
|
||||
) {
|
||||
Column(modifier.fillMaxWidth()) {
|
||||
HorizontalDivider(
|
||||
thickness = 0.5.dp,
|
||||
color = MaterialTheme.colorScheme.outlineVariant,
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(nuvioBottomNavigationBarInsets().asPaddingValues())
|
||||
.padding(horizontal = 4.dp, vertical = nuvioBottomNavigationExtraVerticalPadding),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally),
|
||||
) {
|
||||
NuvioNavigationBarScopeImpl(this).content()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface NuvioNavigationBarScope {
|
||||
@Composable
|
||||
fun NavItem(
|
||||
selected: Boolean,
|
||||
onClick: () -> Unit,
|
||||
icon: ImageVector,
|
||||
contentDescription: String?,
|
||||
modifier: Modifier = Modifier,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun NavItem(
|
||||
selected: Boolean,
|
||||
onClick: () -> Unit,
|
||||
icon: DrawableResource,
|
||||
contentDescription: String?,
|
||||
modifier: Modifier = Modifier,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun NavItem(
|
||||
selected: Boolean,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
content: @Composable () -> Unit,
|
||||
)
|
||||
}
|
||||
|
||||
private class NuvioNavigationBarScopeImpl(
|
||||
private val rowScope: androidx.compose.foundation.layout.RowScope,
|
||||
) : NuvioNavigationBarScope {
|
||||
|
||||
@Composable
|
||||
override fun NavItem(
|
||||
selected: Boolean,
|
||||
onClick: () -> Unit,
|
||||
icon: ImageVector,
|
||||
contentDescription: String?,
|
||||
modifier: Modifier,
|
||||
) {
|
||||
val iconColor by animateColorAsState(
|
||||
targetValue = if (selected) MaterialTheme.colorScheme.primary
|
||||
else MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
with(rowScope) {
|
||||
Icon(
|
||||
modifier = modifier
|
||||
.widthIn(max = 150.dp)
|
||||
.fillMaxWidth()
|
||||
.weight(1f, fill = false)
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.selectable(
|
||||
selected = selected,
|
||||
enabled = true,
|
||||
role = Role.Tab,
|
||||
onClick = onClick,
|
||||
)
|
||||
.padding(10.dp)
|
||||
.size(28.dp),
|
||||
imageVector = icon,
|
||||
contentDescription = contentDescription,
|
||||
tint = iconColor,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun NavItem(
|
||||
selected: Boolean,
|
||||
onClick: () -> Unit,
|
||||
icon: DrawableResource,
|
||||
contentDescription: String?,
|
||||
modifier: Modifier,
|
||||
) {
|
||||
val iconColor by animateColorAsState(
|
||||
targetValue = if (selected) MaterialTheme.colorScheme.primary
|
||||
else MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
with(rowScope) {
|
||||
Icon(
|
||||
modifier = modifier
|
||||
.widthIn(max = 150.dp)
|
||||
.fillMaxWidth()
|
||||
.weight(1f, fill = false)
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.selectable(
|
||||
selected = selected,
|
||||
enabled = true,
|
||||
role = Role.Tab,
|
||||
onClick = onClick,
|
||||
)
|
||||
.padding(10.dp)
|
||||
.size(28.dp),
|
||||
painter = painterResource(icon),
|
||||
contentDescription = contentDescription,
|
||||
tint = iconColor,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun NavItem(
|
||||
selected: Boolean,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier,
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
with(rowScope) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.widthIn(max = 150.dp)
|
||||
.fillMaxWidth()
|
||||
.weight(1f, fill = false)
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.selectable(
|
||||
selected = selected,
|
||||
enabled = true,
|
||||
role = Role.Tab,
|
||||
onClick = onClick,
|
||||
)
|
||||
.padding(10.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,5 +6,6 @@ import androidx.compose.ui.unit.Dp
|
|||
|
||||
internal expect val nuvioPlatformExtraTopPadding: Dp
|
||||
internal expect val nuvioPlatformExtraBottomPadding: Dp
|
||||
internal expect val nuvioBottomNavigationExtraVerticalPadding: Dp
|
||||
@Composable
|
||||
internal expect fun nuvioBottomNavigationBarInsets(): WindowInsets
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ fun ProfileSwitcherTab(
|
|||
onClick: () -> Unit,
|
||||
onProfileSelected: (NuvioProfile) -> Unit,
|
||||
onAddProfileRequested: () -> Unit,
|
||||
triggerContent: (@Composable (selected: Boolean) -> Unit)? = null,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val profileState by ProfileRepository.state.collectAsStateWithLifecycle()
|
||||
|
|
@ -144,13 +145,16 @@ fun ProfileSwitcherTab(
|
|||
},
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
// The avatar icon for the bottom navigation
|
||||
ActiveProfileMiniAvatar(
|
||||
profile = activeProfile,
|
||||
avatars = avatars,
|
||||
selected = selected,
|
||||
size = 28,
|
||||
)
|
||||
if (triggerContent != null) {
|
||||
triggerContent(selected)
|
||||
} else {
|
||||
ActiveProfileMiniAvatar(
|
||||
profile = activeProfile,
|
||||
avatars = avatars,
|
||||
selected = selected,
|
||||
size = 28,
|
||||
)
|
||||
}
|
||||
|
||||
// Floating profile popup (stays composed during exit animation)
|
||||
if (popupVisible && profiles.isNotEmpty()) {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,17 @@
|
|||
package com.nuvio.app.core.ui
|
||||
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||
import androidx.compose.foundation.layout.only
|
||||
import androidx.compose.foundation.layout.safeDrawing
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
internal actual val nuvioPlatformExtraTopPadding: Dp = 0.dp
|
||||
internal actual val nuvioPlatformExtraBottomPadding: Dp = 0.dp
|
||||
internal actual val nuvioBottomNavigationExtraVerticalPadding: Dp = 0.dp
|
||||
|
||||
@Composable
|
||||
internal actual fun nuvioBottomNavigationBarInsets(): WindowInsets = WindowInsets(0)
|
||||
internal actual fun nuvioBottomNavigationBarInsets(): WindowInsets =
|
||||
WindowInsets.safeDrawing.only(WindowInsetsSides.Bottom)
|
||||
|
|
|
|||
Loading…
Reference in a new issue