import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.interop.UIKitView
import androidx.compose.ui.window.ComposeUIViewController
import datamodel.model.PostModel
import kotlinx.cinterop.ExperimentalForeignApi
import platform.UIKit.NSLayoutConstraint
import platform.UIKit.UIColor
import platform.UIKit.UILayoutConstraintAxisVertical
import platform.UIKit.UIScreen
import platform.UIKit.UIScrollView
import platform.UIKit.UIStackView
import platform.UIKit.UIView
import platform.UIKit.UIViewController
import platform.UIKit.addChildViewController
import platform.UIKit.didMoveToParentViewController
import platform.WebKit.WKNavigationDelegateProtocol
import platform.WebKit.WKWebView
import platform.WebKit.javaScriptEnabled
@OptIn(ExperimentalForeignApi::class)
@Composable
actual fun PostContentScreen(
modifier: Modifier,
postModel: PostModel,
htmlContent: String,
) {
val background by rememberUpdatedState(MaterialTheme.colorScheme.background)
val webView by remember {
mutableStateOf(
WKWebView(frame = UIScreen.mainScreen.bounds).also {
it.opaque = false
it.heightAnchor.constraintGreaterThanOrEqualToConstant(2000.0).setActive(true)
it.backgroundColor =
UIColor(
red = background.red.toDouble(),
green = background.green.toDouble(),
blue = background.blue.toDouble(),
alpha = background.alpha.toDouble(),
)
it.configuration.preferences.javaScriptEnabled = true
},
)
}
// Output the HTML content for debugging
UIKitView(
modifier = modifier,
factory = {
ContentViewController(
webView = webView,
backgroundColor =
UIColor(
red = background.red.toDouble(),
green = background.green.toDouble(),
blue = background.blue.toDouble(),
alpha = background.alpha.toDouble(),
),
).view
},
update = {
webView.loadHTMLString(htmlContent, null)
},
interactive = true,
)
}
class ContentViewController(
private val webView: WKWebView,
private val backgroundColor: UIColor,
) : UIViewController(nibName = null, bundle = null) {
override fun viewDidLoad() {
super.viewDidLoad()
setupUI()
}
private fun setupUI() {
val scrollView = UIScrollView()
scrollView.opaque = false
scrollView.backgroundColor = backgroundColor
scrollView.showsVerticalScrollIndicator = false
view.addSubview(scrollView)
scrollView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activateConstraints(
listOf(
scrollView.topAnchor.constraintEqualToAnchor(view.topAnchor),
scrollView.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor),
scrollView.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor),
scrollView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor),
),
)
val stackView = UIStackView()
stackView.axis = UILayoutConstraintAxisVertical
stackView.spacing = 10.0
scrollView.addSubview(stackView)
stackView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activateConstraints(
listOf(
stackView.topAnchor.constraintEqualToAnchor(scrollView.topAnchor),
stackView.leadingAnchor.constraintEqualToAnchor(scrollView.leadingAnchor),
stackView.trailingAnchor.constraintEqualToAnchor(scrollView.trailingAnchor),
stackView.bottomAnchor.constraintEqualToAnchor(scrollView.bottomAnchor),
stackView.widthAnchor.constraintEqualToAnchor(scrollView.widthAnchor),
),
)
val aboveWebViewContentController =
ComposeUIViewController {
Column(
Modifier
.fillMaxWidth()
.windowInsetsPadding(WindowInsets.systemBars),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text("How to use SwiftUI inside Compose Multiplatform")
}
}
val bottomWebViewContentController =
ComposeUIViewController {
Column(
Modifier
.fillMaxWidth()
.windowInsetsPadding(WindowInsets.systemBars),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text("How to use SwiftUI inside Compose Multiplatform")
}
}
stackView.addArrangedSubview(
aboveWebViewContentController.view,
)
addChildViewController(aboveWebViewContentController)
stackView.addArrangedSubview(WebViewContentController(webView).view)
stackView.addArrangedSubview(
bottomWebViewContentController.view,
)
addChildViewController(bottomWebViewContentController)
}
private fun createContainerView(childViewController: UIViewController): UIView {
// Create a Container View for the Child View Controller
val containerView = UIView()
// Add Child View Controller as a Child
addChildViewController(childViewController)
containerView.addSubview(childViewController.view)
childViewController.didMoveToParentViewController(this)
// Setup Constraints (you may need to customize this based on your layout requirements)
childViewController.view.translatesAutoresizingMaskIntoConstraints = true
NSLayoutConstraint.activateConstraints(
listOf(
childViewController.view.topAnchor.constraintEqualToAnchor(containerView.topAnchor),
childViewController.view.leadingAnchor.constraintEqualToAnchor(containerView.leadingAnchor),
childViewController.view.trailingAnchor.constraintEqualToAnchor(containerView.trailingAnchor),
childViewController.view.bottomAnchor.constraintEqualToAnchor(containerView.bottomAnchor),
),
)
return containerView
}
}
class WebViewContentController(private val wkWebView: WKWebView) :
UIViewController(nibName = null, bundle = null),
WKNavigationDelegateProtocol {
override fun loadView() {
wkWebView.navigationDelegate = this
wkWebView.scrollView.bounces = false
view = wkWebView
}
}
class ContentController() :
UIViewController(nibName = null, bundle = null) {
override fun loadView() {
ComposeUIViewController {
Column(
Modifier
.fillMaxWidth()
.windowInsetsPadding(WindowInsets.systemBars),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text("How to use SwiftUI inside Compose Multiplatform")
}
}.view
}
}