package expo.community.modules.emojisheet import android.annotation.SuppressLint import android.content.Context import android.os.Handler import android.os.Looper import expo.modules.kotlin.AppContext import expo.modules.kotlin.viewevent.EventDispatcher import expo.modules.kotlin.views.ExpoView @SuppressLint("ViewConstructor") class EmojiSheetContentView( context: Context, appContext: AppContext ) : ExpoView(context, appContext) { private val onEmojiSelected by EventDispatcher() private val onDismiss by EventDispatcher() private val onOpen by EventDispatcher() private val pickerView = EmojiSheetUIView(context) init { pickerView.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT) pickerView.setSheetExpanded(true) pickerView.onEmojiSelected = { data -> onEmojiSelected(data) } addView(pickerView) pickerView.loadDataAsync() } private var hasOpened = false private val mainHandler = Handler(Looper.getMainLooper()) // A transient detach (layout reparenting, brief clipping) is followed by a // reattach on the same or next loop. Defer the dismiss one loop and skip it if // the view came back, so onDismiss fires only when the view stays detached. private val emitDismissIfStillDetached = Runnable { if (!isAttachedToWindow) { hasOpened = false onDismiss(mapOf()) } } override fun onAttachedToWindow() { super.onAttachedToWindow() mainHandler.removeCallbacks(emitDismissIfStillDetached) if (!hasOpened) { hasOpened = true onOpen(mapOf()) } } override fun onDetachedFromWindow() { super.onDetachedFromWindow() mainHandler.post(emitDismissIfStillDetached) } fun applyConfiguration() { pickerView.applyConfiguration() } fun updateTheme(theme: String) { pickerView.updateTheme(theme) } fun updateCategoryBarPosition(position: String) { pickerView.categoryBarPosition = position pickerView.applyConfiguration() } fun updateLayoutDirection(direction: String) { pickerView.layoutDirectionProp = direction } fun updateColumns(columns: Int) { pickerView.columns = columns pickerView.applyConfiguration() } fun updateEmojiSize(size: Float) { pickerView.emojiSize = size pickerView.applyConfiguration() } fun updateRecentLimit(limit: Int) { pickerView.recentLimit = limit pickerView.rebuildAfterPropChange() } fun updateShowSearch(show: Boolean) { pickerView.showSearch = show pickerView.applyConfiguration() } fun updateShowRecents(show: Boolean) { pickerView.showRecents = show pickerView.rebuildAfterPropChange() } fun updateEnableSkinTones(enable: Boolean) { pickerView.enableSkinTones = enable } fun updateEnableHaptics(enable: Boolean) { pickerView.enableHaptics = enable } fun updateEnableAnimations(enable: Boolean) { pickerView.enableAnimations = enable } fun updateSearchPlaceholder(text: String) { pickerView.searchPlaceholder = text } fun updateNoResultsText(text: String) { pickerView.noResultsText = text } fun updateCategoryNames(names: Map) { pickerView.categoryNames = names pickerView.rebuildAfterPropChange() } fun updateExcludeEmojis(ids: List) { pickerView.excludeEmojis = ids.toSet() pickerView.rebuildAfterPropChange() } }