<lambda>null1 package expo.interfaces.devmenu.items
2 
3 import android.os.Bundle
4 import android.view.KeyCharacterMap
5 import com.facebook.react.bridge.ReadableMap
6 
7 val keyCharacterMap: KeyCharacterMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD)
8 
9 // Android virtual keyboard only supports `SHIFT` as a modifier.
10 data class KeyCommand(val code: Int, val withShift: Boolean = false)
11 
12 /**
13  * An abstract representation of the single dev menu item.
14  */
15 sealed class DevMenuItem {
16   /**
17    * Represent how this item will be treated by the js.
18    *  1 - [DevMenuAction]
19    *  2 - [DevMenuGroup]
20    *  3 - [DevMenuScreen]
21    *  4 - [DevMenuLink]
22    *  5 - [DevMenuSelectionList]
23    */
24   abstract fun getExportedType(): Int
25 
26   open fun serialize() = Bundle().apply {
27     putInt("type", getExportedType())
28   }
29 }
30 
31 abstract class DevMenuScreenItem : DevMenuItem() {
32   var importance = DevMenuItemImportance.MEDIUM.value
33 }
34 
35 class DevMenuScreen(
36   val screenName: String,
37   itemsContainer: DevMenuDSLItemsContainerInterface = DevMenuItemsContainer()
<lambda>null38 ) : DevMenuItem(), DevMenuDSLItemsContainerInterface by itemsContainer {
39   override fun getExportedType() = 3
40 
41   override fun serialize() = super.serialize().apply {
42     putString("screenName", screenName)
43     putParcelableArray("items", serializeItems())
44   }
45 }
46 
47 class DevMenuGroup(
48   itemsContainer: DevMenuDSLItemsContainerInterface = DevMenuItemsContainer()
<lambda>null49 ) : DevMenuScreenItem(), DevMenuDSLItemsContainerInterface by itemsContainer {
50   override fun getExportedType() = 2
51 
52   override fun serialize() = super.serialize().apply {
53     putParcelableArray("items", serializeItems())
54   }
55 }
56 
57 class DevMenuAction(
58   actionId: String,
59   action: () -> Unit
60 ) : DevMenuScreenItem(), DevMenuCallableProvider {
61   val callable = DevMenuExportedAction(actionId, action)
62   var isAvailable: () -> Boolean
63     get() = callable.isAvailable
64     set(value) {
65       callable.isAvailable = value
66     }
<lambda>null67   var isEnabled = { false }
<lambda>null68   var label = { "" }
<lambda>null69   var detail = { "" }
<lambda>null70   var glyphName = { "" }
71 
72   var keyCommand: KeyCommand?
73     get() = callable.keyCommand
74     set(value) {
75       callable.registerKeyCommand(value)
76     }
77 
getExportedTypenull78   override fun getExportedType() = 1
79 
80   override fun serialize() = super.serialize().apply {
81     putString("actionId", callable.id)
82     putBoolean("isAvailable", isAvailable())
83     putBoolean("isEnabled", isEnabled())
84     putString("label", label())
85     putString("detail", detail())
86     putString("glyphName", glyphName())
87 
88     putBundle(
89       "keyCommand",
90       keyCommand?.let { keyCommand ->
91         Bundle().apply {
92           putString("input", keyCharacterMap.getDisplayLabel(keyCommand.code).toString())
93           putInt("modifiers", exportKeyCommandModifiers())
94         }
95       }
96     )
97   }
98 
exportKeyCommandModifiersnull99   private fun exportKeyCommandModifiers(): Int {
100     if (keyCommand?.withShift == true) {
101       return 1 shl 3
102     }
103     return 0
104   }
105 
registerCallablenull106   override fun registerCallable(): DevMenuExportedCallable {
107     return callable
108   }
109 }
110 
111 class DevMenuLink(private val target: String) : DevMenuScreenItem() {
<lambda>null112   var label = { "" }
<lambda>null113   var glyphName = { "" }
114 
getExportedTypenull115   override fun getExportedType() = 4
116 
117   override fun serialize() = super.serialize().apply {
118     putString("target", target)
119     putString("label", label())
120     putString("glyphName", glyphName())
121   }
122 }
123 
124 class DevMenuSelectionList : DevMenuScreenItem(), DevMenuCallableProvider {
125   class Item : DevMenuDataSourceItem {
126     class Tag {
<lambda>null127       var glyphName = { "" }
<lambda>null128       var text = { "" }
129 
<lambda>null130       internal fun serialize() = Bundle().apply {
131         putString("text", text())
132         putString("glyphName", glyphName())
133       }
134     }
135 
<lambda>null136     var title = { "" }
<lambda>null137     var tags: () -> List<Tag> = { emptyList() }
<lambda>null138     var warning: () -> String? = { null }
<lambda>null139     var isChecked = { false }
<lambda>null140     var onClickData: () -> Bundle? = { null }
141 
<lambda>null142     override fun serialize() = Bundle().apply {
143       putString("title", title())
144       putString("warning", warning())
145       putBoolean("isChecked", isChecked())
146       putBundle("onClickData", onClickData())
147       putParcelableArray("tags", tags().map { it.serialize() }.toTypedArray())
148     }
149   }
150 
151   private var items = ArrayList<Item>()
152   private var callable: DevMenuExportedFunction? = null
<lambda>null153   var dataSourceId: () -> String? = { null }
154 
addOnClicknull155   fun addOnClick(handler: (ReadableMap?) -> Unit) {
156     callable = DevMenuExportedFunction("expo-dev-menu.selection-list.#${ActionID++}", handler)
157   }
158 
addItemnull159   fun addItem(item: Item) {
160     items.add(item)
161   }
162 
getExportedTypenull163   override fun getExportedType(): Int {
164     return 5
165   }
166 
<lambda>null167   override fun serialize() = super.serialize().apply {
168     callable?.let {
169       putString("actionId", it.id)
170     }
171     putString("dataSourceId", dataSourceId())
172     putParcelableArray("items", items.map { it.serialize() }.toTypedArray())
173   }
174 
175   companion object {
176     private var ActionID = 0
177   }
178 
registerCallablenull179   override fun registerCallable(): DevMenuExportedCallable? {
180     return callable
181   }
182 }
183