diff --git a/examples/chat/iosApp/iosApp.xcodeproj/project.pbxproj b/examples/chat/iosApp/iosApp.xcodeproj/project.pbxproj index c4ca1d817d..86a284586f 100644 --- a/examples/chat/iosApp/iosApp.xcodeproj/project.pbxproj +++ b/examples/chat/iosApp/iosApp.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 51; objects = { /* Begin PBXBuildFile section */ @@ -25,7 +25,7 @@ 1EB65E27D2C0F884D0A1A133 /* Pods-iosApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-iosApp.debug.xcconfig"; path = "Target Support Files/Pods-iosApp/Pods-iosApp.debug.xcconfig"; sourceTree = ""; }; 2152FB032600AC8F00CF470E /* iosApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iosApp.swift; sourceTree = ""; }; 3D7A606AB0AD7636269BD9D0 /* Pods-iosApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-iosApp.release.xcconfig"; path = "Target Support Files/Pods-iosApp/Pods-iosApp.release.xcconfig"; sourceTree = ""; }; - 7555FF7B242A565900829871 /* iosApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iosApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 7555FF7B242A565900829871 /* Chat.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Chat.app; sourceTree = BUILT_PRODUCTS_DIR; }; 7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 8DE96E47030356CE6AD9794A /* Pods_iosApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_iosApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; AB3632DC29227652001CCB65 /* Config.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = ""; }; @@ -57,7 +57,7 @@ 7555FF7C242A565900829871 /* Products */ = { isa = PBXGroup; children = ( - 7555FF7B242A565900829871 /* iosApp.app */, + 7555FF7B242A565900829871 /* Chat.app */, ); name = Products; sourceTree = ""; @@ -112,6 +112,7 @@ 7555FF77242A565900829871 /* Sources */, 7555FF79242A565900829871 /* Resources */, 9964867F0862B4D9FB6ABFC7 /* Frameworks */, + BF14C3248E150D55CBFB145F /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -119,7 +120,7 @@ ); name = iosApp; productName = iosApp; - productReference = 7555FF7B242A565900829871 /* iosApp.app */; + productReference = 7555FF7B242A565900829871 /* Chat.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -166,6 +167,23 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + BF14C3248E150D55CBFB145F /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; E8D673591E7196AEA2EA10E2 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/examples/chat/iosApp/iosApp/ComposeInsideSwiftUIScreen.swift b/examples/chat/iosApp/iosApp/ComposeInsideSwiftUIScreen.swift index 262d9d39ee..11aebef9f9 100644 --- a/examples/chat/iosApp/iosApp/ComposeInsideSwiftUIScreen.swift +++ b/examples/chat/iosApp/iosApp/ComposeInsideSwiftUIScreen.swift @@ -14,7 +14,7 @@ struct ComposeInsideSwiftUIScreen: View { struct ComposeLayer: View { var body: some View { - GradientTemplate(title: "Compose inside SwiftUI") { + GradientTemplate(title: "The Composers Chat") { ComposeViewControllerToSwiftUI() .ignoresSafeArea(.keyboard) // Compose have own keyboard handler } @@ -22,7 +22,7 @@ struct ComposeLayer: View { } struct TextInputLayer: View { - @State private var textState: String = "text message" + @State private var textState: String = "" @FocusState private var textFieldFocused: Bool var body: some View { @@ -39,12 +39,11 @@ struct TextInputLayer: View { textState = "" }) { HStack { - Image(systemName: "play.fill") - Text("Send") - }.tint(.white) + Image(systemName: "arrow.up.circle.fill") + }.tint(Color(red: 0.671, green: 0.365, blue: 0.792)) } } - }.padding(10).background(RoundedRectangle(cornerRadius: 10).fill(gradient).opacity(0.8)).padding(6) + }.padding(15).background(RoundedRectangle(cornerRadius: 200).fill(.white).opacity(0.95)).padding(15) } } } diff --git a/examples/chat/iosApp/iosApp/GradientTemplate.swift b/examples/chat/iosApp/iosApp/GradientTemplate.swift index 3220732d80..6feea90f63 100644 --- a/examples/chat/iosApp/iosApp/GradientTemplate.swift +++ b/examples/chat/iosApp/iosApp/GradientTemplate.swift @@ -22,6 +22,5 @@ struct GradientTemplate: View { .navigationBarTitleDisplayMode(.inline) .statusBar(hidden: false) } - .toolbar(.visible, for: .tabBar) } } diff --git a/examples/chat/iosApp/iosApp/iosApp.swift b/examples/chat/iosApp/iosApp/iosApp.swift index 67589c096a..20e038ef7f 100644 --- a/examples/chat/iosApp/iosApp/iosApp.swift +++ b/examples/chat/iosApp/iosApp/iosApp.swift @@ -1,7 +1,10 @@ import SwiftUI let gradient = LinearGradient( - colors: gradient3Colors(), + colors: [ + Color(red: 0.933, green: 0.937, blue: 0.953), + Color(red: 0.902, green: 0.941, blue: 0.949) + ], startPoint: .topLeading, endPoint: .bottomTrailing ) @@ -11,12 +14,13 @@ struct iOSApp: App { WindowGroup { TabView { ComposeInsideSwiftUIScreen() - .tabItem { Label("Compose", systemImage: "square.and.pencil") } + .tabItem { Label("Group Chat", systemImage: "rectangle.3.group.bubble.left") } YetAnotherSwiftUIScreen() - .tabItem { Label("SwiftUI", systemImage: "list.dash") } + .tabItem { Label("Settings", systemImage: "gear") } - }.accentColor(.white).preferredColorScheme(.dark) + } + .accentColor(Color(red: 0.671, green: 0.365, blue: 0.792)).preferredColorScheme(.light) } } } diff --git a/examples/chat/shared/src/commonMain/kotlin/ChatApp.kt b/examples/chat/shared/src/commonMain/kotlin/ChatApp.kt index 1045cec6d0..d5e4ba3b3b 100644 --- a/examples/chat/shared/src/commonMain/kotlin/ChatApp.kt +++ b/examples/chat/shared/src/commonMain/kotlin/ChatApp.kt @@ -1,19 +1,46 @@ -import androidx.compose.foundation.layout.* -import androidx.compose.material.* +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material.LocalTextStyle +import androidx.compose.material.MaterialTheme +import androidx.compose.material.ProvideTextStyle +import androidx.compose.material.Scaffold +import androidx.compose.material.Surface +import androidx.compose.material.Text +import androidx.compose.material.TopAppBar +import androidx.compose.material.lightColors import androidx.compose.runtime.Composable -import androidx.compose.runtime.* +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.unit.sp import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.delay +import org.jetbrains.compose.resources.ExperimentalResourceApi +import org.jetbrains.compose.resources.painterResource -val myUser = User("Me") -val friends = listOf(User("Alex"), User("Lily"), User("Sam")) +val myUser = User("Me", picture = null) +val friends = listOf( + User("Alex", picture = "stock1.jpg"), + User("Casey", picture = "stock2.jpg"), + User("Sam", picture = "stock3.jpg") +) val friendMessages = listOf( - "Hi, have a nice day!", - "Nice to see you!", - "Multiline\ntext\nmessage" + "How's everybody doing today?", + "I've been meaning to chat!", + "When do we hang out next? šŸ˜‹", + "We really need to catch up!", + "It's been too long!", + "I can't\nbelieve\nit! šŸ˜±", + "Did you see that ludicrous\ndisplay last night?", + "We should meet up in person!", + "How about a round of pinball?", + "I'd love to:\nšŸ” Eat something\nšŸŽ„ Watch a movie, maybe?\nWDYT?" ) val store = CoroutineScope(SupervisorJob()).createStore() @@ -23,7 +50,7 @@ fun ChatAppWithScaffold(displayTextField: Boolean = true) { Scaffold( topBar = { TopAppBar( - title = { Text("Chat sample") }, + title = { Text("The Composers Chat") }, backgroundColor = MaterialTheme.colors.background, ) }) { @@ -32,12 +59,14 @@ fun ChatAppWithScaffold(displayTextField: Boolean = true) { } } +@OptIn(ExperimentalResourceApi::class) @Composable fun ChatApp(displayTextField: Boolean = true) { val state by store.stateFlow.collectAsState() Theme { Surface { Box(modifier = Modifier.fillMaxSize()) { + Image(painterResource("background.jpg"), null, contentScale = ContentScale.Crop) Column( modifier = Modifier.fillMaxSize() ) { @@ -58,13 +87,21 @@ fun ChatApp(displayTextField: Boolean = true) { } } LaunchedEffect(Unit) { + var lastFriend = friends.random() + var lastMessage = friendMessages.random() while (true) { + val thisFriend = friends.random() + val thisMessage = friendMessages.random() + if(thisFriend == lastFriend) continue + if(thisMessage == lastMessage) continue + lastFriend = thisFriend + lastMessage = thisMessage store.send( Action.SendMessage( message = Message( - user = friends.random(), + user = thisFriend, timeMs = timestampMs(), - text = friendMessages.random() + text = thisMessage ) ) ) @@ -76,11 +113,13 @@ fun ChatApp(displayTextField: Boolean = true) { @Composable fun Theme(content: @Composable () -> Unit) { MaterialTheme( - colors = darkColors( + colors = lightColors( surface = Color(ChatColors.SURFACE), - background = Color(ChatColors.BACKGROUND), + background = Color(ChatColors.TOP_GRADIENT.last()), ), ) { - content() + ProvideTextStyle(LocalTextStyle.current.copy(letterSpacing = 0.sp)) { + content() + } } } diff --git a/examples/chat/shared/src/commonMain/kotlin/ChatMessage.kt b/examples/chat/shared/src/commonMain/kotlin/ChatMessage.kt new file mode 100644 index 0000000000..0ab64b36a7 --- /dev/null +++ b/examples/chat/shared/src/commonMain/kotlin/ChatMessage.kt @@ -0,0 +1,143 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Outline +import androidx.compose.ui.graphics.Path +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.Density +import androidx.compose.ui.unit.LayoutDirection +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp + +@Composable +fun Triangle(risingToTheRight: Boolean, background: Color) { + Box( + Modifier + .padding(bottom = 10.dp, start = 0.dp) + .clip(TriangleEdgeShape(risingToTheRight)) + .background(background) + .size(6.dp) + ) +} + +@Composable +inline fun ChatMessage(isMyMessage: Boolean, message: Message) { + Box( + modifier = Modifier.fillMaxWidth(), + contentAlignment = if (isMyMessage) Alignment.CenterEnd else Alignment.CenterStart + ) { + + Row(verticalAlignment = Alignment.Bottom) { + if (!isMyMessage) { + Column { + UserPic(message.user) + } + Spacer(Modifier.size(2.dp)) + Column { + Triangle(true, ChatColors.OTHERS_MESSAGE) + } + } + + Column { + Box( + Modifier.clip( + RoundedCornerShape( + 10.dp, + 10.dp, + if (!isMyMessage) 10.dp else 0.dp, + if (!isMyMessage) 0.dp else 10.dp + ) + ) + .background(color = if (!isMyMessage) ChatColors.OTHERS_MESSAGE else ChatColors.MY_MESSAGE) + .padding(start = 10.dp, top = 5.dp, end = 10.dp, bottom = 5.dp), + ) { + Column { + if(!isMyMessage) { + Row(verticalAlignment = Alignment.Bottom) { + Text( + text = message.user.name, + style = MaterialTheme.typography.body1.copy( + fontWeight = FontWeight.SemiBold, + letterSpacing = 0.sp, + fontSize = 14.sp + ), + color = message.user.color + ) + } + } + Spacer(Modifier.size(3.dp)) + Text( + text = message.text, + style = MaterialTheme.typography.body1.copy( + fontSize = 18.sp, + letterSpacing = 0.sp + ) + ) + Spacer(Modifier.size(4.dp)) + Row( + horizontalArrangement = Arrangement.End, + modifier = Modifier.align(Alignment.End) + ) { + Text( + text = timeToString(message.timeMs), + textAlign = TextAlign.End, + style = MaterialTheme.typography.subtitle1.copy(fontSize = 10.sp), + color = ChatColors.TIME_TEXT + ) + } + } + } + Box(Modifier.size(10.dp)) + } + if(isMyMessage) { + Column { + Triangle(false, ChatColors.MY_MESSAGE) + } + } + } + } +} + + + +// Adapted from https://stackoverflow.com/questions/65965852/jetpack-compose-create-chat-bubble-with-arrow-and-border-elevation +class TriangleEdgeShape(val risingToTheRight: Boolean) : Shape { + override fun createOutline( + size: Size, + layoutDirection: LayoutDirection, + density: Density + ): Outline { + val trianglePath = if(risingToTheRight) { + Path().apply { + moveTo(x = 0f, y = size.height) + lineTo(x = size.width, y = 0f) + lineTo(x = size.width, y = size.height) + } + } else { + Path().apply { + moveTo(x = 0f, y = 0f) + lineTo(x = size.width, y = size.height) + lineTo(x = 0f, y = size.height) + } + } + + return Outline.Generic(path = trianglePath) + } +} \ No newline at end of file diff --git a/examples/chat/shared/src/commonMain/kotlin/Colors.kt b/examples/chat/shared/src/commonMain/kotlin/Colors.kt index 9700a2e840..81680050ed 100644 --- a/examples/chat/shared/src/commonMain/kotlin/Colors.kt +++ b/examples/chat/shared/src/commonMain/kotlin/Colors.kt @@ -1,3 +1,4 @@ +import androidx.compose.ui.graphics.Color object ChatColors { val GRADIENT_3 = listOf(0xFF7F52FF, 0xFFC811E2, 0xFFE54857) @@ -5,4 +6,8 @@ object ChatColors { val PRIMARY = 0xFFAA77EE val SURFACE = 0xFFCC99FF val BACKGROUND = 0xFF663388 + val TOP_GRADIENT = listOf(0xFFEEEFF3, 0xFFE6F0F2) + val MY_MESSAGE = Color(0xFFE5FEFB) + val OTHERS_MESSAGE = Color.White + val TIME_TEXT = Color(0xFF979797) } diff --git a/examples/chat/shared/src/commonMain/kotlin/Data.kt b/examples/chat/shared/src/commonMain/kotlin/Data.kt index 907d68f96c..9f5b3faaf2 100644 --- a/examples/chat/shared/src/commonMain/kotlin/Data.kt +++ b/examples/chat/shared/src/commonMain/kotlin/Data.kt @@ -1,5 +1,6 @@ import androidx.compose.ui.graphics.Color import kotlin.random.Random +import kotlin.random.nextInt data class Message private constructor( val user: User, @@ -21,9 +22,25 @@ data class Message private constructor( data class User( val name: String, - val pictureColor: Color = Color( - red = Random.nextInt(0xff), - green = Random.nextInt(0xff), - blue = Random.nextInt(0xff) - ), + val color: Color = ColorProvider.getColor(), + val picture: String? ) + +object ColorProvider { + val colors = mutableListOf( + 0xFFEA3468, + 0xFFB634EA, + 0xFF349BEA, + ) + val allColors = colors.toList() + fun getColor(): Color { + if(colors.size == 0) { + colors.addAll(allColors) + } + println(colors.lastIndex) + val idx = Random.nextInt(colors.indices) + val color = colors[idx] + colors.removeAt(idx) + return Color(color) + } +} \ No newline at end of file diff --git a/examples/chat/shared/src/commonMain/kotlin/Messages.kt b/examples/chat/shared/src/commonMain/kotlin/Messages.kt index 33af5c334f..783cd4cd34 100644 --- a/examples/chat/shared/src/commonMain/kotlin/Messages.kt +++ b/examples/chat/shared/src/commonMain/kotlin/Messages.kt @@ -1,30 +1,26 @@ import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.LazyItemScope +import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.* -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Favorite -import androidx.compose.material.icons.outlined.Favorite import androidx.compose.runtime.Composable -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.geometry.Size -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.unit.dp +import org.jetbrains.compose.resources.ExperimentalResourceApi +import org.jetbrains.compose.resources.painterResource @Composable internal inline fun Messages(messages: List) { @@ -35,97 +31,39 @@ internal inline fun Messages(messages: List) { } } LazyColumn( - modifier = Modifier.fillMaxSize(), + modifier = Modifier.fillMaxSize().padding(start = 4.dp, end = 4.dp), verticalArrangement = Arrangement.spacedBy(8.dp), state = listState, ) { - messages.forEach { message -> - item(key = message.id) { - ChatMessage(isMyMessage = message.user == myUser, message) - } + item { Spacer(Modifier.size(20.dp)) } + items(messages, key = { it.id }) { + ChatMessage(isMyMessage = it.user == myUser, it) } item { - Box(Modifier.height(50.dp)) + Box(Modifier.height(70.dp)) } } } + +@OptIn(ExperimentalResourceApi::class) @Composable -private inline fun ChatMessage(isMyMessage: Boolean, message: Message) { - val focusManager = LocalFocusManager.current - Box( - modifier = Modifier.fillMaxWidth(), - contentAlignment = if (isMyMessage) Alignment.CenterEnd else Alignment.CenterStart - ) { - Surface( - modifier = Modifier.padding(4.dp), - shape = RoundedCornerShape(size = 20.dp), - elevation = 8.dp - ) { - Box( - Modifier.background(brush = Brush.horizontalGradient( - ChatColors.GRADIENT_2.map { Color(it) }) - ).padding(10.dp), - ) { - Row(verticalAlignment = Alignment.Top) { - if (!isMyMessage) { - UserPic(message.user) - Spacer(Modifier.size(8.dp)) - } - Column { - Row(verticalAlignment = Alignment.Bottom) { - Text( - text = message.user.name, - style = MaterialTheme.typography.h5 - ) - Spacer(Modifier.size(10.dp)) - Text( - text = timeToString(message.timeMs), - style = MaterialTheme.typography.h6 - ) - } - Text( - text = message.text - ) - } - if (isMyMessage) { - Spacer(Modifier.size(8.dp)) - UserPic(message.user) - } - } - } - if (!isMyMessage) { - var liked by remember { mutableStateOf(false) } - Icon( - modifier = Modifier.align(Alignment.BottomEnd) - .clickable { - liked = !liked - focusManager.clearFocus(true) - } - .padding(3.dp), - imageVector = if (liked) Icons.Filled.Favorite else Icons.Outlined.Favorite, - contentDescription = "Like", - tint = if (liked) Color.Red else Color.Gray - ) - } +fun UserPic(user: User) { + val imageSize = 48f + val painter = user.picture?.let { + painterResource(it) + } ?: object : Painter() { + override val intrinsicSize: Size = Size(imageSize, imageSize) + override fun DrawScope.onDraw() { + drawRect(user.color, size = Size(imageSize * 4, imageSize * 4)) } } -} - -@Composable -private fun UserPic(user: User) { - val imageSize = 64f Image( modifier = Modifier .size(imageSize.dp) .clip(CircleShape), contentScale = ContentScale.Crop, - painter = object : Painter() { - override val intrinsicSize: Size = Size(imageSize, imageSize) - override fun DrawScope.onDraw() { - drawRect(user.pictureColor, size = Size(imageSize * 4, imageSize * 4)) - } - }, + painter = painter, contentDescription = "User picture" ) } diff --git a/examples/chat/shared/src/commonMain/kotlin/SendMessage.kt b/examples/chat/shared/src/commonMain/kotlin/SendMessage.kt index 0c2629e3d5..c7d46706ae 100644 --- a/examples/chat/shared/src/commonMain/kotlin/SendMessage.kt +++ b/examples/chat/shared/src/commonMain/kotlin/SendMessage.kt @@ -7,13 +7,17 @@ import androidx.compose.material.Icon import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.material.TextField +import androidx.compose.material.TextFieldDefaults import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Send import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.* +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp @Composable @@ -23,9 +27,10 @@ fun SendMessage(sendMessage: (String) -> Unit) { modifier = Modifier.fillMaxWidth() .background(MaterialTheme.colors.background) .padding(10.dp), + colors = TextFieldDefaults.textFieldColors(backgroundColor = Color.White), value = inputText, placeholder = { - Text("type message here") + Text("Type message...") }, onValueChange = { inputText = it diff --git a/examples/chat/shared/src/commonMain/resources/background.jpg b/examples/chat/shared/src/commonMain/resources/background.jpg new file mode 100644 index 0000000000..1e974eabfa Binary files /dev/null and b/examples/chat/shared/src/commonMain/resources/background.jpg differ diff --git a/examples/chat/shared/src/commonMain/resources/stock1.jpg b/examples/chat/shared/src/commonMain/resources/stock1.jpg new file mode 100644 index 0000000000..3d6b5f6fdb Binary files /dev/null and b/examples/chat/shared/src/commonMain/resources/stock1.jpg differ diff --git a/examples/chat/shared/src/commonMain/resources/stock2.jpg b/examples/chat/shared/src/commonMain/resources/stock2.jpg new file mode 100644 index 0000000000..0e41e650e1 Binary files /dev/null and b/examples/chat/shared/src/commonMain/resources/stock2.jpg differ diff --git a/examples/chat/shared/src/commonMain/resources/stock3.jpg b/examples/chat/shared/src/commonMain/resources/stock3.jpg new file mode 100644 index 0000000000..cfe8529bcf Binary files /dev/null and b/examples/chat/shared/src/commonMain/resources/stock3.jpg differ diff --git a/examples/chat/shared/src/commonMain/resources/stock4.jpg b/examples/chat/shared/src/commonMain/resources/stock4.jpg new file mode 100644 index 0000000000..2b6e87d578 Binary files /dev/null and b/examples/chat/shared/src/commonMain/resources/stock4.jpg differ