mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
refactor: replace Scaffold with internal component
This commit is contained in:
parent
1c863f35f6
commit
7794c08190
7 changed files with 72 additions and 135 deletions
|
|
@ -23,7 +23,6 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
|
|
@ -36,13 +35,9 @@ import androidx.compose.foundation.text.selection.SelectionContainer
|
|||
import androidx.compose.material.Button
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TopAppBar
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.outlined.CloudDownload
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
|
|
@ -64,13 +59,13 @@ import androidx.compose.ui.text.font.FontWeight
|
|||
import androidx.compose.ui.tooling.preview.PreviewLightDark
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.database.entity.MeshLog
|
||||
import com.geeksville.mesh.model.DebugViewModel
|
||||
import com.geeksville.mesh.ui.components.BaseScaffold
|
||||
import com.geeksville.mesh.ui.theme.AppTheme
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import java.text.DateFormat
|
||||
|
|
@ -85,36 +80,9 @@ class DebugFragment : Fragment() {
|
|||
): View {
|
||||
return ComposeView(requireContext()).apply {
|
||||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
||||
setBackgroundColor(ContextCompat.getColor(context, R.color.colorAdvancedBackground))
|
||||
setContent {
|
||||
val viewModel: DebugViewModel = hiltViewModel()
|
||||
|
||||
AppTheme {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text(stringResource(id = R.string.debug_panel)) },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = { parentFragmentManager.popBackStack() }) {
|
||||
Icon(
|
||||
Icons.AutoMirrored.Filled.ArrowBack,
|
||||
stringResource(id = R.string.navigate_back),
|
||||
)
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
Button(onClick = viewModel::deleteAllLogs) {
|
||||
Text(text = stringResource(R.string.clear))
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
) { innerPadding ->
|
||||
DebugScreen(
|
||||
viewModel = viewModel,
|
||||
contentPadding = innerPadding,
|
||||
)
|
||||
}
|
||||
DebugScreen { parentFragmentManager.popBackStack() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -185,7 +153,7 @@ private fun Int.asNodeId(): String {
|
|||
@Composable
|
||||
internal fun DebugScreen(
|
||||
viewModel: DebugViewModel = hiltViewModel(),
|
||||
contentPadding: PaddingValues,
|
||||
navigateUp: () -> Unit
|
||||
) {
|
||||
val listState = rememberLazyListState()
|
||||
val logs by viewModel.meshLog.collectAsStateWithLifecycle()
|
||||
|
|
@ -199,13 +167,22 @@ internal fun DebugScreen(
|
|||
}
|
||||
}
|
||||
|
||||
SelectionContainer {
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
state = listState,
|
||||
contentPadding = contentPadding,
|
||||
) {
|
||||
items(logs, key = { it.uuid }) { log -> DebugItem(annotateMeshLog(log)) }
|
||||
BaseScaffold(
|
||||
title = stringResource(id = R.string.debug_panel),
|
||||
navigateUp = navigateUp,
|
||||
actions = {
|
||||
Button(onClick = viewModel::deleteAllLogs) {
|
||||
Text(text = stringResource(R.string.clear))
|
||||
}
|
||||
}
|
||||
) {
|
||||
SelectionContainer {
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
state = listState,
|
||||
) {
|
||||
items(logs, key = { it.uuid }) { log -> DebugItem(annotateMeshLog(log)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,14 +22,7 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TopAppBar
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.automirrored.filled.Forward
|
||||
import androidx.compose.material.icons.automirrored.filled.List
|
||||
import androidx.compose.material.icons.automirrored.filled.Message
|
||||
|
|
@ -61,7 +54,6 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
|||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.viewModels
|
||||
|
|
@ -77,6 +69,7 @@ import com.geeksville.mesh.R
|
|||
import com.geeksville.mesh.android.Logging
|
||||
import com.geeksville.mesh.model.MetricsViewModel
|
||||
import com.geeksville.mesh.model.RadioConfigViewModel
|
||||
import com.geeksville.mesh.ui.components.BaseScaffold
|
||||
import com.geeksville.mesh.ui.components.DeviceMetricsScreen
|
||||
import com.geeksville.mesh.ui.components.EnvironmentMetricsScreen
|
||||
import com.geeksville.mesh.ui.components.NodeMapScreen
|
||||
|
|
@ -143,32 +136,26 @@ class NavGraphFragment : ScreenFragment("NavGraph"), Logging {
|
|||
|
||||
return ComposeView(requireContext()).apply {
|
||||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
||||
setBackgroundColor(ContextCompat.getColor(context, R.color.colorAdvancedBackground))
|
||||
setContent {
|
||||
val node by model.destNode.collectAsStateWithLifecycle()
|
||||
|
||||
AppTheme {
|
||||
val navController: NavHostController = rememberNavController()
|
||||
Scaffold(
|
||||
topBar = {
|
||||
MeshAppBar(
|
||||
currentScreen = node?.user?.longName
|
||||
?: stringResource(R.string.unknown_username),
|
||||
canNavigateBack = true,
|
||||
navigateUp = {
|
||||
if (navController.previousBackStackEntry != null) {
|
||||
navController.navigateUp()
|
||||
} else {
|
||||
parentFragmentManager.popBackStack()
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
) { innerPadding ->
|
||||
BaseScaffold(
|
||||
title = node?.user?.longName
|
||||
?: stringResource(R.string.unknown_username),
|
||||
canNavigateBack = true,
|
||||
navigateUp = {
|
||||
if (navController.previousBackStackEntry != null) {
|
||||
navController.navigateUp()
|
||||
} else {
|
||||
parentFragmentManager.popBackStack()
|
||||
}
|
||||
},
|
||||
) {
|
||||
NavGraph(
|
||||
navController = navController,
|
||||
startDestination = startDestination,
|
||||
modifier = Modifier.padding(innerPadding),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -294,29 +281,6 @@ sealed class ResponseState<out T> {
|
|||
fun isWaiting() = this !is Empty
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MeshAppBar(
|
||||
currentScreen: String,
|
||||
canNavigateBack: Boolean,
|
||||
navigateUp: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
TopAppBar(
|
||||
title = { Text(currentScreen) },
|
||||
modifier = modifier,
|
||||
navigationIcon = {
|
||||
if (canNavigateBack) {
|
||||
IconButton(onClick = navigateUp) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
||||
contentDescription = stringResource(id = R.string.navigate_back),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
fun NavGraph(
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@file:Suppress("TooManyFunctions", "LongMethod")
|
||||
@file:Suppress("TooManyFunctions")
|
||||
|
||||
package com.geeksville.mesh.ui
|
||||
|
||||
|
|
@ -108,7 +108,7 @@ import kotlin.math.ln
|
|||
fun NodeDetailScreen(
|
||||
modifier: Modifier = Modifier,
|
||||
viewModel: MetricsViewModel = hiltViewModel(),
|
||||
onNavigate: (Any) -> Unit,
|
||||
onNavigate: (Route) -> Unit,
|
||||
) {
|
||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||
|
||||
|
|
@ -135,7 +135,7 @@ private fun NodeDetailList(
|
|||
modifier: Modifier = Modifier,
|
||||
node: Node,
|
||||
metricsState: MetricsState,
|
||||
onNavigate: (Any) -> Unit = {},
|
||||
onNavigate: (Route) -> Unit = {},
|
||||
) {
|
||||
LazyColumn(
|
||||
modifier = modifier.fillMaxSize(),
|
||||
|
|
@ -320,7 +320,7 @@ private fun NodeDetailsContent(
|
|||
}
|
||||
|
||||
@Composable
|
||||
fun LogNavigationList(state: MetricsState, onNavigate: (Any) -> Unit) {
|
||||
fun LogNavigationList(state: MetricsState, onNavigate: (Route) -> Unit) {
|
||||
NavCard(
|
||||
title = stringResource(R.string.device_metrics_log),
|
||||
icon = Icons.Default.ChargingStation,
|
||||
|
|
|
|||
|
|
@ -49,22 +49,22 @@ import androidx.compose.material.IconButton
|
|||
import androidx.compose.material.ListItem
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.OutlinedTextField
|
||||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.material.Switch
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextButton
|
||||
import androidx.compose.material.TopAppBar
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.FastForward
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.focus.onFocusEvent
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
|
|
@ -76,13 +76,13 @@ import androidx.compose.ui.text.style.TextAlign
|
|||
import androidx.compose.ui.tooling.preview.PreviewLightDark
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.android.Logging
|
||||
import com.geeksville.mesh.database.entity.QuickChatAction
|
||||
import com.geeksville.mesh.model.UIViewModel
|
||||
import com.geeksville.mesh.ui.components.BaseScaffold
|
||||
import com.geeksville.mesh.ui.components.dragContainer
|
||||
import com.geeksville.mesh.ui.components.dragDropItemsIndexed
|
||||
import com.geeksville.mesh.ui.components.rememberDragDropState
|
||||
|
|
@ -98,28 +98,9 @@ class QuickChatSettingsFragment : ScreenFragment("Quick Chat Settings"), Logging
|
|||
): View {
|
||||
return ComposeView(requireContext()).apply {
|
||||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
||||
setBackgroundColor(ContextCompat.getColor(context, R.color.colorAdvancedBackground))
|
||||
setContent {
|
||||
AppTheme {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text(stringResource(id = R.string.quick_chat)) },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = { parentFragmentManager.popBackStack() }) {
|
||||
Icon(
|
||||
Icons.AutoMirrored.Filled.ArrowBack,
|
||||
stringResource(id = R.string.navigate_back),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
) { innerPadding ->
|
||||
QuickChatScreen(
|
||||
modifier = Modifier.padding(innerPadding)
|
||||
)
|
||||
}
|
||||
QuickChatScreen { parentFragmentManager.popBackStack() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -129,7 +110,19 @@ class QuickChatSettingsFragment : ScreenFragment("Quick Chat Settings"), Logging
|
|||
@Composable
|
||||
internal fun QuickChatScreen(
|
||||
viewModel: UIViewModel = hiltViewModel(),
|
||||
modifier: Modifier = Modifier,
|
||||
navigateUp: () -> Unit
|
||||
) {
|
||||
BaseScaffold(
|
||||
title = stringResource(id = R.string.quick_chat),
|
||||
navigateUp = navigateUp,
|
||||
) {
|
||||
QuickChatContent(viewModel)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun QuickChatContent(
|
||||
viewModel: UIViewModel = hiltViewModel(),
|
||||
) {
|
||||
val actions by viewModel.quickChatActions.collectAsStateWithLifecycle()
|
||||
var showActionDialog by remember { mutableStateOf<QuickChatAction?>(null) }
|
||||
|
|
@ -140,7 +133,7 @@ internal fun QuickChatScreen(
|
|||
viewModel.updateActionPositions(list)
|
||||
}
|
||||
|
||||
Box(modifier = modifier.fillMaxSize()) {
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
if (showActionDialog != null) {
|
||||
val action = showActionDialog ?: return
|
||||
EditQuickChatDialog(
|
||||
|
|
@ -212,10 +205,17 @@ private fun EditQuickChatDialog(
|
|||
onDismiss: () -> Unit,
|
||||
) {
|
||||
var actionInput by remember { mutableStateOf(action) }
|
||||
val newQuickChat = action.uuid == 0L
|
||||
val newQuickChat = remember { action.uuid == 0L }
|
||||
val isInstant = actionInput.mode == QuickChatAction.Mode.Instant
|
||||
val title = if (newQuickChat) R.string.quick_chat_new else R.string.quick_chat_edit
|
||||
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
LaunchedEffect(Unit) {
|
||||
if (newQuickChat) {
|
||||
focusRequester.requestFocus()
|
||||
}
|
||||
}
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
|
|
@ -246,9 +246,11 @@ private fun EditQuickChatDialog(
|
|||
OutlinedTextFieldWithCounter(
|
||||
label = stringResource(id = R.string.message),
|
||||
value = actionInput.message,
|
||||
maxSize = 235,
|
||||
maxSize = 200,
|
||||
getSize = { it.toByteArray().size + 1 },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.focusRequester(focusRequester),
|
||||
) {
|
||||
actionInput = actionInput.copy(message = it)
|
||||
if (newQuickChat) {
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ import androidx.lifecycle.compose.dropUnlessResumed
|
|||
import com.geeksville.mesh.R
|
||||
|
||||
@Composable
|
||||
fun BaseScaffold(
|
||||
internal fun BaseScaffold(
|
||||
title: String,
|
||||
modifier: Modifier = Modifier,
|
||||
canNavigateBack: Boolean = true,
|
||||
|
|
@ -82,7 +82,7 @@ fun BaseScaffold(
|
|||
}
|
||||
|
||||
@Composable
|
||||
fun BaseScaffold(
|
||||
internal fun BaseScaffold(
|
||||
modifier: Modifier = Modifier,
|
||||
topBar: @Composable () -> Unit = {},
|
||||
bottomBar: @Composable () -> Unit = {},
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ import androidx.compose.material.ButtonDefaults
|
|||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextButton
|
||||
import androidx.compose.material.TextField
|
||||
|
|
@ -80,7 +79,6 @@ import androidx.compose.ui.text.input.TextFieldValue
|
|||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.PreviewLightDark
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
|
|
@ -94,6 +92,7 @@ import com.geeksville.mesh.database.entity.QuickChatAction
|
|||
import com.geeksville.mesh.model.Node
|
||||
import com.geeksville.mesh.model.UIViewModel
|
||||
import com.geeksville.mesh.model.getChannel
|
||||
import com.geeksville.mesh.ui.components.BaseScaffold
|
||||
import com.geeksville.mesh.ui.components.NodeKeyStatusIcon
|
||||
import com.geeksville.mesh.ui.components.NodeMenuAction
|
||||
import com.geeksville.mesh.ui.message.components.MessageList
|
||||
|
|
@ -139,7 +138,6 @@ class MessagesFragment : Fragment(), Logging {
|
|||
|
||||
return ComposeView(requireContext()).apply {
|
||||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
||||
setBackgroundColor(ContextCompat.getColor(context, R.color.colorAdvancedBackground))
|
||||
setContent {
|
||||
AppTheme {
|
||||
MessageScreen(
|
||||
|
|
@ -213,7 +211,7 @@ internal fun MessageScreen(
|
|||
)
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
BaseScaffold(
|
||||
topBar = {
|
||||
if (inSelectionMode) {
|
||||
ActionModeTopBar(selectedIds.value) { action ->
|
||||
|
|
@ -269,13 +267,12 @@ internal fun MessageScreen(
|
|||
TextInput(isConnected, messageInput) { viewModel.sendMessage(it, contactKey) }
|
||||
}
|
||||
}
|
||||
) { innerPadding ->
|
||||
) {
|
||||
if (messages.isNotEmpty()) {
|
||||
MessageList(
|
||||
messages = messages,
|
||||
selectedIds = selectedIds,
|
||||
onUnreadChanged = { viewModel.clearUnreadCount(contactKey, it) },
|
||||
contentPadding = innerPadding,
|
||||
onSendReaction = { emoji, id -> viewModel.sendReaction(emoji, id, contactKey) },
|
||||
) { action ->
|
||||
when (action) {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
package com.geeksville.mesh.ui.message.components
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
|
|
@ -54,7 +53,6 @@ internal fun MessageList(
|
|||
messages: List<Message>,
|
||||
selectedIds: MutableState<Set<Long>>,
|
||||
onUnreadChanged: (Long) -> Unit,
|
||||
contentPadding: PaddingValues,
|
||||
onSendReaction: (String, Int) -> Unit,
|
||||
onNodeMenuAction: (NodeMenuAction) -> Unit = {}
|
||||
) {
|
||||
|
|
@ -89,7 +87,6 @@ internal fun MessageList(
|
|||
modifier = Modifier.fillMaxSize(),
|
||||
state = listState,
|
||||
reverseLayout = true,
|
||||
contentPadding = contentPadding
|
||||
) {
|
||||
items(messages, key = { it.uuid }) { msg ->
|
||||
val fromLocal = msg.node.user.id == DataPacket.ID_LOCAL
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue