mirror of
https://github.com/status-im/status-mobile.git
synced 2025-01-28 01:16:50 +00:00
Update mention suggestions on selection change
This commit is contained in:
parent
99755d08e9
commit
55278828e6
@ -158,5 +158,5 @@
|
|||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
(send-image)
|
(send-image)
|
||||||
(send-plain-text-message input-text-with-mentions current-chat-id)
|
(send-plain-text-message input-text-with-mentions current-chat-id)
|
||||||
(mentions/clear-suggestions)
|
(mentions/clear-mentions)
|
||||||
(mentions/clear-cursor))))
|
(mentions/clear-cursor))))
|
||||||
|
@ -151,26 +151,6 @@
|
|||||||
(defn check-mentions [cofx text]
|
(defn check-mentions [cofx text]
|
||||||
(replace-mentions text #(get-mentionable-users cofx)))
|
(replace-mentions text #(get-mentionable-users cofx)))
|
||||||
|
|
||||||
(defn check-for-at-sign
|
|
||||||
([text]
|
|
||||||
(check-for-at-sign text 0 0))
|
|
||||||
([text from cnt]
|
|
||||||
(if-let [idx (string/index-of text at-sign from)]
|
|
||||||
(recur text (inc idx) (inc cnt))
|
|
||||||
cnt)))
|
|
||||||
|
|
||||||
(defn at-sign-change [previous-text new-text]
|
|
||||||
(cond
|
|
||||||
(= "" previous-text)
|
|
||||||
(check-for-at-sign new-text)
|
|
||||||
|
|
||||||
(= "" new-text)
|
|
||||||
(- (check-for-at-sign previous-text))
|
|
||||||
|
|
||||||
:else
|
|
||||||
(- (check-for-at-sign new-text)
|
|
||||||
(check-for-at-sign previous-text))))
|
|
||||||
|
|
||||||
(defn get-at-sign-idxs
|
(defn get-at-sign-idxs
|
||||||
([text start]
|
([text start]
|
||||||
(get-at-sign-idxs text start 0 []))
|
(get-at-sign-idxs text start 0 []))
|
||||||
@ -296,11 +276,9 @@
|
|||||||
previous-text
|
previous-text
|
||||||
(subs previous-text start end))
|
(subs previous-text start end))
|
||||||
chat-id (:current-chat-id db)
|
chat-id (:current-chat-id db)
|
||||||
change (at-sign-change normalized-previous-text new-text)
|
|
||||||
previous-state (get-in db [:chats chat-id :mentions])
|
previous-state (get-in db [:chats chat-id :mentions])
|
||||||
text (get-in db [:chat/inputs chat-id :input-text])
|
text (get-in db [:chat/inputs chat-id :input-text])
|
||||||
new-state (-> previous-state
|
new-state (-> previous-state
|
||||||
(update :at-sign-counter + change)
|
|
||||||
(merge args)
|
(merge args)
|
||||||
(assoc :previous-text normalized-previous-text))
|
(assoc :previous-text normalized-previous-text))
|
||||||
old-at-idxs (:at-idxs new-state)
|
old-at-idxs (:at-idxs new-state)
|
||||||
@ -337,7 +315,7 @@
|
|||||||
[{:keys [db]} mentionable-users]
|
[{:keys [db]} mentionable-users]
|
||||||
(let [chat-id (:current-chat-id db)
|
(let [chat-id (:current-chat-id db)
|
||||||
text (get-in db [:chat/inputs chat-id :input-text])
|
text (get-in db [:chat/inputs chat-id :input-text])
|
||||||
{:keys [new-text at-sign-counter start end] :as state}
|
{:keys [new-text start end] :as state}
|
||||||
(get-in db [:chats chat-id :mentions])
|
(get-in db [:chats chat-id :mentions])
|
||||||
new-at-idxs (check-idx-for-mentions
|
new-at-idxs (check-idx-for-mentions
|
||||||
text
|
text
|
||||||
@ -357,12 +335,12 @@
|
|||||||
[{:keys [db] :as cofx} mentionable-users]
|
[{:keys [db] :as cofx} mentionable-users]
|
||||||
(let [chat-id (:current-chat-id db)
|
(let [chat-id (:current-chat-id db)
|
||||||
text (get-in db [:chat/inputs chat-id :input-text])
|
text (get-in db [:chat/inputs chat-id :input-text])
|
||||||
{:keys [new-text at-sign-counter start end] :as state}
|
{:keys [new-text at-idxs start end] :as state}
|
||||||
(get-in db [:chats chat-id :mentions])
|
(get-in db [:chats chat-id :mentions])
|
||||||
new-text (or new-text text)]
|
new-text (or new-text text)]
|
||||||
(log/debug "[mentions] calculate suggestions"
|
(log/debug "[mentions] calculate suggestions"
|
||||||
"state" state)
|
"state" state)
|
||||||
(if-not (pos? at-sign-counter)
|
(if-not (seq at-idxs)
|
||||||
{:db (-> db
|
{:db (-> db
|
||||||
(assoc-in [:chats/mention-suggestions chat-id] nil)
|
(assoc-in [:chats/mention-suggestions chat-id] nil)
|
||||||
(assoc-in [:chats chat-id :mentions :at-idxs] nil)
|
(assoc-in [:chats chat-id :mentions :at-idxs] nil)
|
||||||
@ -382,8 +360,10 @@
|
|||||||
(when (and (not (> at-sign-idx start))
|
(when (and (not (> at-sign-idx start))
|
||||||
(not (> (- end at-sign-idx) 100)))
|
(not (> (- end at-sign-idx) 100)))
|
||||||
(get-suggestions mentionable-users searched-text))]
|
(get-suggestions mentionable-users searched-text))]
|
||||||
(log/debug "[mentions] mention detected"
|
(log/debug "[mentions] mention check"
|
||||||
"addition" addition?
|
"addition" addition?
|
||||||
|
"at-sign-idx" at-sign-idx
|
||||||
|
"start" start
|
||||||
"end" end
|
"end" end
|
||||||
"searched-text" (pr-str searched-text)
|
"searched-text" (pr-str searched-text)
|
||||||
"mentions" (count mentions))
|
"mentions" (count mentions))
|
||||||
@ -419,10 +399,18 @@
|
|||||||
[{:keys [db]}]
|
[{:keys [db]}]
|
||||||
(log/debug "[mentions] clear suggestions")
|
(log/debug "[mentions] clear suggestions")
|
||||||
(let [chat-id (:current-chat-id db)]
|
(let [chat-id (:current-chat-id db)]
|
||||||
{:db (-> db
|
{:db (update db :chats/mention-suggestions dissoc chat-id)}))
|
||||||
(update-in [:chats chat-id] dissoc :mentions)
|
|
||||||
(update :chats/input-with-mentions dissoc chat-id)
|
(fx/defn clear-mentions
|
||||||
(update :chats/mention-suggestions dissoc chat-id))}))
|
[{:keys [db] :as cofx}]
|
||||||
|
(log/debug "[mentions] clear mentions")
|
||||||
|
(let [chat-id (:current-chat-id db)]
|
||||||
|
(fx/merge
|
||||||
|
cofx
|
||||||
|
{:db (-> db
|
||||||
|
(update-in [:chats chat-id] dissoc :mentions)
|
||||||
|
(update :chats/input-with-mentions dissoc chat-id))}
|
||||||
|
(clear-suggestions))))
|
||||||
|
|
||||||
(fx/defn clear-cursor
|
(fx/defn clear-cursor
|
||||||
{:events [::clear-cursor]}
|
{:events [::clear-cursor]}
|
||||||
@ -430,3 +418,29 @@
|
|||||||
(log/debug "[mentions] clear cursor")
|
(log/debug "[mentions] clear cursor")
|
||||||
{:db
|
{:db
|
||||||
(update db :chats/cursor dissoc (:current-chat-id db))})
|
(update db :chats/cursor dissoc (:current-chat-id db))})
|
||||||
|
|
||||||
|
(fx/defn check-selection
|
||||||
|
{:events [::on-selection-change]}
|
||||||
|
[{:keys [db] :as cofx}
|
||||||
|
{:keys [start end] :as selection}
|
||||||
|
mentionable-users]
|
||||||
|
(let [chat-id (:current-chat-id db)
|
||||||
|
{:keys [mention-end at-idxs]}
|
||||||
|
(get-in db [:chats chat-id :mentions])]
|
||||||
|
(when (seq at-idxs)
|
||||||
|
(if (some
|
||||||
|
(fn [{:keys [from to] :as idx}]
|
||||||
|
(when (and (not (< start from))
|
||||||
|
(<= (dec end) to))
|
||||||
|
idx))
|
||||||
|
at-idxs)
|
||||||
|
(fx/merge
|
||||||
|
cofx
|
||||||
|
{:db (update-in db [:chats chat-id :mentions]
|
||||||
|
assoc
|
||||||
|
:start end
|
||||||
|
:end end
|
||||||
|
:new-text "")}
|
||||||
|
(calculate-suggestion mentionable-users))
|
||||||
|
(clear-suggestions cofx)))))
|
||||||
|
|
||||||
|
@ -885,7 +885,6 @@
|
|||||||
(fn [contacts]
|
(fn [contacts]
|
||||||
(reduce
|
(reduce
|
||||||
(fn [acc [key {:keys [alias name identicon public-key] :as contact}]]
|
(fn [acc [key {:keys [alias name identicon public-key] :as contact}]]
|
||||||
(println :foo alias (contact.db/blocked? contact))
|
|
||||||
(if (and alias
|
(if (and alias
|
||||||
(not= alias "")
|
(not= alias "")
|
||||||
(not (contact.db/blocked? contact)))
|
(not (contact.db/blocked? contact)))
|
||||||
|
@ -81,7 +81,9 @@
|
|||||||
(defn text-input
|
(defn text-input
|
||||||
[{:keys [cooldown-enabled? input-with-mentions on-text-change set-active-panel text-input-ref]}]
|
[{:keys [cooldown-enabled? input-with-mentions on-text-change set-active-panel text-input-ref]}]
|
||||||
(let [cursor @(re-frame/subscribe [:chat/cursor])
|
(let [cursor @(re-frame/subscribe [:chat/cursor])
|
||||||
mentionable-users @(re-frame/subscribe [:chats/mentionable-users])]
|
mentionable-users @(re-frame/subscribe [:chats/mentionable-users])
|
||||||
|
timeout-id (atom nil)
|
||||||
|
last-text-change (atom nil)]
|
||||||
[rn/view {:style (styles/text-input-wrapper)}
|
[rn/view {:style (styles/text-input-wrapper)}
|
||||||
[rn/text-input
|
[rn/text-input
|
||||||
{:style (styles/text-input)
|
{:style (styles/text-input)
|
||||||
@ -112,15 +114,48 @@
|
|||||||
:end cursor}))
|
:end cursor}))
|
||||||
|
|
||||||
:on-selection-change
|
:on-selection-change
|
||||||
(fn [_]
|
(fn [args]
|
||||||
;; NOTE(rasom): we have to reset `cursor` value when user starts using
|
(let [selection (.-selection ^js (.-nativeEvent ^js args))
|
||||||
;; text-input because otherwise cursor will stay in the same position
|
start (.-start selection)
|
||||||
(when (and cursor platform/android?)
|
end (.-end selection)]
|
||||||
(re-frame/dispatch [::mentions/clear-cursor])))
|
;; NOTE(rasom): on iOS we do not dispatch this event immediately
|
||||||
|
;; because it is needed only in case if selection is changed without
|
||||||
|
;; typing. Timeout might be canceled on `on-change`.
|
||||||
|
(when platform/ios?
|
||||||
|
(reset!
|
||||||
|
timeout-id
|
||||||
|
(utils.utils/set-timeout
|
||||||
|
#(re-frame/dispatch [::mentions/on-selection-change
|
||||||
|
{:start start
|
||||||
|
:end end}
|
||||||
|
mentionable-users])
|
||||||
|
50)))
|
||||||
|
;; NOTE(rasom): on Android we dispatch event only in case if there
|
||||||
|
;; was no text changes during last 50ms. `on-selection-change` is
|
||||||
|
;; dispatched after `on-change`, that's why there is no another way
|
||||||
|
;; to know whether selection was changed without typing.
|
||||||
|
(when (and platform/android?
|
||||||
|
(or (not @last-text-change)
|
||||||
|
(< 50 (- (js/Date.now) @last-text-change))))
|
||||||
|
(re-frame/dispatch [::mentions/on-selection-change
|
||||||
|
{:start start
|
||||||
|
:end end}
|
||||||
|
mentionable-users]))
|
||||||
|
;; NOTE(rasom): we have to reset `cursor` value when user starts using
|
||||||
|
;; text-input because otherwise cursor will stay in the same position
|
||||||
|
(when (and cursor platform/android?)
|
||||||
|
(re-frame/dispatch [::mentions/clear-cursor]))))
|
||||||
|
|
||||||
:on-change
|
:on-change
|
||||||
(fn [args]
|
(fn [args]
|
||||||
(let [text (.-text ^js (.-nativeEvent ^js args))]
|
(let [text (.-text ^js (.-nativeEvent ^js args))]
|
||||||
|
;; NOTE(rasom): on iOS `on-selection-change` is canceled in case if it
|
||||||
|
;; happens during typing because it is not needed for mention
|
||||||
|
;; suggestions calculation
|
||||||
|
(when (and platform/ios? @timeout-id)
|
||||||
|
(utils.utils/clear-timeout @timeout-id))
|
||||||
|
(when platform/android?
|
||||||
|
(reset! last-text-change (js/Date.now)))
|
||||||
(on-text-change text)
|
(on-text-change text)
|
||||||
;; NOTE(rasom): on iOS `on-change` is dispatched after `on-text-input`,
|
;; NOTE(rasom): on iOS `on-change` is dispatched after `on-text-input`,
|
||||||
;; that's why mention suggestions are calculated on `on-change`
|
;; that's why mention suggestions are calculated on `on-change`
|
||||||
|
Loading…
x
Reference in New Issue
Block a user