diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 528f326..2152988 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -20,6 +20,7 @@ diff --git a/app/src/main/java/ch/broillet/jarvis/android/MainActivity.kt b/app/src/main/java/ch/broillet/jarvis/android/MainActivity.kt index 9b79e34..3b21d5b 100644 --- a/app/src/main/java/ch/broillet/jarvis/android/MainActivity.kt +++ b/app/src/main/java/ch/broillet/jarvis/android/MainActivity.kt @@ -1,7 +1,6 @@ package ch.broillet.jarvis.android import android.os.Bundle -import android.provider.Settings import android.view.WindowManager import androidx.activity.ComponentActivity import androidx.activity.compose.setContent @@ -15,6 +14,7 @@ import ch.broillet.jarvis.android.chat.Message import ch.broillet.jarvis.android.nav.Navigation import ch.broillet.jarvis.android.ui.theme.JarvisclientappTheme import ch.broillet.jarvis.android.utils.SocketHandler +import ch.broillet.jarvis.android.utils.getDeviceId class MainActivity : ComponentActivity() { @@ -36,12 +36,7 @@ class MainActivity : ComponentActivity() { // The following lines connects the Android app to the server. SocketHandler.setSocket() SocketHandler.establishConnection() - SocketHandler.joinRoom( - Settings.Secure.getString( - applicationContext.contentResolver, - Settings.Secure.ANDROID_ID - ) - ) + SocketHandler.joinRoom(getDeviceId(this)) SocketHandler.getSocket() .on("message_from_jarvis") { SocketHandler.messageFromJarvis(it, uiState) } diff --git a/app/src/main/java/ch/broillet/jarvis/android/chat/ConversationUiState.kt b/app/src/main/java/ch/broillet/jarvis/android/chat/ConversationUiState.kt index 5cfb646..b37344b 100644 --- a/app/src/main/java/ch/broillet/jarvis/android/chat/ConversationUiState.kt +++ b/app/src/main/java/ch/broillet/jarvis/android/chat/ConversationUiState.kt @@ -2,6 +2,8 @@ package ch.broillet.jarvis.android.chat import androidx.compose.runtime.Immutable import androidx.compose.runtime.mutableStateListOf +import androidx.compose.ui.res.stringResource +import ch.broillet.jarvis.android.R class ConversationUiState( initialMessages: List @@ -13,6 +15,11 @@ class ConversationUiState( fun addMessage(msg: Message) { _messages.add(0, msg) // Add to the beginning of the list } + + fun clearMessage(){ + _messages.clear() + addMessage(Message(true, "Hello, I'm Jarvis!")) + } } @Immutable diff --git a/app/src/main/java/ch/broillet/jarvis/android/chat/Messages.kt b/app/src/main/java/ch/broillet/jarvis/android/chat/Messages.kt index a28c779..b114ba4 100644 --- a/app/src/main/java/ch/broillet/jarvis/android/chat/Messages.kt +++ b/app/src/main/java/ch/broillet/jarvis/android/chat/Messages.kt @@ -5,10 +5,12 @@ import androidx.compose.foundation.background import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color @@ -16,6 +18,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import ch.broillet.jarvis.android.R import ch.broillet.jarvis.android.ui.theme.productSansFont +import kotlinx.coroutines.delay @Composable fun Messages( @@ -23,9 +26,15 @@ fun Messages( modifier: Modifier = Modifier ) { Box(modifier = modifier) { + val scrollState = rememberLazyListState() + + LaunchedEffect(messages.size) { + delay(50) + scrollState.animateScrollToItem(messages.size) + } LazyColumn( - modifier = Modifier - .fillMaxSize() + modifier = Modifier.fillMaxSize(), + state = scrollState ) { val reverse: List = messages.reversed() diff --git a/app/src/main/java/ch/broillet/jarvis/android/pages/MainPage.kt b/app/src/main/java/ch/broillet/jarvis/android/pages/MainPage.kt index c0cd405..06ac968 100644 --- a/app/src/main/java/ch/broillet/jarvis/android/pages/MainPage.kt +++ b/app/src/main/java/ch/broillet/jarvis/android/pages/MainPage.kt @@ -48,7 +48,7 @@ fun DisplayMainPage( // This column regroup the base and all the conversations (everything except the footer) Column(Modifier.padding(bottom = 80.dp)) { - MainBase(navController) + MainBase(navController, uiState) Messages( messages = uiState.messages, @@ -74,7 +74,7 @@ fun DisplayMainPage( //Draws the base of the main activity, that includes the 3-dots menu and the "hi text". @Composable -fun MainBase(navController: NavController) { +fun MainBase(navController: NavController, uiState: ConversationUiState) { Column( Modifier @@ -82,7 +82,7 @@ fun MainBase(navController: NavController) { .fillMaxWidth() ) { Row(Modifier.align(Alignment.End)) { - DropDownSettingsMenu(navController) + DropDownSettingsMenu(navController, uiState) } Text( @@ -95,7 +95,7 @@ fun MainBase(navController: NavController) { } @Composable -fun DropDownSettingsMenu(navController: NavController) { +fun DropDownSettingsMenu(navController: NavController, uiState: ConversationUiState) { var expanded by remember { mutableStateOf(false) } IconButton(onClick = { expanded = true }) { @@ -112,7 +112,7 @@ fun DropDownSettingsMenu(navController: NavController) { ) { DropdownMenuItem( text = { Text(stringResource(id = R.string.main_page_delete_conversation)) }, - onClick = { navController.navigate(Screen.PermissionsScreen.route) }, + onClick = { SocketHandler.clearMessages(uiState, getDeviceId(navController.context)) }, leadingIcon = { Icon( Icons.Outlined.Edit, @@ -219,13 +219,7 @@ fun processMessage(text: String, navController: NavController, uiState: Conversa uiState.addMessage(Message(false, text)) navController.context.mainExecutor.execute { - SocketHandler.processMessage( - text, - Secure.getString( - navController.context.contentResolver, - Secure.ANDROID_ID - ) - ) + SocketHandler.processMessage(text, getDeviceId(navController.context)) } } diff --git a/app/src/main/java/ch/broillet/jarvis/android/utils/SocketHandler.kt b/app/src/main/java/ch/broillet/jarvis/android/utils/SocketHandler.kt index 5554367..48229e3 100644 --- a/app/src/main/java/ch/broillet/jarvis/android/utils/SocketHandler.kt +++ b/app/src/main/java/ch/broillet/jarvis/android/utils/SocketHandler.kt @@ -53,11 +53,20 @@ object SocketHandler { getSocket().emit("join", body.toString()) } + @Synchronized + fun clearMessages(uiState: ConversationUiState, uuid: String) { + val body = JSONObject() + body.put("uuid", uuid) + + getSocket().emit("clear_chat", body.toString()) + uiState.clearMessage() + } + fun messageFromJarvis(data: Array, uiState: ConversationUiState) { if (data[0].toString().contains("data")) { val result: JSONObject = data[0] as JSONObject - if(result.getString("data") != "") { + if (result.getString("data") != "") { uiState.addMessage(Message(true, result.getString("data"))) } } @@ -67,7 +76,7 @@ object SocketHandler { fun messageFromUser(data: Array, uiState: ConversationUiState) { if (data[0].toString().contains("data")) { val result: JSONObject = data[0] as JSONObject - if(result.getString("data") != "") { + if (result.getString("data") != "") { uiState.addMessage(Message(false, result.getString("data"))) } } diff --git a/app/src/main/java/ch/broillet/jarvis/android/utils/Utils.kt b/app/src/main/java/ch/broillet/jarvis/android/utils/Utils.kt index 108629a..03d351f 100644 --- a/app/src/main/java/ch/broillet/jarvis/android/utils/Utils.kt +++ b/app/src/main/java/ch/broillet/jarvis/android/utils/Utils.kt @@ -9,7 +9,6 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp - @Composable fun DefaultBox( content: @Composable() (BoxScope.() -> Unit) @@ -36,3 +35,7 @@ fun openAppSettings(context: Context) { ) ) } + +fun getDeviceId(context: Context): String { + return Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID) +} \ No newline at end of file