Simplified MainScreen bottom bar implementation
This commit is contained in:
@ -223,7 +223,7 @@ private fun MainScreen(
|
||||
val ua = UserAgent.ofAor(viewModel.selectedAor.value)
|
||||
if (ua != null) {
|
||||
showCall(ctx, viewModel, ua)
|
||||
updateIcons(viewModel, ua.account)
|
||||
viewModel.triggerAccountUpdate()
|
||||
}
|
||||
}
|
||||
Lifecycle.Event.ON_PAUSE -> {
|
||||
@ -447,8 +447,7 @@ private fun MainScreen(
|
||||
LaunchedEffect(currentRoute, viewModel.selectedAor.collectAsState()) {
|
||||
if (currentRoute == "main") {
|
||||
Log.d(TAG, "Updating icons for AOR: ${viewModel.selectedAor.value}")
|
||||
val account = Account.ofAor(viewModel.selectedAor.value)
|
||||
updateIcons(viewModel, account)
|
||||
viewModel.triggerAccountUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
@ -673,41 +672,56 @@ private fun TopAppBar(
|
||||
@Composable
|
||||
private fun BottomBar(ctx: Context, viewModel: ViewModel, navController: NavController) {
|
||||
|
||||
val vmIcon by viewModel.vmIcon.collectAsState()
|
||||
val showVmIcon by viewModel.showVmIcon.collectAsState()
|
||||
val messagesIcon by viewModel.messagesIcon.collectAsState()
|
||||
val callsIcon by viewModel.callsIcon.collectAsState()
|
||||
// ... (the top part of your function is the same) ...
|
||||
val dialpadIcon by viewModel.dialpadIcon.collectAsState()
|
||||
val aor by viewModel.selectedAor.collectAsState()
|
||||
val accountUpdate by viewModel.accountUpdate.collectAsState()
|
||||
|
||||
val showVmIcon = remember(aor, accountUpdate) {
|
||||
if (aor.isNotEmpty()) Account.ofAor(aor)?.vmUri?.isNotEmpty() ?: false else false
|
||||
}
|
||||
val hasNewVoicemail = remember(aor, accountUpdate) {
|
||||
if (aor.isNotEmpty()) (Account.ofAor(aor)?.vmNew ?: 0) > 0 else false
|
||||
}
|
||||
val hasUnreadMessages = remember(aor, accountUpdate) {
|
||||
if (aor.isNotEmpty()) Account.ofAor(aor)?.unreadMessages ?: false else false
|
||||
}
|
||||
val hasMissedCalls = remember(aor, accountUpdate) {
|
||||
if (aor.isNotEmpty()) Account.ofAor(aor)?.missedCalls ?: false else false
|
||||
}
|
||||
|
||||
val buttonSize = 48.dp
|
||||
|
||||
Row( modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.navigationBarsPadding()
|
||||
.padding(bottom = 16.dp),
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.navigationBarsPadding()
|
||||
.padding(bottom = 16.dp),
|
||||
horizontalArrangement = Arrangement.SpaceEvenly,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
|
||||
if (showVmIcon)
|
||||
IconButton(
|
||||
// Disable the button if no account is selected
|
||||
enabled = aor.isNotEmpty(),
|
||||
onClick = {
|
||||
if (viewModel.selectedAor.value != "") {
|
||||
val ua = UserAgent.ofAor(viewModel.selectedAor.value)!!
|
||||
val acc = ua.account
|
||||
if (acc.vmUri != "") {
|
||||
dialogTitle.value = ctx.getString(R.string.voicemail_messages)
|
||||
dialogMessage.value = acc.vmMessages(ctx)
|
||||
positiveText.value = ctx.getString(R.string.listen)
|
||||
onPositiveClicked.value = {
|
||||
val intent = Intent(ctx, MainActivity::class.java)
|
||||
intent.putExtra("uap", ua.uap)
|
||||
intent.putExtra("peer", acc.vmUri)
|
||||
handleIntent(ctx, viewModel, intent, "call")
|
||||
}
|
||||
negativeText.value = ctx.getString(R.string.cancel)
|
||||
onNegativeClicked.value = {}
|
||||
showDialog.value = true
|
||||
// No need for an 'if' check here anymore
|
||||
val ua = UserAgent.ofAor(aor)!!
|
||||
val acc = ua.account
|
||||
if (acc.vmUri.isNotEmpty()) {
|
||||
dialogTitle.value = ctx.getString(R.string.voicemail_messages)
|
||||
dialogMessage.value = acc.vmMessages(ctx)
|
||||
positiveText.value = ctx.getString(R.string.listen)
|
||||
onPositiveClicked.value = {
|
||||
val intent = Intent(ctx, MainActivity::class.java)
|
||||
intent.putExtra("uap", ua.uap)
|
||||
intent.putExtra("peer", acc.vmUri)
|
||||
handleIntent(ctx, viewModel, intent, "call")
|
||||
}
|
||||
negativeText.value = ctx.getString(R.string.cancel)
|
||||
onNegativeClicked.value = {}
|
||||
showDialog.value = true
|
||||
}
|
||||
},
|
||||
modifier = Modifier
|
||||
@ -715,13 +729,10 @@ private fun BottomBar(ctx: Context, viewModel: ViewModel, navController: NavCont
|
||||
.size(buttonSize)
|
||||
) {
|
||||
Icon(
|
||||
imageVector = ImageVector.vectorResource(vmIcon),
|
||||
imageVector = ImageVector.vectorResource(R.drawable.voicemail),
|
||||
contentDescription = null,
|
||||
Modifier.size(buttonSize),
|
||||
tint = if (vmIcon == R.drawable.voicemail)
|
||||
MaterialTheme.colorScheme.secondary
|
||||
else
|
||||
MaterialTheme.colorScheme.error
|
||||
tint = if (hasNewVoicemail) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.secondary
|
||||
)
|
||||
}
|
||||
|
||||
@ -740,52 +751,49 @@ private fun BottomBar(ctx: Context, viewModel: ViewModel, navController: NavCont
|
||||
}
|
||||
|
||||
IconButton(
|
||||
// Disable the button if no account is selected
|
||||
enabled = aor.isNotEmpty(),
|
||||
onClick = {
|
||||
if (viewModel.selectedAor.value != "")
|
||||
navController.navigate("chats/${viewModel.selectedAor.value}")
|
||||
// No need for an 'if' check here anymore
|
||||
navController.navigate("chats/$aor")
|
||||
},
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.size(buttonSize)
|
||||
) {
|
||||
Icon(
|
||||
imageVector = ImageVector.vectorResource(messagesIcon),
|
||||
imageVector = ImageVector.vectorResource(R.drawable.messages),
|
||||
contentDescription = null,
|
||||
Modifier.size(buttonSize),
|
||||
tint = if (messagesIcon == R.drawable.messages)
|
||||
MaterialTheme.colorScheme.secondary
|
||||
else
|
||||
MaterialTheme.colorScheme.error
|
||||
tint = if (hasUnreadMessages) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.secondary
|
||||
)
|
||||
}
|
||||
|
||||
IconButton(
|
||||
// Disable the button if no account is selected
|
||||
enabled = aor.isNotEmpty(),
|
||||
onClick = {
|
||||
if (viewModel.selectedAor.value != "")
|
||||
navController.navigate("calls/${viewModel.selectedAor.value}")
|
||||
// No need for an 'if' check here anymore
|
||||
navController.navigate("calls/$aor")
|
||||
},
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.size(buttonSize)
|
||||
) {
|
||||
Icon(
|
||||
imageVector = ImageVector.vectorResource(callsIcon),
|
||||
imageVector = ImageVector.vectorResource(R.drawable.calls),
|
||||
contentDescription = null,
|
||||
Modifier.size(buttonSize),
|
||||
tint = if (callsIcon == R.drawable.calls)
|
||||
MaterialTheme.colorScheme.secondary
|
||||
else
|
||||
MaterialTheme.colorScheme.error
|
||||
tint = if (hasMissedCalls) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.secondary
|
||||
)
|
||||
}
|
||||
|
||||
IconButton(
|
||||
onClick = { viewModel.updateDialpadIcon(
|
||||
if (dialpadIcon == R.drawable.dialpad_off)
|
||||
R.drawable.dialpad_on
|
||||
else
|
||||
R.drawable.dialpad_off
|
||||
) },
|
||||
onClick = {
|
||||
viewModel.updateDialpadIcon(
|
||||
if (dialpadIcon == R.drawable.dialpad_off) R.drawable.dialpad_on else R.drawable.dialpad_off
|
||||
)
|
||||
},
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.size(buttonSize),
|
||||
@ -795,14 +803,10 @@ private fun BottomBar(ctx: Context, viewModel: ViewModel, navController: NavCont
|
||||
imageVector = ImageVector.vectorResource(dialpadIcon),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(buttonSize),
|
||||
tint = if (dialpadIcon == R.drawable.dialpad_off)
|
||||
MaterialTheme.colorScheme.secondary
|
||||
else
|
||||
MaterialTheme.colorScheme.error
|
||||
tint = if (dialpadIcon == R.drawable.dialpad_off) MaterialTheme.colorScheme.secondary else MaterialTheme.colorScheme.error
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private val callUri = mutableStateOf("")
|
||||
@ -973,8 +977,7 @@ private fun AccountSpinner(ctx: Context, viewModel: ViewModel, navController: Na
|
||||
}
|
||||
|
||||
showCall(ctx, viewModel, UserAgent.ofAor(selected))
|
||||
|
||||
updateIcons(viewModel, Account.ofAor(selected))
|
||||
viewModel.triggerAccountUpdate()
|
||||
|
||||
if (selected == "") {
|
||||
OutlinedButton(
|
||||
@ -1103,7 +1106,7 @@ private fun AccountSpinner(ctx: Context, viewModel: ViewModel, navController: Na
|
||||
expanded = false
|
||||
viewModel.updateSelectedAor(acc.aor)
|
||||
showCall(ctx, viewModel, ua)
|
||||
updateIcons(viewModel, acc)
|
||||
viewModel.triggerAccountUpdate()
|
||||
},
|
||||
text = { Text(
|
||||
text = acc.text(),
|
||||
@ -1831,7 +1834,7 @@ private fun OnHoldNotice() {
|
||||
private fun spinToAor(viewModel: ViewModel, aor: String) {
|
||||
if (aor != viewModel.selectedAor.value)
|
||||
viewModel.updateSelectedAor(aor)
|
||||
updateIcons(viewModel, Account.ofAor(aor))
|
||||
viewModel.triggerAccountUpdate()
|
||||
}
|
||||
|
||||
private fun callClick(ctx: Context, viewModel: ViewModel) {
|
||||
@ -2193,7 +2196,7 @@ fun handleServiceEvent(ctx: Context, viewModel: ViewModel, event: String, params
|
||||
when (ev[0]) {
|
||||
"call rejected" -> {
|
||||
if (aor == viewModel.selectedAor.value)
|
||||
viewModel.updateCallsIcon(R.drawable.calls_missed)
|
||||
viewModel.triggerAccountUpdate()
|
||||
}
|
||||
"call incoming", "call outgoing" -> {
|
||||
val callp = params[1] as Long
|
||||
@ -2336,7 +2339,7 @@ fun handleServiceEvent(ctx: Context, viewModel: ViewModel, event: String, params
|
||||
ua.account.resumeUri = ""
|
||||
showCall(ctx, viewModel, ua)
|
||||
if (acc.missedCalls)
|
||||
viewModel.updateCallsIcon(R.drawable.calls_missed)
|
||||
viewModel.triggerAccountUpdate()
|
||||
}
|
||||
//if (kgm.isDeviceLocked)
|
||||
// this.setShowWhenLocked(false)
|
||||
@ -2356,13 +2359,8 @@ fun handleServiceEvent(ctx: Context, viewModel: ViewModel, event: String, params
|
||||
break
|
||||
}
|
||||
}
|
||||
if (aor == viewModel.selectedAor.value) {
|
||||
viewModel.updateVmIcon(if (acc.vmNew > 0)
|
||||
R.drawable.voicemail_new
|
||||
else
|
||||
R.drawable.voicemail
|
||||
)
|
||||
}
|
||||
if (aor == viewModel.selectedAor.value)
|
||||
viewModel.triggerAccountUpdate()
|
||||
}
|
||||
else -> Log.e(TAG, "Unknown event '${ev[0]}'")
|
||||
}
|
||||
@ -2536,36 +2534,6 @@ private fun acceptTransfer(ctx: Context, viewModel: ViewModel, ua: UserAgent, ca
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateIcons(viewModel: ViewModel, acc: Account?) {
|
||||
if (acc == null) {
|
||||
viewModel.updateShowVmIcon(false)
|
||||
viewModel.updateMessagesIcon(R.drawable.messages)
|
||||
viewModel.updateCallsIcon(R.drawable.calls)
|
||||
}
|
||||
else {
|
||||
|
||||
if (acc.vmUri != "") {
|
||||
viewModel.updateShowVmIcon(true)
|
||||
viewModel.updateVmIcon(if (acc.vmNew > 0)
|
||||
R.drawable.voicemail_new
|
||||
else
|
||||
R.drawable.voicemail
|
||||
)
|
||||
} else
|
||||
viewModel.updateShowVmIcon(false)
|
||||
|
||||
viewModel.updateMessagesIcon(if (acc.unreadMessages)
|
||||
R.drawable.messages_unread
|
||||
else
|
||||
R.drawable.messages)
|
||||
|
||||
viewModel.updateCallsIcon(if (acc.missedCalls)
|
||||
R.drawable.calls_missed
|
||||
else
|
||||
R.drawable.calls)
|
||||
}
|
||||
}
|
||||
|
||||
private fun backup(ctx: Context, password: String) {
|
||||
val files = arrayListOf("accounts", "config", "contacts", "call_history",
|
||||
"messages", "uuid", "gzrtp.zid", "cert.pem", "ca_cert", "ca_certs.crt")
|
||||
|
||||
@ -30,6 +30,13 @@ class ViewModel(application: Application) : AndroidViewModel(application) {
|
||||
_selectedAor.value = newValue
|
||||
}
|
||||
|
||||
private val _accountUpdate = MutableStateFlow(0)
|
||||
val accountUpdate: StateFlow<Int> = _accountUpdate
|
||||
|
||||
fun triggerAccountUpdate() {
|
||||
_accountUpdate.value++
|
||||
}
|
||||
|
||||
private val _aorPeerMessage = MutableStateFlow(mutableMapOf<AorPeer, String>())
|
||||
|
||||
fun updateAorPeerMessage(aor: String, peerUri: String, message: String) {
|
||||
@ -73,13 +80,6 @@ class ViewModel(application: Application) : AndroidViewModel(application) {
|
||||
_micIcon.value = iconResId
|
||||
}
|
||||
|
||||
private val _vmIcon = MutableStateFlow(R.drawable.voicemail)
|
||||
val vmIcon: StateFlow<Int> = _vmIcon.asStateFlow()
|
||||
|
||||
fun updateVmIcon(newIcon: Int) {
|
||||
_vmIcon.value = newIcon
|
||||
}
|
||||
|
||||
private val _showVmIcon = MutableStateFlow(false)
|
||||
val showVmIcon: StateFlow<Boolean> = _showVmIcon.asStateFlow()
|
||||
|
||||
@ -87,20 +87,6 @@ class ViewModel(application: Application) : AndroidViewModel(application) {
|
||||
_showVmIcon.value = show
|
||||
}
|
||||
|
||||
private val _messagesIcon = MutableStateFlow(R.drawable.messages)
|
||||
val messagesIcon: StateFlow<Int> = _messagesIcon.asStateFlow()
|
||||
|
||||
fun updateMessagesIcon(newIcon: Int) {
|
||||
_messagesIcon.value = newIcon
|
||||
}
|
||||
|
||||
private val _callsIcon = MutableStateFlow(R.drawable.calls)
|
||||
val callsIcon: StateFlow<Int> = _callsIcon.asStateFlow()
|
||||
|
||||
fun updateCallsIcon(newIcon: Int) {
|
||||
_callsIcon.value = newIcon
|
||||
}
|
||||
|
||||
private val _dialpadIcon = MutableStateFlow(R.drawable.dialpad_off)
|
||||
val dialpadIcon: StateFlow<Int> = _dialpadIcon.asStateFlow()
|
||||
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
<vector android:height="48dp"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z"/>
|
||||
</vector>
|
||||
@ -1,5 +0,0 @@
|
||||
<vector android:height="44dp"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="44dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM6,9h12v2L6,11L6,9zM14,14L6,14v-2h8v2zM18,8L6,8L6,6h12v2z"/>
|
||||
</vector>
|
||||
@ -1,5 +0,0 @@
|
||||
<vector android:height="48dp"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M18.5,6C15.46,6 13,8.46 13,11.5c0,1.33 0.47,2.55 1.26,3.5L9.74,15c0.79,-0.95 1.26,-2.17 1.26,-3.5C11,8.46 8.54,6 5.5,6S0,8.46 0,11.5 2.46,17 5.5,17h13c3.04,0 5.5,-2.46 5.5,-5.5S21.54,6 18.5,6zM5.5,15C3.57,15 2,13.43 2,11.5S3.57,8 5.5,8 9,9.57 9,11.5 7.43,15 5.5,15zM18.5,15c-1.93,0 -3.5,-1.57 -3.5,-3.5S16.57,8 18.5,8 22,9.57 22,11.5 20.43,15 18.5,15z"/>
|
||||
</vector>
|
||||
Reference in New Issue
Block a user