Improve Compose group paging (#6105)
This commit is contained in:
1 parent
3c9336f671
commit
26099c198e
2 files changed
+68
-56
No files matched your search
@@ -333,25 +333,14 @@ object CoreServiceManager {
|
||||
}
|
||||
}
|
||||
|
||||
val endpoint = if (time >= 0) SpeedtestManager.getRemoteIPInfo() else null
|
||||
val result = ConnectionTestResult(
|
||||
delayMillis = time,
|
||||
errorMessage = errorStr,
|
||||
country = endpoint?.country,
|
||||
ipAddress = endpoint?.ipAddress,
|
||||
)
|
||||
MessageHelper.sendMsg2UI(service, AppConfig.MSG_MEASURE_DELAY_RESULT, result)
|
||||
|
||||
// Only fetch IP info if the delay test was successful
|
||||
if (time >= 0) {
|
||||
SpeedtestManager.getRemoteIPInfo()?.let { ip ->
|
||||
MessageHelper.sendMsg2UI(
|
||||
service,
|
||||
AppConfig.MSG_MEASURE_DELAY_RESULT,
|
||||
result.copy(
|
||||
country = ip.country,
|
||||
ipAddress = ip.ipAddress,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,27 @@
|
||||
package com.v2ray.ang.ui.main
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.PrimaryScrollableTabRow
|
||||
import androidx.compose.material3.Tab
|
||||
import androidx.compose.material3.TabRowDefaults
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.v2ray.ang.dto.GroupMapItem
|
||||
@@ -28,32 +36,34 @@ fun GroupTabBar(
|
||||
onTabClick: (Int) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
PrimaryScrollableTabRow(
|
||||
selectedTabIndex = selectedTabIndex.coerceIn(0, groups.lastIndex),
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
containerColor = MaterialTheme.colorScheme.surface.copy(alpha = 0.95f),
|
||||
contentColor = MaterialTheme.colorScheme.onSurface,
|
||||
edgePadding = 16.dp,
|
||||
minTabWidth = 56.dp,
|
||||
indicator = {
|
||||
TabRowDefaults.PrimaryIndicator(
|
||||
modifier = Modifier
|
||||
.tabIndicatorOffset(
|
||||
selectedTabIndex = selectedTabIndex.coerceIn(0, groups.lastIndex),
|
||||
matchContentSize = true
|
||||
)
|
||||
.clip(RoundedCornerShape(3.dp)),
|
||||
width = Dp.Unspecified,
|
||||
color = MaterialTheme.colorScheme.secondary
|
||||
)
|
||||
},
|
||||
divider = {}
|
||||
val selectedIndex = selectedTabIndex.coerceIn(0, groups.lastIndex)
|
||||
val listState = rememberLazyListState(initialFirstVisibleItemIndex = selectedIndex)
|
||||
|
||||
LaunchedEffect(selectedIndex) {
|
||||
if (listState.layoutInfo.visibleItemsInfo.none { it.index == selectedIndex }) {
|
||||
listState.animateScrollToItem(selectedIndex)
|
||||
}
|
||||
}
|
||||
|
||||
LazyRow(
|
||||
state = listState,
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.background(MaterialTheme.colorScheme.surface.copy(alpha = 0.95f)),
|
||||
contentPadding = PaddingValues(horizontal = 16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
groups.forEachIndexed { index, group ->
|
||||
itemsIndexed(
|
||||
items = groups,
|
||||
key = { _, group -> group.id },
|
||||
) { index, group ->
|
||||
val serverFlow = remember(group.id, mainViewModel) {
|
||||
mainViewModel.serversForGroup(group.id)
|
||||
}
|
||||
GroupTabItem(
|
||||
group = group,
|
||||
selected = index == selectedTabIndex,
|
||||
serverFlowProvider = { mainViewModel.serversForGroup(group.id) },
|
||||
selected = index == selectedIndex,
|
||||
serverFlow = serverFlow,
|
||||
onClick = { onTabClick(index) }
|
||||
)
|
||||
}
|
||||
@@ -64,26 +74,39 @@ fun GroupTabBar(
|
||||
private fun GroupTabItem(
|
||||
group: GroupMapItem,
|
||||
selected: Boolean,
|
||||
serverFlowProvider: () -> StateFlow<List<ServersCache>>,
|
||||
serverFlow: StateFlow<List<ServersCache>>,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
val serverFlow = remember(group.id) { serverFlowProvider() }
|
||||
val servers by serverFlow.collectAsStateWithLifecycle()
|
||||
Tab(
|
||||
selected = selected,
|
||||
onClick = onClick,
|
||||
text = {
|
||||
val text = if (group.id.isEmpty()) {
|
||||
group.remarks
|
||||
} else {
|
||||
"${group.remarks} (${servers.size})"
|
||||
val text = if (group.id.isEmpty()) {
|
||||
group.remarks
|
||||
} else {
|
||||
"${group.remarks} (${servers.size})"
|
||||
}
|
||||
|
||||
Box(Modifier.widthIn(min = 56.dp)) {
|
||||
Tab(
|
||||
selected = selected,
|
||||
onClick = onClick,
|
||||
modifier = Modifier.heightIn(min = 48.dp),
|
||||
text = {
|
||||
Text(
|
||||
text = text,
|
||||
maxLines = 1,
|
||||
softWrap = false,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = text,
|
||||
maxLines = 1,
|
||||
softWrap = false,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
if (selected) {
|
||||
Box(
|
||||
Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.fillMaxWidth()
|
||||
.height(3.dp)
|
||||
.clip(RoundedCornerShape(3.dp))
|
||||
.background(MaterialTheme.colorScheme.secondary)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user