bring some android stuff back up to date
This commit is contained in:
-150
@@ -1,150 +0,0 @@
|
|||||||
package expo.modules.bottomsheet
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.view.View
|
|
||||||
import android.widget.FrameLayout
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.ui.platform.ComposeView
|
|
||||||
import androidx.core.view.allViews
|
|
||||||
import com.facebook.react.ReactRootView
|
|
||||||
import expo.modules.kotlin.AppContext
|
|
||||||
import expo.modules.kotlin.viewevent.EventDispatcher
|
|
||||||
import expo.modules.kotlin.views.ExpoView
|
|
||||||
|
|
||||||
class BottomSheetView(
|
|
||||||
context: Context,
|
|
||||||
appContext: AppContext,
|
|
||||||
) : ExpoView(context, appContext) {
|
|
||||||
val sheetState = mutableStateOf(SheetState())
|
|
||||||
|
|
||||||
private var reactRootView: ReactRootView? = null
|
|
||||||
private var innerView: View? = null
|
|
||||||
|
|
||||||
private var sheetView: ComposeView? = null
|
|
||||||
|
|
||||||
private val onStateChange by EventDispatcher()
|
|
||||||
private val onAttemptDismiss by EventDispatcher()
|
|
||||||
|
|
||||||
// Props
|
|
||||||
var preventDismiss = false
|
|
||||||
var minHeight = 0f
|
|
||||||
var maxHeight = 0f
|
|
||||||
|
|
||||||
private var isOpen: Boolean = false
|
|
||||||
set(value) {
|
|
||||||
if (field == value) return
|
|
||||||
|
|
||||||
field = value
|
|
||||||
this.sheetState.value.isOpen = value
|
|
||||||
onStateChange(
|
|
||||||
mapOf(
|
|
||||||
"state" to if (value) "open" else "closed",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private var isOpening: Boolean = false
|
|
||||||
set(value) {
|
|
||||||
field = value
|
|
||||||
if (value) {
|
|
||||||
onStateChange(mapOf("state" to "opening"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private var isClosing: Boolean = false
|
|
||||||
set(value) {
|
|
||||||
field = value
|
|
||||||
if (value) {
|
|
||||||
onStateChange(mapOf("state" to "closing"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private var hasInitiallyOpened = false
|
|
||||||
|
|
||||||
// Lifecycle
|
|
||||||
|
|
||||||
override fun addView(
|
|
||||||
child: View?,
|
|
||||||
index: Int,
|
|
||||||
) {
|
|
||||||
this.innerView = child
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onLayout(
|
|
||||||
changed: Boolean,
|
|
||||||
l: Int,
|
|
||||||
t: Int,
|
|
||||||
r: Int,
|
|
||||||
b: Int,
|
|
||||||
) {
|
|
||||||
this.innerView?.let {
|
|
||||||
val height =
|
|
||||||
it.allViews
|
|
||||||
.last()
|
|
||||||
.measuredHeight
|
|
||||||
.toFloat()
|
|
||||||
this.present(height)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun destroy() {
|
|
||||||
this.isClosing = false
|
|
||||||
this.isOpen = false
|
|
||||||
|
|
||||||
this.getRootLayout().removeView(this.sheetView)
|
|
||||||
this.sheetView = null
|
|
||||||
|
|
||||||
this.reactRootView = null
|
|
||||||
this.innerView = null
|
|
||||||
}
|
|
||||||
|
|
||||||
// Presentation
|
|
||||||
|
|
||||||
private fun present(contentHeight: Float) {
|
|
||||||
val innerView = this.innerView ?: return
|
|
||||||
|
|
||||||
// For GestureRootView to work, we need to create a ReactRootView for the innerView to be
|
|
||||||
// contained inside of
|
|
||||||
val reactRootView = ReactRootView(context)
|
|
||||||
reactRootView.addView(innerView)
|
|
||||||
this.reactRootView = reactRootView
|
|
||||||
|
|
||||||
this.isOpening = true
|
|
||||||
this.sheetView =
|
|
||||||
ComposeView(context).also {
|
|
||||||
it.setContent {
|
|
||||||
SheetView(
|
|
||||||
state = sheetState,
|
|
||||||
innerView = reactRootView,
|
|
||||||
contentHeight = innerView.height.toFloat(),
|
|
||||||
onDismissRequest = {
|
|
||||||
onAttemptDismiss(mapOf())
|
|
||||||
if (!preventDismiss) {
|
|
||||||
dismiss()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onExpanded = {
|
|
||||||
isOpening = false
|
|
||||||
isOpen = true
|
|
||||||
hasInitiallyOpened = true
|
|
||||||
},
|
|
||||||
onHidden = {
|
|
||||||
if (hasInitiallyOpened) {
|
|
||||||
destroy()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
getRootLayout().addView(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun dismiss() {
|
|
||||||
this.isClosing = true
|
|
||||||
this.destroy()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utils
|
|
||||||
|
|
||||||
private fun getRootLayout(): FrameLayout = appContext.currentActivity!!.findViewById(android.R.id.content)
|
|
||||||
}
|
|
||||||
+17
-12
@@ -7,17 +7,18 @@ import expo.modules.kotlin.modules.ModuleDefinition
|
|||||||
class BottomSheetModule : Module() {
|
class BottomSheetModule : Module() {
|
||||||
override fun definition() =
|
override fun definition() =
|
||||||
ModuleDefinition {
|
ModuleDefinition {
|
||||||
Name("BlueskyBottomSheet")
|
Name("BottomSheet")
|
||||||
|
|
||||||
Function("getSafeAreaInset") {
|
AsyncFunction("dismissAll") {
|
||||||
return@Function 10 // @TODO
|
SheetManager.dismissAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
View(BottomSheetView::class) {
|
View(BottomSheetView::class) {
|
||||||
Events(
|
Events(
|
||||||
arrayOf(
|
arrayOf(
|
||||||
"onStateChange",
|
|
||||||
"onAttemptDismiss",
|
"onAttemptDismiss",
|
||||||
|
"onSnapPointChange",
|
||||||
|
"onStateChange",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -25,8 +26,16 @@ class BottomSheetModule : Module() {
|
|||||||
view.dismiss()
|
view.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
Prop("preventDismiss") { view: BottomSheetView, prop: Boolean ->
|
AsyncFunction("updateLayout") { view: BottomSheetView ->
|
||||||
view.preventDismiss = prop
|
view.updateLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
Prop("containerBackgroundColor") { view: BottomSheetView, prop: String ->
|
||||||
|
view.sheetState.value.containerBackgroundColor = Color.parseColor(prop)
|
||||||
|
}
|
||||||
|
|
||||||
|
Prop("cornerRadius") { view: BottomSheetView, prop: Float ->
|
||||||
|
view.sheetState.value.cornerRadius = prop
|
||||||
}
|
}
|
||||||
|
|
||||||
Prop("minHeight") { view: BottomSheetView, prop: Float ->
|
Prop("minHeight") { view: BottomSheetView, prop: Float ->
|
||||||
@@ -37,12 +46,8 @@ class BottomSheetModule : Module() {
|
|||||||
view.maxHeight = prop
|
view.maxHeight = prop
|
||||||
}
|
}
|
||||||
|
|
||||||
Prop("cornerRadius") { view: BottomSheetView, prop: Float ->
|
Prop("preventDismiss") { view: BottomSheetView, prop: Boolean ->
|
||||||
view.sheetState.value.cornerRadius = prop
|
view.preventDismiss = prop
|
||||||
}
|
|
||||||
|
|
||||||
Prop("containerBackgroundColor") { view: BottomSheetView, prop: String ->
|
|
||||||
view.sheetState.value.containerBackgroundColor = Color.parseColor(prop)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Prop("preventExpansion") { view: BottomSheetView, prop: Boolean ->
|
Prop("preventExpansion") { view: BottomSheetView, prop: Boolean ->
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ class SheetView: ExpoView, UISheetPresentationControllerDelegate {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.present(contentHeight: innerView.subviews[0].frame.size.height)
|
self.present()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func destroy() {
|
private func destroy() {
|
||||||
@@ -109,9 +109,10 @@ class SheetView: ExpoView, UISheetPresentationControllerDelegate {
|
|||||||
|
|
||||||
// MARK: - Presentation
|
// MARK: - Presentation
|
||||||
|
|
||||||
func present(contentHeight: CGFloat) {
|
func present() {
|
||||||
guard !self.isOpen,
|
guard !self.isOpen,
|
||||||
let innerView = self.innerView,
|
let innerView = self.innerView,
|
||||||
|
let contentHeight = innerView.subviews.first?.frame.height,
|
||||||
let rvc = self.reactViewController() else {
|
let rvc = self.reactViewController() else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -135,7 +136,7 @@ class SheetView: ExpoView, UISheetPresentationControllerDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func updateLayout() {
|
func updateLayout() {
|
||||||
if let contentHeight = self.innerView?.subviews[0].frame.size.height {
|
if let contentHeight = self.innerView?.subviews.first?.frame.size.height {
|
||||||
self.sheetVc?.updateDetents(contentHeight: self.clampHeight(contentHeight),
|
self.sheetVc?.updateDetents(contentHeight: self.clampHeight(contentHeight),
|
||||||
preventExpansion: self.preventExpansion)
|
preventExpansion: self.preventExpansion)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user