[#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.CookieManager;
|
||||||
import android.webkit.CookieSyncManager;
|
import android.webkit.CookieSyncManager;
|
||||||
import android.webkit.WebStorage;
|
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.Arguments;
|
||||||
import com.facebook.react.bridge.Callback;
|
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.ReadableArray;
|
||||||
import com.facebook.react.bridge.WritableMap;
|
import com.facebook.react.bridge.WritableMap;
|
||||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
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.SignalHandler;
|
||||||
import statusgo.Statusgo;
|
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 platform (.-Platform ^js rn))
|
||||||
|
|
||||||
|
(def find-node-handle (.-findNodeHandle ^js rn))
|
||||||
|
|
||||||
(def view (reagent/adapt-react-class (.-View ^js rn)))
|
(def view (reagent/adapt-react-class (.-View ^js rn)))
|
||||||
(def image (reagent/adapt-react-class (.-Image rn)))
|
(def image (reagent/adapt-react-class (.-Image rn)))
|
||||||
(def text (reagent/adapt-react-class (.-Text ^js 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))})
|
{:db (assoc-in db [:chat/inputs current-chat-id :input-text] (text->emoji new-input))})
|
||||||
|
|
||||||
(fx/defn select-mention
|
(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)
|
(let [chat-id (:current-chat-id db)
|
||||||
new-text (mentions/new-input-text-with-mention cofx user)
|
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
|
(fx/merge
|
||||||
cofx
|
cofx
|
||||||
{:db (-> db
|
{: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))}
|
(assoc-in [:chats/mention-suggestions chat-id] nil))}
|
||||||
(set-chat-input-text new-text)
|
(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
|
;; NOTE(roman): on-text-input event is not dispatched when we change input
|
||||||
;; programmatically, so we have to call `on-text-input` manually
|
;; programmatically, so we have to call `on-text-input` manually
|
||||||
(mentions/on-text-input
|
(mentions/on-text-input
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
(ns status-im.chat.models.mentions
|
(ns status-im.chat.models.mentions
|
||||||
(:require [clojure.string :as string]
|
(:require [clojure.string :as string]
|
||||||
|
[re-frame.core :as re-frame]
|
||||||
[status-im.utils.fx :as fx]
|
[status-im.utils.fx :as fx]
|
||||||
[status-im.contact.db :as contact.db]
|
[status-im.contact.db :as contact.db]
|
||||||
[status-im.utils.platform :as platform]
|
[status-im.utils.platform :as platform]
|
||||||
[taoensso.timbre :as log]
|
[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 "@")
|
(def at-sign "@")
|
||||||
|
|
||||||
|
@ -450,3 +454,14 @@
|
||||||
(calculate-suggestions mentionable-users))
|
(calculate-suggestions mentionable-users))
|
||||||
(clear-suggestions cofx)))))
|
(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
|
(handlers/register-handler-fx
|
||||||
:chat.ui/select-mention
|
:chat.ui/select-mention
|
||||||
(fn [cofx [_ mention]]
|
(fn [cofx [_ text-input-ref mention]]
|
||||||
(chat.input/select-mention cofx mention)))
|
(chat.input/select-mention cofx text-input-ref mention)))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:chat.ui/set-chat-input-text
|
:chat.ui/set-chat-input-text
|
||||||
|
|
|
@ -380,3 +380,8 @@
|
||||||
(defn deactivate-keep-awake []
|
(defn deactivate-keep-awake []
|
||||||
(log/debug "[native-module] deactivateKeepAwake")
|
(log/debug "[native-module] deactivateKeepAwake")
|
||||||
(.deactivateKeepAwake ^js (status)))
|
(.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)]]))
|
input-with-mentions)]]))
|
||||||
|
|
||||||
(defn mention-item
|
(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)]
|
(let [ens-name? (not= alias name)]
|
||||||
[list-item/list-item
|
[list-item/list-item
|
||||||
(cond-> {:icon
|
(cond-> {:icon
|
||||||
|
@ -233,14 +233,14 @@
|
||||||
:title-text-weight :medium
|
:title-text-weight :medium
|
||||||
:on-press
|
:on-press
|
||||||
(fn []
|
(fn []
|
||||||
(re-frame/dispatch [:chat.ui/select-mention user]))}
|
(re-frame/dispatch [:chat.ui/select-mention text-input-ref user]))}
|
||||||
|
|
||||||
ens-name?
|
ens-name?
|
||||||
(assoc :subtitle alias))]))
|
(assoc :subtitle alias))]))
|
||||||
|
|
||||||
(def chat-input-height (reagent/atom nil))
|
(def chat-input-height (reagent/atom nil))
|
||||||
|
|
||||||
(defn autocomplete-mentions []
|
(defn autocomplete-mentions [text-input-ref]
|
||||||
(let [suggestions @(re-frame/subscribe [:chat/mention-suggestions])]
|
(let [suggestions @(re-frame/subscribe [:chat/mention-suggestions])]
|
||||||
(when (and (seq suggestions) @chat-input-height)
|
(when (and (seq suggestions) @chat-input-height)
|
||||||
(let [height (+ 16 (* 52 (min 4.5 (count suggestions))))]
|
(let [height (+ 16 (* 52 (min 4.5 (count suggestions))))]
|
||||||
|
@ -254,7 +254,7 @@
|
||||||
:header [rn/view {:style {:height 8}}]
|
:header [rn/view {:style {:height 8}}]
|
||||||
:data suggestions
|
:data suggestions
|
||||||
:key-fn first
|
:key-fn first
|
||||||
:render-fn #(mention-item %)}]]]))))
|
:render-fn #(mention-item text-input-ref %)}]]]))))
|
||||||
|
|
||||||
(defn chat-input
|
(defn chat-input
|
||||||
[{:keys [set-active-panel active-panel on-send-press reply
|
[{: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.
|
;; :always doesn't work and keyboard is hidden on pressing suggestion.
|
||||||
;; Scrolling of suggestions doesn't work neither in this case.
|
;; Scrolling of suggestions doesn't work neither in this case.
|
||||||
(when platform/android?
|
(when platform/android?
|
||||||
[components/autocomplete-mentions])
|
[components/autocomplete-mentions text-input-ref])
|
||||||
(when show-input?
|
(when show-input?
|
||||||
[accessory/view {:y position-y
|
[accessory/view {:y position-y
|
||||||
:pan-state pan-state
|
:pan-state pan-state
|
||||||
|
|
Loading…
Reference in New Issue