diff --git a/experimental/examples/chat-mpp/README.md b/experimental/examples/chat-mpp/README.md index 8ac4b08fe0..468072b28c 100644 --- a/experimental/examples/chat-mpp/README.md +++ b/experimental/examples/chat-mpp/README.md @@ -25,3 +25,12 @@ Then choose **iosApp** configuration in IDE and run it. ## Run JS in browser with WebAssembly Skia via Gradle `./gradlew jsApp:jsBrowserDevelopmentRun` + +### Run MacOS via Gradle: +- on Intel CPU: `./gradlew :shared:runDebugExecutableMacosX64` +- on Apple Silicon: `./gradlew :shared:runDebugExecutableMacosArm64` + +## SwiftUI interop +This example shows how you can set up an interop between SwiftUI and Compose. +Pay attention to the file [ComposeViewControllerToSwiftUI.swift](iosApp%2FiosApp%2FComposeViewControllerToSwiftUI.swift). +This file help to add Compose inside SwiftUI hierarchy. diff --git a/experimental/examples/chat-mpp/gradle.properties b/experimental/examples/chat-mpp/gradle.properties index 662d52bb4c..b4602ef0db 100644 --- a/experimental/examples/chat-mpp/gradle.properties +++ b/experimental/examples/chat-mpp/gradle.properties @@ -14,4 +14,4 @@ kotlin.mpp.enableGranularSourceSetsMetadata=true kotlin.native.binary.memoryModel=experimental kotlin.version=1.8.0 agp.version=7.1.3 -compose.version=1.3.0 +compose.version=1.4.0-alpha01-dev940 diff --git a/experimental/examples/chat-mpp/iosApp/iosApp.xcodeproj/project.pbxproj b/experimental/examples/chat-mpp/iosApp/iosApp.xcodeproj/project.pbxproj index c9a234c0cf..fd38c4550e 100644 --- a/experimental/examples/chat-mpp/iosApp/iosApp.xcodeproj/project.pbxproj +++ b/experimental/examples/chat-mpp/iosApp/iosApp.xcodeproj/project.pbxproj @@ -7,11 +7,21 @@ objects = { /* Begin PBXBuildFile section */ + 184880BA0E9910C2B5012412 /* KotlinToSwiftHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18488D89B8500CD7696A04EB /* KotlinToSwiftHelper.swift */; }; + 1848810122D49D4AD3668D91 /* ComposeViewControllerToSwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18488656503C85EEDA66341D /* ComposeViewControllerToSwiftUI.swift */; }; + 184881FBE98BA5BF02A0A186 /* GradientTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1848892FA748717E4087E7D7 /* GradientTemplate.swift */; }; + 1848823F43E447F9A8B4AC7C /* YetAnotherSwiftUIScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18488451271FAAD8FA34A2FB /* YetAnotherSwiftUIScreen.swift */; }; + 184882D8AF2A7A3642004010 /* ComposeInsideSwiftUIScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18488CAB0978B80826E5BBB4 /* ComposeInsideSwiftUIScreen.swift */; }; 2152FB042600AC8F00CF470E /* iosApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* iosApp.swift */; }; C1FC908188C4E8695729CB06 /* Pods_iosApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DE96E47030356CE6AD9794A /* Pods_iosApp.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 18488451271FAAD8FA34A2FB /* YetAnotherSwiftUIScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = YetAnotherSwiftUIScreen.swift; sourceTree = ""; }; + 18488656503C85EEDA66341D /* ComposeViewControllerToSwiftUI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ComposeViewControllerToSwiftUI.swift; sourceTree = ""; }; + 1848892FA748717E4087E7D7 /* GradientTemplate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GradientTemplate.swift; sourceTree = ""; }; + 18488CAB0978B80826E5BBB4 /* ComposeInsideSwiftUIScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ComposeInsideSwiftUIScreen.swift; sourceTree = ""; }; + 18488D89B8500CD7696A04EB /* KotlinToSwiftHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KotlinToSwiftHelper.swift; sourceTree = ""; }; 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 = ""; }; @@ -57,6 +67,11 @@ children = ( 7555FF8C242A565B00829871 /* Info.plist */, 2152FB032600AC8F00CF470E /* iosApp.swift */, + 18488656503C85EEDA66341D /* ComposeViewControllerToSwiftUI.swift */, + 18488D89B8500CD7696A04EB /* KotlinToSwiftHelper.swift */, + 18488CAB0978B80826E5BBB4 /* ComposeInsideSwiftUIScreen.swift */, + 18488451271FAAD8FA34A2FB /* YetAnotherSwiftUIScreen.swift */, + 1848892FA748717E4087E7D7 /* GradientTemplate.swift */, ); path = iosApp; sourceTree = ""; @@ -181,6 +196,11 @@ buildActionMask = 2147483647; files = ( 2152FB042600AC8F00CF470E /* iosApp.swift in Sources */, + 1848810122D49D4AD3668D91 /* ComposeViewControllerToSwiftUI.swift in Sources */, + 184880BA0E9910C2B5012412 /* KotlinToSwiftHelper.swift in Sources */, + 184882D8AF2A7A3642004010 /* ComposeInsideSwiftUIScreen.swift in Sources */, + 1848823F43E447F9A8B4AC7C /* YetAnotherSwiftUIScreen.swift in Sources */, + 184881FBE98BA5BF02A0A186 /* GradientTemplate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -316,13 +336,13 @@ DEVELOPMENT_TEAM = "${TEAM_ID}"; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = iosApp/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = "org.jetbrains.Chat${TEAM_ID}"; - PRODUCT_NAME = "Chat"; + PRODUCT_NAME = Chat; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -340,13 +360,13 @@ DEVELOPMENT_TEAM = "${TEAM_ID}"; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = iosApp/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = "org.jetbrains.Chat${TEAM_ID}"; - PRODUCT_NAME = "Chat"; + PRODUCT_NAME = Chat; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/experimental/examples/chat-mpp/iosApp/iosApp/ComposeInsideSwiftUIScreen.swift b/experimental/examples/chat-mpp/iosApp/iosApp/ComposeInsideSwiftUIScreen.swift new file mode 100644 index 0000000000..262d9d39ee --- /dev/null +++ b/experimental/examples/chat-mpp/iosApp/iosApp/ComposeInsideSwiftUIScreen.swift @@ -0,0 +1,50 @@ +import SwiftUI + +struct ComposeInsideSwiftUIScreen: View { + var body: some View { + ZStack { + ComposeLayer() + TextInputLayer() + }.onTapGesture { + // Hide keyboard on tap outside of TextField + UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) + } + } +} + +struct ComposeLayer: View { + var body: some View { + GradientTemplate(title: "Compose inside SwiftUI") { + ComposeViewControllerToSwiftUI() + .ignoresSafeArea(.keyboard) // Compose have own keyboard handler + } + } +} + +struct TextInputLayer: View { + @State private var textState: String = "text message" + @FocusState private var textFieldFocused: Bool + + var body: some View { + VStack { + Spacer() + HStack { + TextField("Type message...", text: $textState, axis: .vertical) + .focused($textFieldFocused) + .lineLimit(3) + if (!textState.isEmpty) { + Button(action: { + sendMessage(textState) + textFieldFocused = false + textState = "" + }) { + HStack { + Image(systemName: "play.fill") + Text("Send") + }.tint(.white) + } + } + }.padding(10).background(RoundedRectangle(cornerRadius: 10).fill(gradient).opacity(0.8)).padding(6) + } + } +} diff --git a/experimental/examples/chat-mpp/iosApp/iosApp/ComposeViewControllerToSwiftUI.swift b/experimental/examples/chat-mpp/iosApp/iosApp/ComposeViewControllerToSwiftUI.swift new file mode 100644 index 0000000000..1de3f10601 --- /dev/null +++ b/experimental/examples/chat-mpp/iosApp/iosApp/ComposeViewControllerToSwiftUI.swift @@ -0,0 +1,12 @@ +import UIKit +import SwiftUI +import shared + +struct ComposeViewControllerToSwiftUI: UIViewControllerRepresentable { + func makeUIViewController(context: Context) -> UIViewController { + return Main_iosKt.ChapViewController() + } + + func updateUIViewController(_ uiViewController: UIViewController, context: Context) { + } +} diff --git a/experimental/examples/chat-mpp/iosApp/iosApp/GradientTemplate.swift b/experimental/examples/chat-mpp/iosApp/iosApp/GradientTemplate.swift new file mode 100644 index 0000000000..3220732d80 --- /dev/null +++ b/experimental/examples/chat-mpp/iosApp/iosApp/GradientTemplate.swift @@ -0,0 +1,27 @@ +import SwiftUI + +struct GradientTemplate: View { + var title: String + var content: () -> Content + + var body: some View { + NavigationView { + ZStack { + surfaceColor() + VStack { + gradient.ignoresSafeArea(edges: .top).frame(height: 0) + Spacer() + } + content() + VStack { + Spacer() + Rectangle().frame(height: 0).background(gradient) + } + } + .navigationTitle(title) + .navigationBarTitleDisplayMode(.inline) + .statusBar(hidden: false) + } + .toolbar(.visible, for: .tabBar) + } +} diff --git a/experimental/examples/chat-mpp/iosApp/iosApp/KotlinToSwiftHelper.swift b/experimental/examples/chat-mpp/iosApp/iosApp/KotlinToSwiftHelper.swift new file mode 100644 index 0000000000..6cacbdcd1b --- /dev/null +++ b/experimental/examples/chat-mpp/iosApp/iosApp/KotlinToSwiftHelper.swift @@ -0,0 +1,25 @@ +import UIKit +import SwiftUI +import shared + +public func sendMessage(_ text: String) { + Main_iosKt.sendMessage(text: text) +} + +public func gradient3Colors() -> [Color] { + return Main_iosKt.gradient3Colors().map { hex in + Color(getCGColor(hex.intValue)).opacity(1.0) + } +} + +public func surfaceColor() -> Color { + Color(getCGColor(Int(Main_iosKt.surfaceColor()))) +} + +private func getCGColor(_ argb: Int) -> CGColor { + func clr(_ component: Int) -> CGFloat { + CGFloat(component & 0xff) / 255.0 + } + + return CGColor(red: clr(argb >> 16), green: clr(argb >> 8), blue: clr(argb), alpha: clr(argb >> 24)) +} diff --git a/experimental/examples/chat-mpp/iosApp/iosApp/YetAnotherSwiftUIScreen.swift b/experimental/examples/chat-mpp/iosApp/iosApp/YetAnotherSwiftUIScreen.swift new file mode 100644 index 0000000000..3c6e2367d6 --- /dev/null +++ b/experimental/examples/chat-mpp/iosApp/iosApp/YetAnotherSwiftUIScreen.swift @@ -0,0 +1,11 @@ +import SwiftUI + +struct YetAnotherSwiftUIScreen: View { + var body: some View { + GradientTemplate(title: "SwiftUI") { + VStack { + Text("Yet another SwiftUI screen") + } + } + } +} diff --git a/experimental/examples/chat-mpp/iosApp/iosApp/iosApp.swift b/experimental/examples/chat-mpp/iosApp/iosApp/iosApp.swift index b42016a6fc..67589c096a 100644 --- a/experimental/examples/chat-mpp/iosApp/iosApp/iosApp.swift +++ b/experimental/examples/chat-mpp/iosApp/iosApp/iosApp.swift @@ -1,15 +1,22 @@ -import UIKit -import shared +import SwiftUI -@UIApplicationMain -class AppDelegate: UIResponder, UIApplicationDelegate { - var window: UIWindow? +let gradient = LinearGradient( + colors: gradient3Colors(), + startPoint: .topLeading, endPoint: .bottomTrailing +) - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - window = UIWindow(frame: UIScreen.main.bounds) - let mainViewController = Main_iosKt.MainViewController() - window?.rootViewController = mainViewController - window?.makeKeyAndVisible() - return true - } +@main +struct iOSApp: App { + var body: some Scene { + WindowGroup { + TabView { + ComposeInsideSwiftUIScreen() + .tabItem { Label("Compose", systemImage: "square.and.pencil") } + + YetAnotherSwiftUIScreen() + .tabItem { Label("SwiftUI", systemImage: "list.dash") } + + }.accentColor(.white).preferredColorScheme(.dark) + } + } } diff --git a/experimental/examples/chat-mpp/shared/src/androidMain/kotlin/main.android.kt b/experimental/examples/chat-mpp/shared/src/androidMain/kotlin/main.android.kt index bef1ebc77c..d634b32f32 100644 --- a/experimental/examples/chat-mpp/shared/src/androidMain/kotlin/main.android.kt +++ b/experimental/examples/chat-mpp/shared/src/androidMain/kotlin/main.android.kt @@ -1,4 +1,4 @@ import androidx.compose.runtime.Composable @Composable -fun MainView() = ChatApp() \ No newline at end of file +fun MainView() = ChatAppWithScaffold() \ No newline at end of file diff --git a/experimental/examples/chat-mpp/shared/src/commonMain/kotlin/ChatApp.kt b/experimental/examples/chat-mpp/shared/src/commonMain/kotlin/ChatApp.kt index 873212b97b..109a915297 100644 --- a/experimental/examples/chat-mpp/shared/src/commonMain/kotlin/ChatApp.kt +++ b/experimental/examples/chat-mpp/shared/src/commonMain/kotlin/ChatApp.kt @@ -3,6 +3,9 @@ import androidx.compose.material.* import androidx.compose.runtime.Composable import androidx.compose.runtime.* import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.delay val myUser = User("Me") @@ -12,34 +15,43 @@ val friendMessages = listOf( "Nice to see you!", "Multiline\ntext\nmessage" ) +val store = CoroutineScope(SupervisorJob()).createStore() @Composable -internal fun ChatApp() { - val coroutineScope = rememberCoroutineScope() - val store = remember { coroutineScope.createStore() } - val state by store.stateFlow.collectAsState() +internal fun ChatAppWithScaffold(displayTextField: Boolean = true) { + Theme { + Scaffold( + topBar = { + TopAppBar( + title = { Text("Chat sample") }, + backgroundColor = MaterialTheme.colors.background, + ) + }) { + ChatApp(displayTextField = displayTextField) + } + } +} - MaterialTheme { - Box(modifier = Modifier.fillMaxSize()) { - Scaffold( - topBar = { - TopAppBar( - title = { Text("Chat sample") } - ) - } - ) { +@Composable +internal fun ChatApp(displayTextField: Boolean = true) { + val state by store.stateFlow.collectAsState() + Theme { + Surface { + Box(modifier = Modifier.fillMaxSize()) { Column( modifier = Modifier.fillMaxSize() ) { Box(Modifier.weight(1f)) { Messages(state.messages) } - SendMessage { text -> - store.send( - Action.SendMessage( - Message(myUser, timeMs = timestampMs(), text) + if (displayTextField) { + SendMessage { text -> + store.send( + Action.SendMessage( + Message(myUser, timeMs = timestampMs(), text) + ) ) - ) + } } } } @@ -60,3 +72,15 @@ internal fun ChatApp() { } } } + +@Composable +internal fun Theme(content: @Composable () -> Unit) { + MaterialTheme( + colors = darkColors( + surface = Color(ChatColors.SURFACE), + background = Color(ChatColors.BACKGROUND), + ), + ) { + content() + } +} diff --git a/experimental/examples/chat-mpp/shared/src/commonMain/kotlin/Colors.kt b/experimental/examples/chat-mpp/shared/src/commonMain/kotlin/Colors.kt new file mode 100644 index 0000000000..9700a2e840 --- /dev/null +++ b/experimental/examples/chat-mpp/shared/src/commonMain/kotlin/Colors.kt @@ -0,0 +1,8 @@ + +object ChatColors { + val GRADIENT_3 = listOf(0xFF7F52FF, 0xFFC811E2, 0xFFE54857) + val GRADIENT_2 = listOf(0xFFC811E2, 0xFF7F52FF) + val PRIMARY = 0xFFAA77EE + val SURFACE = 0xFFCC99FF + val BACKGROUND = 0xFF663388 +} diff --git a/experimental/examples/chat-mpp/shared/src/commonMain/kotlin/Messages.kt b/experimental/examples/chat-mpp/shared/src/commonMain/kotlin/Messages.kt index cc5408e739..33af5c334f 100644 --- a/experimental/examples/chat-mpp/shared/src/commonMain/kotlin/Messages.kt +++ b/experimental/examples/chat-mpp/shared/src/commonMain/kotlin/Messages.kt @@ -3,7 +3,7 @@ import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape @@ -23,6 +23,7 @@ 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 @Composable @@ -43,27 +44,31 @@ internal inline fun Messages(messages: List) { ChatMessage(isMyMessage = message.user == myUser, message) } } -// items(messages, key = { it.id }) { message -> //TODO not working in JS -// ChatMessage(isMyMessage = message.user == myUser, message) -// } + item { + Box(Modifier.height(50.dp)) + } } } @Composable private inline fun ChatMessage(isMyMessage: Boolean, message: Message) { - Box(modifier = Modifier.fillMaxWidth()) { + val focusManager = LocalFocusManager.current + Box( + modifier = Modifier.fillMaxWidth(), + contentAlignment = if (isMyMessage) Alignment.CenterEnd else Alignment.CenterStart + ) { Surface( - modifier = Modifier.padding(4.dp) - .align(if (isMyMessage) Alignment.CenterStart else Alignment.CenterEnd), + modifier = Modifier.padding(4.dp), shape = RoundedCornerShape(size = 20.dp), elevation = 8.dp ) { Box( - Modifier.background(brush = Brush.horizontalGradient(listOf(Color(0xff8888ff), Color(0xffddddff)))) - .padding(10.dp), + Modifier.background(brush = Brush.horizontalGradient( + ChatColors.GRADIENT_2.map { Color(it) }) + ).padding(10.dp), ) { Row(verticalAlignment = Alignment.Top) { - if (isMyMessage) { + if (!isMyMessage) { UserPic(message.user) Spacer(Modifier.size(8.dp)) } @@ -83,25 +88,26 @@ private inline fun ChatMessage(isMyMessage: Boolean, message: Message) { text = message.text ) } - if (!isMyMessage) { + 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 - } - .padding(4.dp), - imageVector = if (liked) Icons.Filled.Favorite else Icons.Outlined.Favorite, - contentDescription = "Like", - tint = if (liked) Color.Red else Color.Gray - ) + 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 + ) + } } } } diff --git a/experimental/examples/chat-mpp/shared/src/desktopMain/kotlin/main.desktop.kt b/experimental/examples/chat-mpp/shared/src/desktopMain/kotlin/main.desktop.kt index b5f998e2c7..ad2af2bf6d 100644 --- a/experimental/examples/chat-mpp/shared/src/desktopMain/kotlin/main.desktop.kt +++ b/experimental/examples/chat-mpp/shared/src/desktopMain/kotlin/main.desktop.kt @@ -2,10 +2,10 @@ import androidx.compose.desktop.ui.tooling.preview.Preview import androidx.compose.runtime.Composable @Composable -fun MainView() = ChatApp() +fun MainView() = ChatAppWithScaffold() @Preview @Composable fun ChatPreview() { - ChatApp() + MainView() } diff --git a/experimental/examples/chat-mpp/shared/src/iosMain/kotlin/main.ios.kt b/experimental/examples/chat-mpp/shared/src/iosMain/kotlin/main.ios.kt index c643166f94..fd69f960ee 100644 --- a/experimental/examples/chat-mpp/shared/src/iosMain/kotlin/main.ios.kt +++ b/experimental/examples/chat-mpp/shared/src/iosMain/kotlin/main.ios.kt @@ -1,8 +1,15 @@ import androidx.compose.ui.window.Application import platform.UIKit.UIViewController -fun MainViewController(): UIViewController = +fun ChapViewController(): UIViewController = Application("Chat") { - ChatApp() + ChatApp(displayTextField = false) } +fun sendMessage(text: String) { + store.send(Action.SendMessage(Message(myUser, timestampMs(), text))) +} + +fun gradient3Colors() = ChatColors.GRADIENT_3 + +fun surfaceColor() = ChatColors.SURFACE diff --git a/experimental/examples/chat-mpp/shared/src/jsMain/kotlin/main.js.kt b/experimental/examples/chat-mpp/shared/src/jsMain/kotlin/main.js.kt index 6ea0df4686..9c5e081fa5 100644 --- a/experimental/examples/chat-mpp/shared/src/jsMain/kotlin/main.js.kt +++ b/experimental/examples/chat-mpp/shared/src/jsMain/kotlin/main.js.kt @@ -1,6 +1,6 @@ import androidx.compose.runtime.Composable @Composable -fun MainView() = ChatApp() +fun MainView() = ChatAppWithScaffold() diff --git a/experimental/examples/chat-mpp/shared/src/macosMain/kotlin/main.macos.kt b/experimental/examples/chat-mpp/shared/src/macosMain/kotlin/main.macos.kt index 37edafc707..475b8eb8c2 100644 --- a/experimental/examples/chat-mpp/shared/src/macosMain/kotlin/main.macos.kt +++ b/experimental/examples/chat-mpp/shared/src/macosMain/kotlin/main.macos.kt @@ -5,7 +5,7 @@ import platform.AppKit.NSApplication fun main() { NSApplication.sharedApplication() Window("Chat App") { - ChatApp() + ChatAppWithScaffold() } NSApp?.run() }