fix: Fixed issue on Android where pressing backspace in Super notes would delete characters on both side of the cursor (#2336)
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
package com.standardnotes;
|
||||
|
||||
import com.reactnativecommunity.webview.RNCWebViewManager;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
import android.view.inputmethod.InputConnectionWrapper;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputConnection;
|
||||
import android.webkit.WebView;
|
||||
|
||||
@ReactModule(name = CustomWebViewManager.REACT_CLASS)
|
||||
public class CustomWebViewManager extends RNCWebViewManager {
|
||||
/* This name must match what we’re referring to in JS */
|
||||
protected static final String REACT_CLASS = "CustomWebView";
|
||||
|
||||
protected static class CustomWebViewClient extends RNCWebViewClient {}
|
||||
|
||||
protected static class CustomWebView extends RNCWebView {
|
||||
public CustomWebView(ThemedReactContext reactContext) {
|
||||
super(reactContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
|
||||
InputConnection con = super.onCreateInputConnection(outAttrs);
|
||||
if (con == null) {
|
||||
return null;
|
||||
}
|
||||
return new CustomInputConnection(con, true);
|
||||
}
|
||||
|
||||
private class CustomInputConnection extends InputConnectionWrapper {
|
||||
public CustomInputConnection(InputConnection target, boolean mutable) {
|
||||
super(target, mutable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sendKeyEvent(KeyEvent event) {
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
|
||||
// Un-comment if you wish to cancel the backspace:
|
||||
// return false;
|
||||
}
|
||||
return super.sendKeyEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteSurroundingText(int beforeLength, int afterLength) {
|
||||
// magic: in latest Android, deleteSurroundingText(1, 0) will be called for backspace
|
||||
if (beforeLength == 1 && afterLength == 0) {
|
||||
// backspace
|
||||
return sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))
|
||||
&& sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));
|
||||
}
|
||||
return super.deleteSurroundingText(beforeLength, afterLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RNCWebView createRNCWebViewInstance(ThemedReactContext reactContext) {
|
||||
return new CustomWebView(reactContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return REACT_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addEventEmitters(ThemedReactContext reactContext, WebView view) {
|
||||
view.setWebViewClient(new CustomWebViewClient());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.standardnotes;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
|
||||
public class CustomWebViewPackage implements ReactPackage {
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
||||
return Arrays.<ViewManager>asList(new CustomWebViewManager());
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,7 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||
|
||||
packages.add(new Fido2ApiPackage());
|
||||
packages.add(new CustomWebViewPackage());
|
||||
|
||||
return packages;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
import { ReactNativeToWebEvent } from '@standardnotes/snjs'
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { Button, Keyboard, Platform, Text, View } from 'react-native'
|
||||
import { Button, Keyboard, Platform, requireNativeComponent, Text, View } from 'react-native'
|
||||
import VersionInfo from 'react-native-version-info'
|
||||
import { WebView, WebViewMessageEvent } from 'react-native-webview'
|
||||
import { OnShouldStartLoadWithRequest } from 'react-native-webview/lib/WebViewTypes'
|
||||
import { NativeWebViewAndroid, OnShouldStartLoadWithRequest } from 'react-native-webview/lib/WebViewTypes'
|
||||
import { AndroidBackHandlerService } from './AndroidBackHandlerService'
|
||||
import { AppStateObserverService } from './AppStateObserverService'
|
||||
import { ColorSchemeObserverService } from './ColorSchemeObserverService'
|
||||
import { MobileDevice, MobileDeviceEvent } from './Lib/MobileDevice'
|
||||
import { IsDev } from './Lib/Utils'
|
||||
|
||||
const CustomWebView: NativeWebViewAndroid = requireNativeComponent('CustomWebView')
|
||||
|
||||
const LoggingEnabled = IsDev
|
||||
|
||||
export const MobileWebAppContainer = () => {
|
||||
@@ -354,6 +356,12 @@ const MobileWebAppContents = ({ destroyAndReload }: { destroyAndReload: () => vo
|
||||
* This is needed to prevent the keyboard from pushing the webview up and down when it appears and disappears.
|
||||
*/
|
||||
scrollEnabled={false}
|
||||
overScrollMode="never"
|
||||
nativeConfig={Platform.select({
|
||||
android: {
|
||||
component: CustomWebView,
|
||||
},
|
||||
})}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user