package com.swmansion.rnscreens.gamma.stack.header.config import android.view.View import com.facebook.react.bridge.JSApplicationIllegalArgumentException import com.facebook.react.bridge.ReadableMap import com.facebook.react.module.annotations.ReactModule import com.facebook.react.uimanager.ReactStylesDiffMap import com.facebook.react.uimanager.StateWrapper import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.ViewGroupManager import com.facebook.react.uimanager.ViewManagerDelegate import com.facebook.react.viewmanagers.RNSStackHeaderConfigAndroidManagerDelegate import com.facebook.react.viewmanagers.RNSStackHeaderConfigAndroidManagerInterface import com.swmansion.rnscreens.gamma.stack.header.subview.StackHeaderSubview @ReactModule(name = StackHeaderConfigViewManager.REACT_CLASS) open class StackHeaderConfigViewManager : ViewGroupManager(), RNSStackHeaderConfigAndroidManagerInterface { private val delegate: ViewManagerDelegate init { delegate = RNSStackHeaderConfigAndroidManagerDelegate(this) } override fun getName() = REACT_CLASS override fun createViewInstance(reactContext: ThemedReactContext) = StackHeaderConfig(reactContext) override fun getDelegate(): ViewManagerDelegate = delegate /** * Subviews need to be positioned by native layout from Toolbar and CollapsingToolbarLayout. * Even with this option enabled, we receive dimensions calculated by Yoga via onMeasure. */ override fun needsCustomLayoutForChildren() = true override fun addView( parent: StackHeaderConfig, child: View, index: Int, ) { require(child is StackHeaderSubview) { "[RNScreens] StackHeaderConfig can only have children of type StackHeaderSubview. Received $child instead." } parent.addConfigSubview(child) } override fun removeView( parent: StackHeaderConfig, view: View, ) { require(view is StackHeaderSubview) { "[RNScreens] StackHeaderConfig can only have children of type StackHeaderSubview. Attempted to remove $view instead." } parent.removeConfigSubview(view) } override fun removeViewAt( parent: StackHeaderConfig, index: Int, ) { parent.removeConfigSubviewAt(index) } override fun removeAllViews(parent: StackHeaderConfig) { parent.removeAllConfigSubviews() } override fun getChildCount(parent: StackHeaderConfig): Int = parent.configSubviewsCount override fun getChildAt( parent: StackHeaderConfig, index: Int, ): View? = parent.getConfigSubviewAt(index) override fun updateState( view: StackHeaderConfig, props: ReactStylesDiffMap?, stateWrapper: StateWrapper?, ): Any? { view.stateWrapper = stateWrapper return super.updateState(view, props, stateWrapper) } override fun onAfterUpdateTransaction(view: StackHeaderConfig) { super.onAfterUpdateTransaction(view) view.resolveBackButtonIconIfNeeded() view.notifyConfigChanged() } override fun setType( view: StackHeaderConfig, value: String?, ) { view.type = when (value) { "small" -> StackHeaderType.SMALL "medium" -> StackHeaderType.MEDIUM "large" -> StackHeaderType.LARGE else -> throw JSApplicationIllegalArgumentException("[RNScreens] Invalid StackHeaderConfig type: $value.") } } override fun setTitle( view: StackHeaderConfig, value: String?, ) { view.title = value ?: "" } override fun setHidden( view: StackHeaderConfig, value: Boolean, ) { view.hidden = value } override fun setTransparent( view: StackHeaderConfig, value: Boolean, ) { view.transparent = value } override fun setBackButtonHidden( view: StackHeaderConfig, value: Boolean, ) { view.backButtonHidden = value } override fun setBackButtonTintColor( view: StackHeaderConfig, value: Int?, ) { view.backButtonTintColor = value } override fun setBackButtonDrawableIconResourceName( view: StackHeaderConfig, value: String?, ) { view.backButtonDrawableIconResourceName = value } override fun setBackButtonImageIconResource( view: StackHeaderConfig, value: ReadableMap?, ) { view.backButtonImageIconUri = value?.getString("uri") } override fun setScrollFlagScroll( view: StackHeaderConfig, value: Boolean, ) { view.scrollFlagScroll = value } override fun setScrollFlagEnterAlways( view: StackHeaderConfig, value: Boolean, ) { view.scrollFlagEnterAlways = value } override fun setScrollFlagEnterAlwaysCollapsed( view: StackHeaderConfig, value: Boolean, ) { view.scrollFlagEnterAlwaysCollapsed = value } override fun setScrollFlagExitUntilCollapsed( view: StackHeaderConfig, value: Boolean, ) { view.scrollFlagExitUntilCollapsed = value } override fun setScrollFlagSnap( view: StackHeaderConfig, value: Boolean, ) { view.scrollFlagSnap = value } companion object { const val REACT_CLASS = "RNSStackHeaderConfigAndroid" } }