Android compose navigation (#316)

* initial rough ideas

* refactor and put in high level navigation

* refactor

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
This commit is contained in:
IanRDavies
2022-02-16 18:00:59 +00:00
committed by GitHub
parent 12b4325435
commit 7c8ad4aee4
11 changed files with 306 additions and 20 deletions

117
apps/android/.idea/codeStyles/Project.xml generated Normal file
View File

@@ -0,0 +1,117 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<codeStyleSettings language="XML">
<option name="FORCE_REARRANGE_MODE" value="1" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>

View File

@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

View File

@@ -12,6 +12,6 @@
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2022-02-16T16:12:41.610721Z" />
<timeTargetWasSelectedWithDropDown value="2022-02-16T17:42:43.145045Z" />
</component>
</project>

View File

@@ -7,6 +7,8 @@
<entry key="../../../../../../../layout/compose-model-1644941851914.xml" value="0.28378378378378377" />
<entry key="../../../../../../../layout/compose-model-1644956742665.xml" value="1.0" />
<entry key="../../../../../../../layout/compose-model-1644963789622.xml" value="0.8420454545454545" />
<entry key="../../../../../../../layout/compose-model-1645006324692.xml" value="0.36363636363636365" />
<entry key="../../../../../../../layout/compose-model-1645006342272.xml" value="0.36363636363636365" />
</map>
</option>
</component>

View File

@@ -73,4 +73,5 @@ dependencies {
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
implementation "androidx.navigation:navigation-compose:2.4.1"
}

View File

@@ -8,11 +8,9 @@ import androidx.activity.viewModels
import androidx.compose.runtime.Composable
import chat.simplex.app.ui.theme.SimpleXTheme
import androidx.lifecycle.AndroidViewModel
import chat.simplex.app.model.*
import chat.simplex.app.views.TerminalView
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import kotlinx.serialization.modules.*
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
class MainActivity: ComponentActivity() {
@@ -21,7 +19,7 @@ class MainActivity: ComponentActivity() {
super.onCreate(savedInstanceState)
setContent {
SimpleXTheme {
MainPage(viewModel)
Navigation(viewModel = viewModel)
}
}
}
@@ -32,6 +30,21 @@ class SimplexViewModel(application: Application) : AndroidViewModel(application)
}
@Composable
fun MainPage(vm: SimplexViewModel) {
TerminalView(vm.chatModel)
fun Navigation(viewModel: SimplexViewModel) {
val navController = rememberNavController()
NavHost(navController=navController, startDestination=Pages.Home.route){
composable(route=Pages.Home.route){
MainPage(vm = viewModel)
}
// composable(route=Pages.Welcome.route){
// WelcomeView(vm.)
// }
}
}
sealed class Pages(val route: String) {
object Home : Pages("home")
object Terminal : Pages("terminal")
object Welcome : Pages("welcome")
}

View File

@@ -0,0 +1,10 @@
package chat.simplex.app
import androidx.compose.runtime.Composable
import chat.simplex.app.views.TerminalPage
@Composable
fun MainPage(vm: SimplexViewModel) {
TerminalPage(vm.chatModel)
}

View File

@@ -3,20 +3,41 @@ package chat.simplex.app.views
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material.Text
import androidx.compose.material.Button
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.tooling.preview.Preview
import chat.simplex.app.model.CC
import chat.simplex.app.model.ChatModel
import chat.simplex.app.model.TerminalItem
import androidx.navigation.*
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import chat.simplex.app.model.*
import chat.simplex.app.ui.theme.SimpleXTheme
import chat.simplex.app.views.chat.SendMsgView
@Composable
fun TerminalView(chatModel: ChatModel) {
fun TerminalPage(chatModel: ChatModel) {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "terminalView"){
composable("terminalView") { TerminalView(chatModel, navController) }
composable(
"details" + "/{_details}",
arguments=listOf(
navArgument("_details"){
type = NavType.StringType
}
)
) { entry -> DetailView( entry.arguments?.getString("_details"), navController)}
}
}
@Composable
fun TerminalView(chatModel: ChatModel, navController: NavController) {
Column {
TerminalLog(chatModel.terminalItems)
TerminalLog(chatModel.terminalItems, navController)
SendMsgView(sendMessage = { cmd ->
chatModel.controller.sendCmd(CC.Console(cmd))
})
@@ -24,18 +45,26 @@ fun TerminalView(chatModel: ChatModel) {
}
@Composable
fun TerminalLog(terminalItems: List<TerminalItem>) {
fun TerminalLog(terminalItems: List<TerminalItem>, navController: NavController) {
LazyColumn {
items(terminalItems) { item ->
Text(item.label)
ClickableText(
AnnotatedString(item.label),
onClick={navController.navigate("details/${item.details}")}
)
}
}
}
@Preview
@Composable
fun PreviewSendMsgView() {
SimpleXTheme {
TerminalView(chatModel = ChatModel.sampleData)
fun DetailView(details: String?, navController: NavController){
Column {
Text("$details")
Button(
onClick={navController.popBackStack()}
)
{Text("Back")}
}
}

View File

@@ -0,0 +1,48 @@
package chat.simplex.app.views
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.Image
import androidx.compose.ui.res.painterResource
import androidx.compose.runtime.*
import androidx.compose.runtime.Composable
import chat.simplex.app.R
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.material.Button
import androidx.compose.ui.unit.dp
import androidx.compose.ui.Modifier
import androidx.navigation.NavController
@Composable
fun WelcomeView(createUser: (data: String) -> String, navController: NavController) {
Column {
Image(
painter=painterResource(R.drawable.logo), contentDescription = "Simplex Logo",
)
Text("You control your chat!")
Text("The messaging and application platform protecting your privacy and security.")
Spacer(Modifier.height(8.dp))
Text("We don't store any of your contacts or messages (once delivered) on the servers.")
Spacer(Modifier.height(24.dp))
CreateProfilePanel(createUser, navController)
}
}
@Composable
fun CreateProfilePanel(createUser: (data: String) -> String, navController: NavController) {
var displayName by remember { mutableStateOf("") }
var fullName by remember { mutableStateOf("") }
Column {
Text("Create profile")
Text("Your profile is stored on your device and shared only with your contacts.")
Text("Display Name")
TextField(value = displayName, onValueChange = { displayName = it }, modifier = Modifier.height(30.dp))
Text("Full Name (Optional)")
TextField(value = fullName, onValueChange = { fullName = it }, modifier = Modifier.height(30.dp))
Button(onClick={
createUser("{\"displayName\": $displayName, \"fullName\": $fullName}")
navController.navigate("home") { popUpTo("home") { inclusive = true }}
}) { Text("Create")}
}
}

View File

@@ -0,0 +1,61 @@
package chat.simplex.app.views.usersettings
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import chat.simplex.app.model.Profile
//@Preview(showBackground = true)
@Composable
fun SettingsView(profile: Profile) {
Column() {
Text("Your Settings")
Spacer(Modifier.height(4.dp))
Text("YOU", style= MaterialTheme.typography.h4)
Button(
onClick = { println(profile.displayName) }
) {
Text(profile.displayName)
}
Button(
onClick = { println(profile.hashCode()) }
) {
Text("Your SimpleX contact address", style= MaterialTheme.typography.body1)
}
Spacer(Modifier.height(10.dp))
Text("HELP", style= MaterialTheme.typography.h4)
Button(
onClick = { println("navigate to help") }
) {
Text("How to use SimpleX Chat")
}
Button(
onClick = { println("start help chat") }
) {
Text("Get help & advice via chat")
}
Button(
onClick = { println("navigate to email") }
) {
Text("Ask questions via email")
}
Spacer(Modifier.height(10.dp))
Text("DEVELOP", style= MaterialTheme.typography.h4)
Button(
onClick = { println("navigate to console") }
) {
Text("Chat console")
}
Button(
onClick = { println("navigate to github") }
) {
Text("Install SimpleX for terminal")
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB