chore: convert `RNSelectableTextInput` to Kotlin (#18320)
### Summary This commit adds `Kotlin` plugin to native module `react-native-status` and converts these files to `Kotlin` : - `modules/react-native-status/android/src/main/java/im/status/ethereum/module/RNSelectableTextInputViewManager.java` - `modules/react-native-status/android/src/main/java/im/status/ethereum/module/RNSelectableTextInputModule.java` ### Platforms - Android
This commit is contained in:
parent
85c928f862
commit
d64508a74a
|
@ -1,4 +1,5 @@
|
||||||
apply plugin: 'com.android.library'
|
apply plugin: 'com.android.library'
|
||||||
|
apply plugin: "org.jetbrains.kotlin.android"
|
||||||
|
|
||||||
def getStatusGoSHA1 = { ->
|
def getStatusGoSHA1 = { ->
|
||||||
def statusgoOverridePath = System.getenv("STATUS_GO_SRC_OVERRIDE")
|
def statusgoOverridePath = System.getenv("STATUS_GO_SRC_OVERRIDE")
|
||||||
|
|
|
@ -1,78 +0,0 @@
|
||||||
package im.status.ethereum.module;
|
|
||||||
|
|
||||||
import android.view.ActionMode;
|
|
||||||
import com.facebook.react.bridge.ReactApplicationContext;
|
|
||||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
||||||
import com.facebook.react.bridge.ReactMethod;
|
|
||||||
import com.facebook.react.uimanager.NativeViewHierarchyManager;
|
|
||||||
import com.facebook.react.uimanager.UIBlock;
|
|
||||||
import com.facebook.react.uimanager.UIManagerModule;
|
|
||||||
import com.facebook.react.views.textinput.ReactEditText;
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
class RNSelectableTextInputModule extends ReactContextBaseJavaModule {
|
|
||||||
|
|
||||||
private ActionMode lastActionMode;
|
|
||||||
|
|
||||||
public RNSelectableTextInputModule(ReactApplicationContext reactContext) {
|
|
||||||
super(reactContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "RNSelectableTextInputManager";
|
|
||||||
}
|
|
||||||
|
|
||||||
@ReactMethod
|
|
||||||
public void setupMenuItems(final Integer selectableTextViewReactTag, final Integer textInputReactTag) {
|
|
||||||
ReactApplicationContext reactContext = this.getReactApplicationContext();
|
|
||||||
UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class);
|
|
||||||
uiManager.addUIBlock(new UIBlock() {
|
|
||||||
public void execute (NativeViewHierarchyManager nvhm) {
|
|
||||||
RNSelectableTextInputViewManager rnSelectableTextManager = (RNSelectableTextInputViewManager) nvhm.resolveViewManager(selectableTextViewReactTag);
|
|
||||||
ReactEditText reactTextView = (ReactEditText) nvhm.resolveView(textInputReactTag);
|
|
||||||
rnSelectableTextManager.registerSelectionListener(reactTextView);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@ReactMethod
|
|
||||||
public void startActionMode(final Integer textInputReactTag) {
|
|
||||||
ReactApplicationContext reactContext = this.getReactApplicationContext();
|
|
||||||
UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class);
|
|
||||||
uiManager.addUIBlock(new UIBlock() {
|
|
||||||
public void execute (NativeViewHierarchyManager nvhm) {
|
|
||||||
ReactEditText reactTextView = (ReactEditText) nvhm.resolveView(textInputReactTag);
|
|
||||||
lastActionMode = reactTextView.startActionMode(reactTextView.getCustomSelectionActionModeCallback(), ActionMode.TYPE_FLOATING);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@ReactMethod
|
|
||||||
public void hideLastActionMode(){
|
|
||||||
ReactApplicationContext reactContext = this.getReactApplicationContext();
|
|
||||||
UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class);
|
|
||||||
uiManager.addUIBlock(new UIBlock() {
|
|
||||||
public void execute (NativeViewHierarchyManager nvhm) {
|
|
||||||
if(lastActionMode!=null){
|
|
||||||
lastActionMode.finish();
|
|
||||||
lastActionMode = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@ReactMethod
|
|
||||||
public void setSelection(final Integer textInputReactTag, final Integer start, final Integer end){
|
|
||||||
ReactApplicationContext reactContext = this.getReactApplicationContext();
|
|
||||||
UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class);
|
|
||||||
uiManager.addUIBlock(new UIBlock() {
|
|
||||||
public void execute (NativeViewHierarchyManager nvhm) {
|
|
||||||
ReactEditText reactTextView = (ReactEditText) nvhm.resolveView(textInputReactTag);
|
|
||||||
reactTextView.setSelection(start, end);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
package im.status.ethereum.module
|
||||||
|
|
||||||
|
import android.view.ActionMode
|
||||||
|
import com.facebook.react.bridge.ReactApplicationContext
|
||||||
|
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
||||||
|
import com.facebook.react.bridge.ReactMethod
|
||||||
|
import com.facebook.react.uimanager.NativeViewHierarchyManager
|
||||||
|
import com.facebook.react.uimanager.UIBlock
|
||||||
|
import com.facebook.react.uimanager.UIManagerModule
|
||||||
|
import com.facebook.react.views.textinput.ReactEditText
|
||||||
|
|
||||||
|
class RNSelectableTextInputModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
|
||||||
|
|
||||||
|
private var lastActionMode: ActionMode? = null
|
||||||
|
|
||||||
|
override fun getName(): String {
|
||||||
|
return "RNSelectableTextInputManager"
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
fun setupMenuItems(selectableTextViewReactTag: Int?, textInputReactTag: Int?) {
|
||||||
|
val reactContext = reactApplicationContext
|
||||||
|
val uiManager = reactContext.getNativeModule(UIManagerModule::class.java)
|
||||||
|
selectableTextViewReactTag?.let { selectableTag ->
|
||||||
|
textInputReactTag?.let { inputTag ->
|
||||||
|
uiManager?.addUIBlock(UIBlock { nvhm: NativeViewHierarchyManager ->
|
||||||
|
val rnSelectableTextManager = nvhm.resolveViewManager(selectableTag) as RNSelectableTextInputViewManager
|
||||||
|
val reactTextView = nvhm.resolveView(inputTag) as ReactEditText
|
||||||
|
rnSelectableTextManager.registerSelectionListener(reactTextView)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
fun startActionMode(textInputReactTag: Int?) {
|
||||||
|
val reactContext = reactApplicationContext
|
||||||
|
val uiManager = reactContext.getNativeModule(UIManagerModule::class.java)
|
||||||
|
textInputReactTag?.let { inputTag ->
|
||||||
|
uiManager?.addUIBlock(UIBlock { nvhm: NativeViewHierarchyManager ->
|
||||||
|
val reactTextView = nvhm.resolveView(inputTag) as ReactEditText
|
||||||
|
lastActionMode = reactTextView.startActionMode(reactTextView.customSelectionActionModeCallback, ActionMode.TYPE_FLOATING)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
fun hideLastActionMode() {
|
||||||
|
val reactContext = reactApplicationContext
|
||||||
|
val uiManager = reactContext.getNativeModule(UIManagerModule::class.java)
|
||||||
|
uiManager?.addUIBlock(UIBlock { _ ->
|
||||||
|
lastActionMode?.finish()
|
||||||
|
lastActionMode = null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
fun setSelection(textInputReactTag: Int?, start: Int?, end: Int?) {
|
||||||
|
val reactContext = reactApplicationContext
|
||||||
|
val uiManager = reactContext.getNativeModule(UIManagerModule::class.java)
|
||||||
|
textInputReactTag?.let { inputTag ->
|
||||||
|
start?.let { s ->
|
||||||
|
end?.let { e ->
|
||||||
|
uiManager?.addUIBlock(UIBlock { nvhm: NativeViewHierarchyManager ->
|
||||||
|
val reactTextView = nvhm.resolveView(inputTag) as ReactEditText
|
||||||
|
reactTextView.setSelection(s, e)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,102 +0,0 @@
|
||||||
package im.status.ethereum.module;
|
|
||||||
|
|
||||||
import android.view.ActionMode;
|
|
||||||
import android.view.ActionMode.Callback;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import com.facebook.react.bridge.Arguments;
|
|
||||||
import com.facebook.react.bridge.ReactContext;
|
|
||||||
import com.facebook.react.bridge.ReadableArray;
|
|
||||||
import com.facebook.react.bridge.WritableMap;
|
|
||||||
import com.facebook.react.common.MapBuilder;
|
|
||||||
import com.facebook.react.uimanager.ThemedReactContext;
|
|
||||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
|
||||||
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
|
||||||
import com.facebook.react.views.textinput.ReactEditText;
|
|
||||||
import com.facebook.react.views.view.ReactViewGroup;
|
|
||||||
import com.facebook.react.views.view.ReactViewManager;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class RNSelectableTextInputViewManager extends ReactViewManager {
|
|
||||||
public static final String REACT_CLASS = "RNSelectableTextInput";
|
|
||||||
private String[] _menuItems = new String[0];
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return REACT_CLASS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReactViewGroup createViewInstance(ThemedReactContext context) {
|
|
||||||
return new ReactViewGroup(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ReactProp(name = "menuItems")
|
|
||||||
public void setMenuItems(ReactViewGroup reactViewGroup, ReadableArray items) {
|
|
||||||
if(items != null) {
|
|
||||||
List<String> result = new ArrayList<String>(items.size());
|
|
||||||
for (int i = 0; i < items.size(); i++) {
|
|
||||||
result.add(items.getString(i));
|
|
||||||
}
|
|
||||||
this._menuItems = result.toArray(new String[items.size()]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerSelectionListener(final ReactEditText view) {
|
|
||||||
view.setCustomSelectionActionModeCallback(new Callback() {
|
|
||||||
@Override
|
|
||||||
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
|
||||||
menu.clear();
|
|
||||||
for (int i = 0; i < _menuItems.length; i++) {
|
|
||||||
menu.add(0, i, 0, _menuItems[i]);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroyActionMode(ActionMode mode) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
|
||||||
int selectionStart = view.getSelectionStart();
|
|
||||||
int selectionEnd = view.getSelectionEnd();
|
|
||||||
String selectedText = view.getText().toString().substring(selectionStart, selectionEnd);
|
|
||||||
|
|
||||||
// Dispatch event
|
|
||||||
onSelectNativeEvent(view, item.getItemId(), selectedText, selectionStart, selectionEnd);
|
|
||||||
|
|
||||||
mode.finish();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onSelectNativeEvent(ReactEditText view, int eventType, String content, int selectionStart, int selectionEnd) {
|
|
||||||
WritableMap event = Arguments.createMap();
|
|
||||||
event.putInt("eventType", eventType);
|
|
||||||
event.putString("content", content);
|
|
||||||
event.putInt("selectionStart", selectionStart);
|
|
||||||
event.putInt("selectionEnd", selectionEnd);
|
|
||||||
|
|
||||||
// Dispatch
|
|
||||||
ReactContext reactContext = (ReactContext) view.getContext();
|
|
||||||
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(view.getId(), "topSelection", event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map getExportedCustomDirectEventTypeConstants() {
|
|
||||||
return MapBuilder.builder()
|
|
||||||
.put("topSelection", MapBuilder.of("registrationName","onSelection"))
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
package im.status.ethereum.module
|
||||||
|
|
||||||
|
import android.view.ActionMode
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuItem
|
||||||
|
import com.facebook.react.bridge.Arguments
|
||||||
|
import com.facebook.react.bridge.ReactContext
|
||||||
|
import com.facebook.react.bridge.ReadableArray
|
||||||
|
import com.facebook.react.bridge.WritableMap
|
||||||
|
import com.facebook.react.common.MapBuilder
|
||||||
|
import com.facebook.react.uimanager.ThemedReactContext
|
||||||
|
import com.facebook.react.uimanager.annotations.ReactProp
|
||||||
|
import com.facebook.react.uimanager.events.RCTEventEmitter
|
||||||
|
import com.facebook.react.views.textinput.ReactEditText
|
||||||
|
import com.facebook.react.views.view.ReactViewGroup
|
||||||
|
import com.facebook.react.views.view.ReactViewManager
|
||||||
|
|
||||||
|
class RNSelectableTextInputViewManager : ReactViewManager() {
|
||||||
|
companion object {
|
||||||
|
const val REACT_CLASS = "RNSelectableTextInput"
|
||||||
|
}
|
||||||
|
|
||||||
|
private var _menuItems = arrayOf<String>()
|
||||||
|
|
||||||
|
override fun getName(): String {
|
||||||
|
return REACT_CLASS
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createViewInstance(context: ThemedReactContext): ReactViewGroup {
|
||||||
|
return ReactViewGroup(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "menuItems")
|
||||||
|
fun setMenuItems(reactViewGroup: ReactViewGroup, items: ReadableArray?) {
|
||||||
|
_menuItems = items?.let {
|
||||||
|
Array(items.size()) { i -> items.getString(i) }
|
||||||
|
} ?: arrayOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun registerSelectionListener(view: ReactEditText) {
|
||||||
|
view.customSelectionActionModeCallback = object : ActionMode.Callback {
|
||||||
|
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||||
|
menu.clear()
|
||||||
|
_menuItems.forEachIndexed { i, item ->
|
||||||
|
menu.add(0, i, 0, item)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyActionMode(mode: ActionMode) {}
|
||||||
|
|
||||||
|
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||||
|
val selectionStart = view.selectionStart
|
||||||
|
val selectionEnd = view.selectionEnd
|
||||||
|
val selectedText = view.text.toString().substring(selectionStart, selectionEnd)
|
||||||
|
|
||||||
|
onSelectNativeEvent(view, item.itemId, selectedText, selectionStart, selectionEnd)
|
||||||
|
mode.finish()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onSelectNativeEvent(view: ReactEditText, eventType: Int, content: String, selectionStart: Int, selectionEnd: Int) {
|
||||||
|
val event: WritableMap = Arguments.createMap().apply {
|
||||||
|
putInt("eventType", eventType)
|
||||||
|
putString("content", content)
|
||||||
|
putInt("selectionStart", selectionStart)
|
||||||
|
putInt("selectionEnd", selectionEnd)
|
||||||
|
}
|
||||||
|
|
||||||
|
val reactContext = view.context as ReactContext
|
||||||
|
reactContext.getJSModule(RCTEventEmitter::class.java).receiveEvent(view.id, "topSelection", event)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getExportedCustomDirectEventTypeConstants(): Map<String, Any>? {
|
||||||
|
return MapBuilder.builder<String, Any>()
|
||||||
|
.put("topSelection", MapBuilder.of("registrationName", "onSelection"))
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue