mirror of
https://github.com/status-im/status-mobile.git
synced 2025-02-23 13:58:43 +00:00
[#11216] Fix moving cursor after pressing mention suggestion on samsung device
This commit is contained in:
parent
b5f7a62b14
commit
22ca98b0f8
@ -19,6 +19,11 @@ import android.view.WindowManager;
|
||||
import android.webkit.CookieManager;
|
||||
import android.webkit.CookieSyncManager;
|
||||
import android.webkit.WebStorage;
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.EditText;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.Callback;
|
||||
@ -30,6 +35,9 @@ import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.uimanager.UIBlock;
|
||||
import com.facebook.react.uimanager.NativeViewHierarchyManager;
|
||||
|
||||
import statusgo.SignalHandler;
|
||||
import statusgo.Statusgo;
|
||||
@ -1386,5 +1394,24 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void resetKeyboardInputCursor(final int reactTagToReset, final int selection) {
|
||||
UIManagerModule uiManager = getReactApplicationContext().getNativeModule(UIManagerModule.class);
|
||||
uiManager.addUIBlock(new UIBlock() {
|
||||
@Override
|
||||
public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) {
|
||||
InputMethodManager imm = (InputMethodManager) getReactApplicationContext().getBaseContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (imm != null) {
|
||||
View viewToReset = nativeViewHierarchyManager.resolveView(reactTagToReset);
|
||||
imm.restartInput(viewToReset);
|
||||
try {
|
||||
EditText textView = (EditText) viewToReset;
|
||||
textView.setSelection(selection);
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
(def platform (.-Platform ^js rn))
|
||||
|
||||
(def find-node-handle (.-findNodeHandle ^js rn))
|
||||
|
||||
(def view (reagent/adapt-react-class (.-View ^js rn)))
|
||||
(def image (reagent/adapt-react-class (.-Image rn)))
|
||||
(def text (reagent/adapt-react-class (.-Text ^js rn)))
|
||||
|
@ -30,16 +30,24 @@
|
||||
{:db (assoc-in db [:chat/inputs current-chat-id :input-text] (text->emoji new-input))})
|
||||
|
||||
(fx/defn select-mention
|
||||
[{:keys [db] :as cofx} {:keys [alias name searched-text match] :as user}]
|
||||
[{:keys [db] :as cofx} text-input-ref {:keys [alias name searched-text match] :as user}]
|
||||
(let [chat-id (:current-chat-id db)
|
||||
new-text (mentions/new-input-text-with-mention cofx user)
|
||||
at-sign-idx (get-in db [:chats chat-id :mentions :at-sign-idx])]
|
||||
at-sign-idx (get-in db [:chats chat-id :mentions :at-sign-idx])
|
||||
cursor (+ at-sign-idx (count name) 2)]
|
||||
(fx/merge
|
||||
cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:chats/cursor chat-id] (+ at-sign-idx (count name) 2))
|
||||
(assoc-in [:chats/cursor chat-id] cursor)
|
||||
(assoc-in [:chats/mention-suggestions chat-id] nil))}
|
||||
(set-chat-input-text new-text)
|
||||
;; NOTE(rasom): Some keyboards do not react on selection property passed to
|
||||
;; text input (specifically Samsung keyboard with predictive text set on).
|
||||
;; In this case, if the user continues typing after the programmatic change,
|
||||
;; the new text is added to the last known cursor position before
|
||||
;; programmatic change. By calling `reset-text-input-cursor` we force the
|
||||
;; keyboard's cursor position to be changed before the next input.
|
||||
(mentions/reset-text-input-cursor text-input-ref cursor)
|
||||
;; NOTE(roman): on-text-input event is not dispatched when we change input
|
||||
;; programmatically, so we have to call `on-text-input` manually
|
||||
(mentions/on-text-input
|
||||
|
@ -1,10 +1,14 @@
|
||||
(ns status-im.chat.models.mentions
|
||||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.contact.db :as contact.db]
|
||||
[status-im.utils.platform :as platform]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.utils.utils :as utils]))
|
||||
[status-im.utils.utils :as utils]
|
||||
[status-im.native-module.core :as status]
|
||||
[quo.react-native :as rn]
|
||||
[quo.react :as react]))
|
||||
|
||||
(def at-sign "@")
|
||||
|
||||
@ -450,3 +454,14 @@
|
||||
(calculate-suggestions mentionable-users))
|
||||
(clear-suggestions cofx)))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::reset-text-input-cursor
|
||||
(fn [[ref cursor]]
|
||||
(when ref
|
||||
(status/reset-keyboard-input
|
||||
(rn/find-node-handle (react/current-ref ref))
|
||||
cursor))))
|
||||
|
||||
(fx/defn reset-text-input-cursor
|
||||
[_ ref cursor]
|
||||
{::reset-text-input-cursor [ref cursor]})
|
||||
|
@ -506,8 +506,8 @@
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:chat.ui/select-mention
|
||||
(fn [cofx [_ mention]]
|
||||
(chat.input/select-mention cofx mention)))
|
||||
(fn [cofx [_ text-input-ref mention]]
|
||||
(chat.input/select-mention cofx text-input-ref mention)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:chat.ui/set-chat-input-text
|
||||
|
@ -380,3 +380,8 @@
|
||||
(defn deactivate-keep-awake []
|
||||
(log/debug "[native-module] deactivateKeepAwake")
|
||||
(.deactivateKeepAwake ^js (status)))
|
||||
|
||||
(defn reset-keyboard-input [input selection]
|
||||
(log/debug "[native-module] resetKeyboardInput")
|
||||
(when platform/android?
|
||||
(.resetKeyboardInputCursor ^js (status) input selection)))
|
||||
|
@ -197,7 +197,7 @@
|
||||
input-with-mentions)]]))
|
||||
|
||||
(defn mention-item
|
||||
[[_ {:keys [identicon alias name nickname] :as user}]]
|
||||
[text-input-ref [_ {:keys [identicon alias name nickname] :as user}]]
|
||||
(let [ens-name? (not= alias name)]
|
||||
[list-item/list-item
|
||||
(cond-> {:icon
|
||||
@ -233,14 +233,14 @@
|
||||
:title-text-weight :medium
|
||||
:on-press
|
||||
(fn []
|
||||
(re-frame/dispatch [:chat.ui/select-mention user]))}
|
||||
(re-frame/dispatch [:chat.ui/select-mention text-input-ref user]))}
|
||||
|
||||
ens-name?
|
||||
(assoc :subtitle alias))]))
|
||||
|
||||
(def chat-input-height (reagent/atom nil))
|
||||
|
||||
(defn autocomplete-mentions []
|
||||
(defn autocomplete-mentions [text-input-ref]
|
||||
(let [suggestions @(re-frame/subscribe [:chat/mention-suggestions])]
|
||||
(when (and (seq suggestions) @chat-input-height)
|
||||
(let [height (+ 16 (* 52 (min 4.5 (count suggestions))))]
|
||||
@ -254,7 +254,7 @@
|
||||
:header [rn/view {:style {:height 8}}]
|
||||
:data suggestions
|
||||
:key-fn first
|
||||
:render-fn #(mention-item %)}]]]))))
|
||||
:render-fn #(mention-item text-input-ref %)}]]]))))
|
||||
|
||||
(defn chat-input
|
||||
[{:keys [set-active-panel active-panel on-send-press reply
|
||||
|
@ -301,7 +301,7 @@
|
||||
;; :always doesn't work and keyboard is hidden on pressing suggestion.
|
||||
;; Scrolling of suggestions doesn't work neither in this case.
|
||||
(when platform/android?
|
||||
[components/autocomplete-mentions])
|
||||
[components/autocomplete-mentions text-input-ref])
|
||||
(when show-input?
|
||||
[accessory/view {:y position-y
|
||||
:pan-state pan-state
|
||||
|
Loading…
x
Reference in New Issue
Block a user