mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
Generate a POSIX timezone string from a ZoneID (#3514)
This commit is contained in:
parent
58eeef38a9
commit
e4ba6d6136
11 changed files with 271 additions and 17 deletions
|
|
@ -17,27 +17,43 @@
|
|||
|
||||
package org.meshtastic.feature.settings.radio.component
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.Clear
|
||||
import androidx.compose.material.icons.rounded.PhoneAndroid
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.ButtonDefaults.MediumContainerHeight
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.Checkbox
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.produceState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.RectangleShape
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.res.stringResource
|
||||
|
|
@ -47,19 +63,23 @@ import androidx.compose.ui.text.TextLinkStyles
|
|||
import androidx.compose.ui.text.fromHtml
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import org.meshtastic.core.strings.R
|
||||
import org.meshtastic.core.ui.component.DropDownPreference
|
||||
import org.meshtastic.core.ui.component.EditTextPreference
|
||||
import org.meshtastic.core.ui.component.InsetDivider
|
||||
import org.meshtastic.core.ui.component.SwitchPreference
|
||||
import org.meshtastic.core.ui.component.TitledCard
|
||||
import org.meshtastic.core.ui.timezone.toPosixString
|
||||
import org.meshtastic.feature.settings.radio.RadioConfigViewModel
|
||||
import org.meshtastic.feature.settings.util.IntervalConfiguration
|
||||
import org.meshtastic.feature.settings.util.toDisplayString
|
||||
import org.meshtastic.proto.ConfigProtos.Config.DeviceConfig
|
||||
import org.meshtastic.proto.config
|
||||
import org.meshtastic.proto.copy
|
||||
import java.time.ZoneId
|
||||
|
||||
private val DeviceConfig.Role.description: Int
|
||||
get() =
|
||||
|
|
@ -91,6 +111,7 @@ private val DeviceConfig.RebroadcastMode.description: Int
|
|||
else -> R.string.unrecognized
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack: () -> Unit) {
|
||||
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
|
||||
|
|
@ -131,6 +152,7 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
|
|||
onItemSelected = { selectedRole = it },
|
||||
summary = stringResource(id = formState.value.role.description),
|
||||
)
|
||||
|
||||
HorizontalDivider()
|
||||
|
||||
DropDownPreference(
|
||||
|
|
@ -140,6 +162,7 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
|
|||
onItemSelected = { formState.value = formState.value.copy { rebroadcastMode = it } },
|
||||
summary = stringResource(id = formState.value.rebroadcastMode.description),
|
||||
)
|
||||
|
||||
HorizontalDivider()
|
||||
|
||||
val nodeInfoBroadcastIntervals = remember { IntervalConfiguration.NODE_INFO_BROADCAST.allowedIntervals }
|
||||
|
|
@ -152,6 +175,7 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
item {
|
||||
TitledCard(title = stringResource(R.string.hardware)) {
|
||||
SwitchPreference(
|
||||
|
|
@ -162,7 +186,8 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
|
|||
onCheckedChange = { formState.value = formState.value.copy { doubleTapAsButtonPress = it } },
|
||||
containerColor = CardDefaults.cardColors().containerColor,
|
||||
)
|
||||
HorizontalDivider()
|
||||
|
||||
InsetDivider()
|
||||
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.triple_click_adhoc_ping),
|
||||
|
|
@ -172,7 +197,9 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
|
|||
onCheckedChange = { formState.value = formState.value.copy { disableTripleClick = !it } },
|
||||
containerColor = CardDefaults.cardColors().containerColor,
|
||||
)
|
||||
HorizontalDivider()
|
||||
|
||||
InsetDivider()
|
||||
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.led_heartbeat),
|
||||
summary = stringResource(id = R.string.config_device_ledHeartbeatEnabled_summary),
|
||||
|
|
@ -181,13 +208,27 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
|
|||
onCheckedChange = { formState.value = formState.value.copy { ledHeartbeatDisabled = !it } },
|
||||
containerColor = CardDefaults.cardColors().containerColor,
|
||||
)
|
||||
HorizontalDivider()
|
||||
}
|
||||
}
|
||||
item {
|
||||
TitledCard(title = stringResource(R.string.debug)) {
|
||||
TitledCard(title = stringResource(R.string.time_zone)) {
|
||||
val context = LocalContext.current
|
||||
val appTzPosixString by
|
||||
produceState(initialValue = ZoneId.systemDefault().toPosixString()) {
|
||||
val receiver =
|
||||
object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if (intent.action == Intent.ACTION_TIMEZONE_CHANGED) {
|
||||
value = ZoneId.systemDefault().toPosixString()
|
||||
}
|
||||
}
|
||||
}
|
||||
context.registerReceiver(receiver, IntentFilter(Intent.ACTION_TIMEZONE_CHANGED))
|
||||
awaitDispose { context.unregisterReceiver(receiver) }
|
||||
}
|
||||
|
||||
EditTextPreference(
|
||||
title = stringResource(R.string.time_zone),
|
||||
title = "",
|
||||
value = formState.value.tzdef,
|
||||
summary = stringResource(id = R.string.config_device_tzdef_summary),
|
||||
maxSize = 64, // tzdef max_size:65
|
||||
|
|
@ -197,7 +238,27 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
|
|||
KeyboardOptions.Default.copy(keyboardType = KeyboardType.Text, imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
|
||||
onValueChanged = { formState.value = formState.value.copy { tzdef = it } },
|
||||
trailingIcon = {
|
||||
IconButton(onClick = { formState.value = formState.value.copy { tzdef = "" } }) {
|
||||
Icon(imageVector = Icons.Rounded.Clear, contentDescription = null)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
HorizontalDivider()
|
||||
|
||||
TextButton(
|
||||
modifier = Modifier.height(MediumContainerHeight).fillMaxWidth(),
|
||||
enabled = state.connected,
|
||||
shape = RectangleShape,
|
||||
onClick = { formState.value = formState.value.copy { tzdef = appTzPosixString } },
|
||||
) {
|
||||
Icon(imageVector = Icons.Rounded.PhoneAndroid, contentDescription = null)
|
||||
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
|
||||
Text(text = stringResource(R.string.config_device_use_phone_tz))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import androidx.compose.animation.fadeOut
|
|||
import androidx.compose.animation.shrinkOut
|
||||
import androidx.compose.animation.slideInVertically
|
||||
import androidx.compose.animation.slideOutVertically
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
|
|
@ -78,7 +79,11 @@ fun <T : MessageLite> RadioConfigScreenList(
|
|||
val showFooterButtons = configState.isDirty
|
||||
|
||||
Box(modifier = Modifier.padding(innerPadding)) {
|
||||
LazyColumn(modifier = Modifier.fillMaxSize(), contentPadding = PaddingValues(16.dp)) {
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentPadding = PaddingValues(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
) {
|
||||
content()
|
||||
|
||||
item {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue