package com.reactnativetink.manager import android.view.Choreographer import android.view.View import android.view.ViewGroup import android.widget.FrameLayout import androidx.fragment.app.FragmentActivity import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.ReadableArray import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.ViewGroupManager import com.facebook.react.uimanager.annotations.ReactProp import com.facebook.react.uimanager.annotations.ReactPropGroup import com.reactnativetink.fragment.FinanceOverviewFragment class MoneyManagerViewManager(private val reactContext: ReactApplicationContext) : ViewGroupManager() { private var propWidth: Int? = null private var propHeight: Int? = null private var propClientId: String = "" private var propAccessToken: String = "" companion object { const val NAME = "MoneyManagerFinanceOverview" private const val COMMAND_CREATE = 1 } override fun getName(): String { return NAME } override fun createViewInstance(reactContext: ThemedReactContext): FrameLayout { return FrameLayout(reactContext) } override fun getCommandsMap(): Map { return mapOf("create" to COMMAND_CREATE) } override fun receiveCommand( root: FrameLayout, commandId: String, args: ReadableArray?, ) { super.receiveCommand(root, commandId, args) val reactNativeViewId = requireNotNull(args).getInt(0) when (commandId.toInt()) { COMMAND_CREATE -> createFragment(root, reactNativeViewId) } } @ReactPropGroup(names = ["width", "height"], customType = "Style") fun setStyle( view: FrameLayout, index: Int, value: Int, ) { if (index == 0) propWidth = value if (index == 1) propHeight = value } @ReactProp(name = "clientId") fun setClientId( view: FrameLayout, clientId: String, ) { propClientId = clientId } @ReactProp(name = "accessToken") fun setAccessToken( view: FrameLayout, accessToken: String, ) { propAccessToken = accessToken } private fun createFragment( frameLayout: FrameLayout, reactNativeViewId: Int, ) { val parentView = frameLayout.findViewById(reactNativeViewId) setupLayout(parentView) val financeOverviewFragment = FinanceOverviewFragment(reactContext, propClientId, propAccessToken) val activity = reactContext.currentActivity as FragmentActivity activity.supportFragmentManager .beginTransaction() .replace(reactNativeViewId, financeOverviewFragment, reactNativeViewId.toString()) .commit() } private fun setupLayout(view: View) { Choreographer.getInstance().postFrameCallback( object : Choreographer.FrameCallback { override fun doFrame(frameTimeNanos: Long) { manuallyLayoutChildren(view) view.viewTreeObserver.dispatchOnGlobalLayout() Choreographer.getInstance().postFrameCallback(this) } }, ) } private fun manuallyLayoutChildren(view: View) { // propWidth and propHeight coming from react-native props val width = requireNotNull(propWidth) val height = requireNotNull(propHeight) view.measure( View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY), ) view.layout(0, 0, width, height) } }