Added dropdown menu, added text entry menu (instead of STT), made FAB bigger

This commit is contained in:
Mathieu 2022-01-03 15:05:08 +01:00
parent a080089811
commit f318467465
5 changed files with 190 additions and 19 deletions

View File

@ -13,7 +13,13 @@
<entry key="../../../../../layout/compose-model-1641155782430.xml" value="0.7886363636363637" /> <entry key="../../../../../layout/compose-model-1641155782430.xml" value="0.7886363636363637" />
<entry key="../../../../../layout/compose-model-1641156150634.xml" value="0.33" /> <entry key="../../../../../layout/compose-model-1641156150634.xml" value="0.33" />
<entry key="../../../../../layout/compose-model-1641203039863.xml" value="0.38981481481481484" /> <entry key="../../../../../layout/compose-model-1641203039863.xml" value="0.38981481481481484" />
<entry key="../../../../../layout/compose-model-1641205687355.xml" value="1.0" />
<entry key="../../../../../layout/compose-model-1641205768032.xml" value="0.38981481481481484" />
<entry key="../../../../../layout/compose-model-1641206474090.xml" value="0.33" />
<entry key="../../../../../layout/compose-model-1641212403026.xml" value="0.25" />
<entry key="../../../../../layout/compose-model-1641213954769.xml" value="0.33" />
<entry key="app/src/main/res/drawable-v24/ic_launcher_foreground.xml" value="0.5307291666666667" /> <entry key="app/src/main/res/drawable-v24/ic_launcher_foreground.xml" value="0.5307291666666667" />
<entry key="app/src/main/res/drawable/ic_baseline_keyboard_24.xml" value="0.38981481481481484" />
<entry key="app/src/main/res/drawable/ic_baseline_more_vert_24.xml" value="0.38981481481481484" /> <entry key="app/src/main/res/drawable/ic_baseline_more_vert_24.xml" value="0.38981481481481484" />
<entry key="app/src/main/res/drawable/ic_baseline_person_24.xml" value="0.5307291666666667" /> <entry key="app/src/main/res/drawable/ic_baseline_person_24.xml" value="0.5307291666666667" />
<entry key="app/src/main/res/drawable/ic_launcher_background.xml" value="0.5307291666666667" /> <entry key="app/src/main/res/drawable/ic_launcher_background.xml" value="0.5307291666666667" />

View File

