mirror of
https://github.com/jlengrand/compose-multiplatform.git
synced 2026-03-10 08:11:20 +00:00
Compose inside SwiftUI example (#2755)
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = "<group>"; };
|
||||
18488656503C85EEDA66341D /* ComposeViewControllerToSwiftUI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ComposeViewControllerToSwiftUI.swift; sourceTree = "<group>"; };
|
||||
1848892FA748717E4087E7D7 /* GradientTemplate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GradientTemplate.swift; sourceTree = "<group>"; };
|
||||
18488CAB0978B80826E5BBB4 /* ComposeInsideSwiftUIScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ComposeInsideSwiftUIScreen.swift; sourceTree = "<group>"; };
|
||||
18488D89B8500CD7696A04EB /* KotlinToSwiftHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KotlinToSwiftHelper.swift; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
2152FB032600AC8F00CF470E /* iosApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iosApp.swift; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
@@ -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 = "<group>";
|
||||
@@ -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";
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import SwiftUI
|
||||
|
||||
struct GradientTemplate<Content: View>: 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)
|
||||
}
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import SwiftUI
|
||||
|
||||
struct YetAnotherSwiftUIScreen: View {
|
||||
var body: some View {
|
||||
GradientTemplate(title: "SwiftUI") {
|
||||
VStack {
|
||||
Text("Yet another SwiftUI screen")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import androidx.compose.runtime.Composable
|
||||
|
||||
@Composable
|
||||
fun MainView() = ChatApp()
|
||||
fun MainView() = ChatAppWithScaffold()
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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<Message>) {
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import androidx.compose.runtime.Composable
|
||||
|
||||
@Composable
|
||||
fun MainView() = ChatApp()
|
||||
fun MainView() = ChatAppWithScaffold()
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import platform.AppKit.NSApplication
|
||||
fun main() {
|
||||
NSApplication.sharedApplication()
|
||||
Window("Chat App") {
|
||||
ChatApp()
|
||||
ChatAppWithScaffold()
|
||||
}
|
||||
NSApp?.run()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user