Skip to content
Snippets Groups Projects

Finish view model for contact list

Files

package org.briarproject.briar.desktop.contact
package org.briarproject.briar.desktop.contact.add.remote
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@@ -15,35 +15,21 @@ import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import org.briarproject.bramble.api.FormatException
import org.briarproject.bramble.api.contact.ContactManager
import org.briarproject.bramble.api.db.ContactExistsException
import org.briarproject.bramble.api.db.PendingContactExistsException
import org.briarproject.bramble.api.identity.AuthorConstants
import org.briarproject.bramble.util.StringUtils
import org.briarproject.briar.desktop.ui.CTM
import java.security.GeneralSecurityException
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun AddContactDialog(isVisible: Boolean, setDialogVisibility: (Boolean) -> Unit) {
if (!isVisible) {
return
fun AddContactDialog(viewModel: AddContactViewModel, onClose: () -> Unit) {
LaunchedEffect("fetchHandshake") {
// todo: should instead be done automatically as soon as DB is loaded -> in view model
viewModel.fetchHandshakeLink()
}
var contactAlias by remember { mutableStateOf("") }
var contactLink by remember { mutableStateOf("") }
val contactManager = CTM.current
val ownLink = CTM.current.handshakeLink
AlertDialog(
onDismissRequest = { setDialogVisibility(false) },
onDismissRequest = onClose,
text = {
Column(modifier = Modifier.fillMaxWidth()) {
Row(Modifier.fillMaxWidth().padding(vertical = 16.dp)) {
@@ -58,14 +44,22 @@ fun AddContactDialog(isVisible: Boolean, setDialogVisibility: (Boolean) -> Unit)
"Contact's Link",
Modifier.width(128.dp).align(Alignment.CenterVertically),
)
TextField(contactLink, onValueChange = { contactLink = it }, modifier = Modifier.fillMaxWidth())
TextField(
viewModel.remoteHandshakeLink.value,
viewModel::setRemoteHandshakeLink,
modifier = Modifier.fillMaxWidth()
)
}
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
Text(
"Contact's Name",
Modifier.width(128.dp).align(Alignment.CenterVertically),
)
TextField(contactAlias, onValueChange = { contactAlias = it }, modifier = Modifier.fillMaxWidth())
TextField(
viewModel.alias.value,
viewModel::setAddContactAlias,
modifier = Modifier.fillMaxWidth()
)
}
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
Text(
@@ -73,7 +67,7 @@ fun AddContactDialog(isVisible: Boolean, setDialogVisibility: (Boolean) -> Unit)
modifier = Modifier.width(128.dp).align(Alignment.CenterVertically),
)
TextField(
ownLink,
viewModel.handshakeLink.value,
onValueChange = {},
modifier = Modifier.fillMaxWidth()
)
@@ -81,23 +75,13 @@ fun AddContactDialog(isVisible: Boolean, setDialogVisibility: (Boolean) -> Unit)
}
},
confirmButton = {
Button(
onClick = {
if (ownLink.equals(contactLink)) {
println("Please enter contact's link, not your own")
setDialogVisibility(false)
return@Button
}
addPendingContact(contactManager, contactAlias, contactLink)
setDialogVisibility(false)
},
) {
Button(onClick = { viewModel.onSubmitAddContactDialog(); onClose() }) {
Text("Add")
}
},
dismissButton = {
TextButton(
onClick = { setDialogVisibility(false) }
onClick = onClose
) {
Text("Cancel", color = MaterialTheme.colors.onSurface)
}
@@ -105,38 +89,3 @@ fun AddContactDialog(isVisible: Boolean, setDialogVisibility: (Boolean) -> Unit)
modifier = Modifier.size(600.dp, 300.dp),
)
}
private fun addPendingContact(contactManager: ContactManager, alias: String, link: String) {
if (aliasIsInvalid(alias)) {
println("Alias is invalid")
return
}
try {
contactManager.addPendingContact(link, alias)
} catch (e: FormatException) {
println("Link is invalid")
println(e.stackTrace)
} catch (e: GeneralSecurityException) {
println("Public key is invalid")
println(e.stackTrace)
}
/*
TODO: Warn user that the following two errors might be an attack
Use `e.pendingContact.id.bytes` and `e.pendingContact.alias` to implement the following logic:
https://code.briarproject.org/briar/briar-gtk/-/merge_requests/97
*/
catch (e: ContactExistsException) {
println("Contact already exists")
println(e.stackTrace)
} catch (e: PendingContactExistsException) {
println("Pending Contact already exists")
println(e.stackTrace)
}
}
private fun aliasIsInvalid(alias: String): Boolean {
val aliasUtf8 = StringUtils.toUtf8(alias)
return aliasUtf8.isEmpty() || aliasUtf8.size > AuthorConstants.MAX_AUTHOR_NAME_LENGTH
}
Loading