@ -6,21 +6,24 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.compose.foundation.* import androidx.compose.foundation.*
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.* import androidx.compose.material.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsControllerCompat import androidx.core.view.WindowInsetsControllerCompat
import ch.mathieubroillet.jarvis.android.ui.theme.JarvisComposeTheme import ch.mathieubroillet.jarvis.android.ui.theme.JarvisComposeTheme
import ch.mathieubroillet.jarvis.android.ui.theme.productSansFont import ch.mathieubroillet.jarvis.android.ui.theme.productSansFont
import ch.mathieubroillet.jarvis.android.utils.IconAlertDialogTextField
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -52,18 +55,46 @@ class MainActivity : ComponentActivity() {
} }
} }
var messageScroll: ScrollState? = null
//Draws the base of the main activity, that includes the 3-dots menu and the "hi text". //Draws the base of the main activity, that includes the 3-dots menu and the "hi text".
@Composable @Composable
fun Base() { fun Base() {
var expanded by remember { mutableStateOf(false) }
Column(Modifier.padding(bottom = 25.dp)) { Column(Modifier.padding(bottom = 25.dp)) {
Row(Modifier.align(Alignment.End)) { Row(Modifier.align(Alignment.End)) {
IconButton(onClick = { /*TODO*/ }) {
IconAlertDialogTextField(
R.drawable.ic_baseline_keyboard_24,
"Demandez-moi quelque chose",
"Entrez une phrase"
)
IconButton(onClick = { expanded = true }) {
Icon( Icon(
painter = painterResource(id = R.drawable.ic_baseline_more_vert_24), painter = painterResource(id = R.drawable.ic_baseline_more_vert_24),
contentDescription = "3 dots button" contentDescription = "3 dots button"
) )
} }
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
offset = DpOffset((-500).dp, 0.dp)
) {
DropdownMenuItem(onClick = { /* Handle refresh! */ }) {
Text("Effacer la conversation")
}
DropdownMenuItem(onClick = { /* Handle settings! */ }) {
Text("Paramètres")
}
Divider()
DropdownMenuItem(onClick = { /* Handle send feedback! */ }) {
Text("Signaler un problème")
}
}
} }
Text( Text(
@ -76,17 +107,16 @@ fun Base() {
} }
@Composable @Composable
fun Footer() { fun RecordFloatingButton() {
//We create a row that we align to the bottom center of the parent box //We create a row that we align to the bottom center of the parent box
Row( Row(
Modifier Modifier
.padding(bottom = 50.dp)
.fillMaxWidth(), .fillMaxWidth(),
verticalAlignment = Alignment.Bottom, verticalAlignment = Alignment.Bottom,
horizontalArrangement = Arrangement.Center horizontalArrangement = Arrangement.Center
) { ) {
//Microphone floating button to manually start/stop listening //Microphone floating button to manually start/stop listening
FloatingActionButton(onClick = { /*TODO*/ }) { FloatingActionButton(onClick = { /*TODO*/ }, modifier = Modifier.size(70.dp)) {
Icon( Icon(
painter = painterResource(id = R.drawable.ic_baseline_mic_24), painter = painterResource(id = R.drawable.ic_baseline_mic_24),
contentDescription = "microphone" contentDescription = "microphone"
@ -158,30 +188,34 @@ fun DefaultPreview() {
.fillMaxHeight() .fillMaxHeight()
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 15.dp) .padding(horizontal = 15.dp)
.padding(top = 45.dp, bottom = 0.dp) .padding(top = 45.dp, bottom = 10.dp)
) { ) {
// This column regroup the base and all the conversations (everything except the footer) // This column regroup the base and all the conversations (everything except the footer)
Column { Column(Modifier.padding(bottom = 80.dp)) {
Base() Base()
messageScroll = rememberScrollState()
// This column regroup only the conversations and make them scrollable // This column regroup only the conversations and make them scrollable
Column(
modifier = Modifier LazyColumn(content = {
.verticalScroll(rememberScrollState()) item {
.weight(weight = 1f, fill = false) // Basic interaction stuff for demo
) { MessageFromJarvis(text = "Salut, je suis Jarvis! \nPose moi une question et je ferais de mon mieux pour te renseigner.")
// Basic interaction stuff for demo MessageFromUser(text = "Quel temps fait-il à Paris en ce moment ?")
MessageFromJarvis(text = "Salut, je suis Jarvis! \nPose moi une question et je ferais de mon mieux pour te renseigner.") MessageFromJarvis(text = "A Paris, il fait actuellement 10 degrés et le ciel est nuageux.")
MessageFromUser(text = "Quel temps fait-il à Paris en ce moment ?") }
MessageFromJarvis(text = "A Paris, il fait actuellement 10 degrés et le ciel est nuageux.") })
}
} }
// Finally we add the footer to the bottom center of the main box // Finally we add the footer to the bottom center of the main box
Column(Modifier.align(Alignment.BottomCenter)) { Column(
Footer() Modifier
.align(Alignment.BottomCenter)
.padding(bottom = 40.dp)
) {
RecordFloatingButton()
} }
} }
} }

View File

@ -0,0 +1,111 @@
package ch.mathieubroillet.jarvis.android.utils
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import ch.mathieubroillet.jarvis.android.R
import ch.mathieubroillet.jarvis.android.ui.theme.productSansFont
@Composable
fun IconAlertDialogTextField(
buttonIcon: Int = R.drawable.ic_baseline_error_24,
title: String = "Title",
label: String = "Label"
) {
MaterialTheme {
Column {
val openDialog = remember { mutableStateOf(false) }
IconButton(onClick = { openDialog.value = true }) {
Icon(
painter = painterResource(id = buttonIcon),
contentDescription = "icon button with dialog"
)
}
if (openDialog.value) {
AlertDialog(
onDismissRequest = {
// Dismiss the dialog when the user clicks outside the dialog or on the back
// button. If you want to disable that functionality, simply use an empty
// onCloseRequest.
openDialog.value = false
},
title = null,
text = null,
buttons = {
Column(Modifier.fillMaxWidth()) {
Box(
modifier = Modifier
.clip(RectangleShape)
.background(color = MaterialTheme.colors.secondaryVariant)
.padding(horizontal = 20.dp, vertical = 15.dp)
) {
Text(
text = title,
fontFamily = productSansFont,
fontSize = 30.sp
)
}
Box(
modifier = Modifier
.clip(RectangleShape)
.background(color = MaterialTheme.colors.background)
.padding(horizontal = 20.dp)
.padding(top = 15.dp, bottom = 10.dp)
) {
Column {
var text by remember { mutableStateOf(TextFieldValue("")) }
OutlinedTextField(
value = text,
onValueChange = { newText ->
text = newText
},
label = { Text(text = label) },
colors = TextFieldDefaults.outlinedTextFieldColors(
focusedBorderColor = MaterialTheme.colors.secondaryVariant,
focusedLabelColor = MaterialTheme.colors.secondary
)
)
Row(
Modifier
.fillMaxWidth()
.padding(top = 5.dp),
horizontalArrangement = Arrangement.End
) {
TextButton(onClick = { openDialog.value = false }) {
Text(
text = "Annuler",
color = MaterialTheme.colors.secondary
)
}
TextButton(onClick = { /*TODO*/ }) {
Text(
text = "OK",
color = MaterialTheme.colors.secondary
)
}
}
}
}
}
},
shape = RoundedCornerShape(8.dp)
)
}
}
}
}

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M20,5L4,5c-1.1,0 -1.99,0.9 -1.99,2L2,17c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,7c0,-1.1 -0.9,-2 -2,-2zM11,8h2v2h-2L11,8zM11,11h2v2h-2v-2zM8,8h2v2L8,10L8,8zM8,11h2v2L8,13v-2zM7,13L5,13v-2h2v2zM7,10L5,10L5,8h2v2zM16,17L8,17v-2h8v2zM16,13h-2v-2h2v2zM16,10h-2L14,8h2v2zM19,13h-2v-2h2v2zM19,10h-2L17,8h2v2z"/>
</vector>