Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aac90672b0 | ||
|
|
2a1d0d9562 | ||
|
|
cc10044f30 | ||
|
|
cad32158cd | ||
|
|
2033ab8804 | ||
|
|
9eccd0fa3d | ||
|
|
4f397c83f2 | ||
|
|
75aeb336e1 | ||
|
|
720ee3f4ad | ||
|
|
88445791a9 | ||
|
|
4e130a71a5 | ||
|
|
ced0f5e289 |
@@ -0,0 +1 @@
|
|||||||
|
{:host "localhost" :port 59423}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
(ns status-im.chat.models.mentions
|
(ns status-im.chat.models.mentions
|
||||||
(:require [clojure.set :as set]
|
(:require [clojure.set :as set]
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log]
|
||||||
|
[utils.debounce :as debounce]
|
||||||
|
[status-im2.contexts.chat.composer.constants :as constants]))
|
||||||
|
|
||||||
(defn- transfer-input-segments
|
(defn- transfer-input-segments
|
||||||
[segments]
|
[segments]
|
||||||
@@ -57,18 +59,22 @@
|
|||||||
mentionable-users))
|
mentionable-users))
|
||||||
(defn- transfer-mention-result
|
(defn- transfer-mention-result
|
||||||
[result]
|
[result]
|
||||||
(let [{:keys [input-segments mentionable-users state chat-id new-text]}
|
(let [{:keys [input-segments mentionable-users state chat-id new-text call-id call-time]}
|
||||||
(set/rename-keys result
|
(set/rename-keys result
|
||||||
{:InputSegments :input-segments
|
{:InputSegments :input-segments
|
||||||
:MentionSuggestions :mentionable-users
|
:MentionSuggestions :mentionable-users
|
||||||
:MentionState :state
|
:MentionState :state
|
||||||
:ChatID :chat-id
|
:ChatID :chat-id
|
||||||
:NewText :new-text})]
|
:NewText :new-text
|
||||||
|
:CallID :call-id
|
||||||
|
:CallTime :call-time})]
|
||||||
{:chat-id chat-id
|
{:chat-id chat-id
|
||||||
:input-segments (transfer-input-segments input-segments)
|
:input-segments (transfer-input-segments input-segments)
|
||||||
:mentionable-users (rename-mentionable-users mentionable-users)
|
:mentionable-users (rename-mentionable-users mentionable-users)
|
||||||
:state (rename-state state)
|
:state (rename-state state)
|
||||||
:new-text new-text}))
|
:new-text new-text
|
||||||
|
:call-id call-id
|
||||||
|
:call-time call-time}))
|
||||||
|
|
||||||
(rf/defn on-error
|
(rf/defn on-error
|
||||||
{:events [:mention/on-error]}
|
{:events [:mention/on-error]}
|
||||||
@@ -98,11 +104,13 @@
|
|||||||
(assoc-in [:chats/mentions chat-id :mentions] state)
|
(assoc-in [:chats/mentions chat-id :mentions] state)
|
||||||
(assoc-in [:chat/inputs-with-mentions chat-id] input-segments))}))
|
(assoc-in [:chat/inputs-with-mentions chat-id] input-segments))}))
|
||||||
|
|
||||||
|
(defonce current-call-id (atom 0))
|
||||||
|
|
||||||
(rf/defn on-change-text
|
(rf/defn on-change-text
|
||||||
{:events [:mention/on-change-text]}
|
{:events [:mention/on-change-text]}
|
||||||
[{:keys [db]} text]
|
[{:keys [db]} text]
|
||||||
(let [chat-id (:current-chat-id db)
|
(let [chat-id (:current-chat-id db)
|
||||||
params [chat-id text]
|
params [chat-id text (swap! current-call-id inc) (js/Date.now)]
|
||||||
method "wakuext_chatMentionOnChangeText"]
|
method "wakuext_chatMentionOnChangeText"]
|
||||||
(log/debug "[mentions] on-change-text" {:params params})
|
(log/debug "[mentions] on-change-text" {:params params})
|
||||||
{:json-rpc/call [{:method method
|
{:json-rpc/call [{:method method
|
||||||
@@ -116,11 +124,31 @@
|
|||||||
{:events [:mention/on-change-text-success]}
|
{:events [:mention/on-change-text-success]}
|
||||||
[{:keys [db]} result]
|
[{:keys [db]} result]
|
||||||
(log/debug "[mentions] on-change-text-success" {:result result})
|
(log/debug "[mentions] on-change-text-success" {:result result})
|
||||||
(let [{:keys [state chat-id mentionable-users input-segments]} (transfer-mention-result result)]
|
(let [{:keys [state chat-id mentionable-users
|
||||||
{:db (-> db
|
input-segments call-id call-time]} (transfer-mention-result result)]
|
||||||
(assoc-in [:chats/mention-suggestions chat-id] mentionable-users)
|
(when (= call-id @current-call-id)
|
||||||
(assoc-in [:chats/mentions chat-id :mentions] state)
|
(debounce/debounce-and-dispatch [:mention/re-render-text-input
|
||||||
(assoc-in [:chat/inputs-with-mentions chat-id] input-segments))}))
|
{:chat-id chat-id
|
||||||
|
:mentionable-users mentionable-users
|
||||||
|
:state state
|
||||||
|
:input-segments input-segments
|
||||||
|
:call-id call-id
|
||||||
|
:response-time (- (js/Date.now) call-time)}]
|
||||||
|
constants/mention-rerender-debounce-ms)
|
||||||
|
)))
|
||||||
|
|
||||||
|
(rf/defn re-render-text-input
|
||||||
|
{:events [:mention/re-render-text-input]}
|
||||||
|
[{:keys [db]}
|
||||||
|
{:keys [chat-id mentionable-users state input-segments] :as params}]
|
||||||
|
(log/debug "[mentions] re-render-text-input" params)
|
||||||
|
{:db (-> db
|
||||||
|
(assoc-in [:chat/inputs-with-mentions chat-id]
|
||||||
|
input-segments)
|
||||||
|
(assoc-in [:chats/mention-suggestions chat-id]
|
||||||
|
mentionable-users)
|
||||||
|
(assoc-in [:chats/mentions chat-id :mentions]
|
||||||
|
state))})
|
||||||
|
|
||||||
(rf/defn on-select-mention-success
|
(rf/defn on-select-mention-success
|
||||||
{:events [:mention/on-select-mention-success]}
|
{:events [:mention/on-select-mention-success]}
|
||||||
|
|||||||
@@ -42,3 +42,5 @@
|
|||||||
(def ^:const unfurl-debounce-ms
|
(def ^:const unfurl-debounce-ms
|
||||||
"Use a high threshold to prevent unnecessary rendering overhead."
|
"Use a high threshold to prevent unnecessary rendering overhead."
|
||||||
400)
|
400)
|
||||||
|
|
||||||
|
(def ^:const mention-rerender-debounce-ms 500)
|
||||||
|
|||||||
@@ -19,7 +19,8 @@
|
|||||||
(when (and (empty? @text-value) (not= input-text nil))
|
(when (and (empty? @text-value) (not= input-text nil))
|
||||||
(reset! text-value input-text)
|
(reset! text-value input-text)
|
||||||
(reset! content-height input-content-height)
|
(reset! content-height input-content-height)
|
||||||
(reset! saved-cursor-position (count input-text)))
|
(reset! saved-cursor-position (count input-text))
|
||||||
|
(rf/dispatch [:mention/on-change-text @text-value]))
|
||||||
(when input-maximized?
|
(when input-maximized?
|
||||||
(reset! maximized? true)))
|
(reset! maximized? true)))
|
||||||
|
|
||||||
@@ -109,7 +110,6 @@
|
|||||||
(let [edit-text (get-in edit [:content :text])]
|
(let [edit-text (get-in edit [:content :text])]
|
||||||
(when (and edit @input-ref)
|
(when (and edit @input-ref)
|
||||||
(.focus ^js @input-ref)
|
(.focus ^js @input-ref)
|
||||||
(.setNativeProps ^js @input-ref (clj->js {:text edit-text}))
|
|
||||||
(reset! text-value edit-text)
|
(reset! text-value edit-text)
|
||||||
(reset! saved-cursor-position (count edit-text)))))
|
(reset! saved-cursor-position (count edit-text)))))
|
||||||
[(:message-id edit)]))
|
[(:message-id edit)]))
|
||||||
@@ -126,32 +126,12 @@
|
|||||||
(.focus ^js @input-ref)))
|
(.focus ^js @input-ref)))
|
||||||
[(:message-id reply)]))
|
[(:message-id reply)]))
|
||||||
|
|
||||||
(defn edit-mentions
|
|
||||||
[{:keys [input-ref]} {:keys [text-value cursor-position]} {:keys [input-with-mentions]}]
|
|
||||||
(rn/use-effect (fn []
|
|
||||||
(let [input-text (reduce (fn [acc item]
|
|
||||||
(str acc (second item)))
|
|
||||||
""
|
|
||||||
input-with-mentions)]
|
|
||||||
(reset! text-value input-text)
|
|
||||||
(reset! cursor-position (count input-text))
|
|
||||||
(js/setTimeout #(when @input-ref
|
|
||||||
(.setNativeProps ^js @input-ref
|
|
||||||
(clj->js {:selection {:start (count input-text)
|
|
||||||
:end (count
|
|
||||||
input-text)}})))
|
|
||||||
300)))
|
|
||||||
[(some #(= :mention (first %)) (seq input-with-mentions))]))
|
|
||||||
|
|
||||||
(defn update-input-mention
|
(defn update-input-mention
|
||||||
[{:keys [input-ref]}
|
[{:keys [text-value]}
|
||||||
{:keys [text-value]}
|
|
||||||
{:keys [input-text]}]
|
{:keys [input-text]}]
|
||||||
(rn/use-effect
|
(rn/use-effect
|
||||||
(fn []
|
(fn []
|
||||||
(when (and input-text (not= @text-value input-text))
|
(when (and input-text (not= @text-value input-text))
|
||||||
(when @input-ref
|
|
||||||
(.setNativeProps ^js @input-ref (clj->js {:text input-text})))
|
|
||||||
(reset! text-value input-text)
|
(reset! text-value input-text)
|
||||||
(rf/dispatch [:mention/on-change-text input-text])))
|
(rf/dispatch [:mention/on-change-text input-text])))
|
||||||
[input-text]))
|
[input-text]))
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
(ns status-im2.contexts.chat.composer.handlers
|
(ns status-im2.contexts.chat.composer.handlers
|
||||||
(:require
|
(:require
|
||||||
[clojure.string :as string]
|
|
||||||
[oops.core :as oops]
|
[oops.core :as oops]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.reanimated :as reanimated]
|
[react-native.reanimated :as reanimated]
|
||||||
[reagent.core :as reagent]
|
|
||||||
[status-im2.contexts.chat.composer.constants :as constants]
|
[status-im2.contexts.chat.composer.constants :as constants]
|
||||||
[status-im2.contexts.chat.composer.keyboard :as kb]
|
[status-im2.contexts.chat.composer.keyboard :as kb]
|
||||||
[status-im2.contexts.chat.composer.selection :as selection]
|
[status-im2.contexts.chat.composer.selection :as selection]
|
||||||
@@ -13,8 +11,8 @@
|
|||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(defn focus
|
(defn focus
|
||||||
[{:keys [input-ref] :as props}
|
[props
|
||||||
{:keys [text-value focused? lock-selection? saved-cursor-position gradient-z-index]}
|
{:keys [focused? lock-selection? gradient-z-index]}
|
||||||
{:keys [height saved-height last-height opacity background-y gradient-opacity container-opacity]
|
{:keys [height saved-height last-height opacity background-y gradient-opacity container-opacity]
|
||||||
:as animations}
|
:as animations}
|
||||||
{:keys [max-height] :as dimensions}]
|
{:keys [max-height] :as dimensions}]
|
||||||
@@ -30,9 +28,6 @@
|
|||||||
(reanimated/animate gradient-opacity 1)
|
(reanimated/animate gradient-opacity 1)
|
||||||
(reset! gradient-z-index 1))
|
(reset! gradient-z-index 1))
|
||||||
(js/setTimeout #(reset! lock-selection? false) 300)
|
(js/setTimeout #(reset! lock-selection? false) 300)
|
||||||
(when (and (not-empty @text-value) @input-ref)
|
|
||||||
(.setNativeProps ^js @input-ref
|
|
||||||
(clj->js {:selection {:start @saved-cursor-position :end @saved-cursor-position}})))
|
|
||||||
(kb/handle-refocus-emoji-kb-ios props animations dimensions))
|
(kb/handle-refocus-emoji-kb-ios props animations dimensions))
|
||||||
|
|
||||||
(defn blur
|
(defn blur
|
||||||
@@ -119,23 +114,17 @@
|
|||||||
|
|
||||||
(defn change-text
|
(defn change-text
|
||||||
[text
|
[text
|
||||||
{:keys [input-ref record-reset-fn]}
|
{:keys [record-reset-fn]}
|
||||||
{:keys [text-value cursor-position recording?]}]
|
{:keys [text-value recording?]}]
|
||||||
(debounce/debounce-and-dispatch [:link-preview/unfurl-urls text]
|
(debounce/debounce-and-dispatch [:link-preview/unfurl-urls text]
|
||||||
constants/unfurl-debounce-ms)
|
constants/unfurl-debounce-ms)
|
||||||
|
|
||||||
(reset! text-value text)
|
(reset! text-value text)
|
||||||
(reagent/next-tick #(when @input-ref
|
|
||||||
(.setNativeProps ^js @input-ref
|
|
||||||
(clj->js {:selection {:start @cursor-position
|
|
||||||
:end @cursor-position}}))))
|
|
||||||
(when @recording?
|
(when @recording?
|
||||||
(@record-reset-fn)
|
(@record-reset-fn)
|
||||||
(reset! recording? false))
|
(reset! recording? false))
|
||||||
(rf/dispatch [:chat.ui/set-chat-input-text text])
|
(rf/dispatch [:chat.ui/set-chat-input-text text])
|
||||||
(if (string/ends-with? text "@")
|
(rf/dispatch [:mention/on-change-text text]))
|
||||||
(rf/dispatch [:mention/on-change-text text])
|
|
||||||
(debounce/debounce-and-dispatch [:mention/on-change-text text] 300)))
|
|
||||||
|
|
||||||
(defn selection-change
|
(defn selection-change
|
||||||
[event
|
[event
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
(ns status-im2.contexts.chat.composer.mentions.view
|
(ns status-im2.contexts.chat.composer.mentions.view
|
||||||
(:require
|
(:require
|
||||||
[react-native.platform :as platform]
|
|
||||||
[react-native.safe-area :as safe-area]
|
[react-native.safe-area :as safe-area]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im2.contexts.chat.composer.utils :as utils]
|
[status-im2.contexts.chat.composer.utils :as utils]
|
||||||
@@ -10,23 +9,12 @@
|
|||||||
[status-im2.common.contact-list-item.view :as contact-list-item]
|
[status-im2.common.contact-list-item.view :as contact-list-item]
|
||||||
[status-im2.contexts.chat.composer.mentions.style :as style]))
|
[status-im2.contexts.chat.composer.mentions.style :as style]))
|
||||||
|
|
||||||
(defn update-cursor
|
|
||||||
[user {:keys [cursor-position input-ref]}]
|
|
||||||
(when platform/android?
|
|
||||||
(let [new-cursor-pos (+ (count (:primary-name user)) @cursor-position 1)]
|
|
||||||
(reset! cursor-position new-cursor-pos)
|
|
||||||
(reagent/next-tick #(when @input-ref
|
|
||||||
(.setNativeProps ^js @input-ref
|
|
||||||
(clj->js {:selection {:start new-cursor-pos
|
|
||||||
:end
|
|
||||||
new-cursor-pos}})))))))
|
|
||||||
|
|
||||||
(defn mention-item
|
(defn mention-item
|
||||||
[user _ _ render-data]
|
[user _ _ _]
|
||||||
[contact-list-item/contact-list-item
|
[contact-list-item/contact-list-item
|
||||||
{:on-press (fn []
|
{:on-press (fn []
|
||||||
(rf/dispatch [:chat.ui/select-mention nil user])
|
(rf/dispatch [:chat.ui/select-mention nil user]))}
|
||||||
(update-cursor user render-data))}
|
|
||||||
user])
|
user])
|
||||||
|
|
||||||
(defn- f-view
|
(defn- f-view
|
||||||
|
|||||||
@@ -125,3 +125,10 @@
|
|||||||
{:transform [{:translate-y translate-y}]
|
{:transform [{:translate-y translate-y}]
|
||||||
:opacity opacity}
|
:opacity opacity}
|
||||||
{}))
|
{}))
|
||||||
|
|
||||||
|
(def mention
|
||||||
|
{:color (colors/theme-colors colors/primary-50
|
||||||
|
colors/primary-60)
|
||||||
|
:background-color colors/primary-50-opa-10
|
||||||
|
:selection-color :transparent
|
||||||
|
:suppress-highlighting true})
|
||||||
|
|||||||
@@ -23,7 +23,19 @@
|
|||||||
[status-im2.contexts.chat.composer.handlers :as handler]
|
[status-im2.contexts.chat.composer.handlers :as handler]
|
||||||
[status-im2.contexts.chat.composer.gradients.view :as gradients]
|
[status-im2.contexts.chat.composer.gradients.view :as gradients]
|
||||||
[status-im2.contexts.chat.composer.selection :as selection]
|
[status-im2.contexts.chat.composer.selection :as selection]
|
||||||
[quo2.theme :as theme]))
|
[quo2.theme :as theme]
|
||||||
|
[quo2.core :as quo]))
|
||||||
|
|
||||||
|
(defn styled-text-input-content
|
||||||
|
[input-with-mentions]
|
||||||
|
(reduce (fn
|
||||||
|
[styled-text [chunk-type chunk-content]]
|
||||||
|
(condp = chunk-type
|
||||||
|
:text (conj styled-text chunk-content)
|
||||||
|
:mention (conj styled-text
|
||||||
|
[quo/text {:style style/mention :weight :medium} chunk-content])))
|
||||||
|
[quo/text]
|
||||||
|
input-with-mentions))
|
||||||
|
|
||||||
(defn sheet-component
|
(defn sheet-component
|
||||||
[{:keys [insets window-height blur-height opacity background-y]} props state]
|
[{:keys [insets window-height blur-height opacity background-y]} props state]
|
||||||
@@ -61,8 +73,7 @@
|
|||||||
subs)
|
subs)
|
||||||
(effects/edit props state subs)
|
(effects/edit props state subs)
|
||||||
(effects/reply props animations subs)
|
(effects/reply props animations subs)
|
||||||
(effects/update-input-mention props state subs)
|
(effects/update-input-mention state subs)
|
||||||
(effects/edit-mentions props state subs)
|
|
||||||
(effects/link-previews props state animations subs)
|
(effects/link-previews props state animations subs)
|
||||||
(effects/images props state animations subs)
|
(effects/images props state animations subs)
|
||||||
[:<>
|
[:<>
|
||||||
@@ -94,7 +105,6 @@
|
|||||||
:style (style/input-view state)}
|
:style (style/input-view state)}
|
||||||
[rn/text-input
|
[rn/text-input
|
||||||
{:ref #(reset! (:input-ref props) %)
|
{:ref #(reset! (:input-ref props) %)
|
||||||
:default-value @(:text-value state)
|
|
||||||
:on-focus #(handler/focus props state animations dimensions)
|
:on-focus #(handler/focus props state animations dimensions)
|
||||||
:on-blur #(handler/blur state animations dimensions subs)
|
:on-blur #(handler/blur state animations dimensions subs)
|
||||||
:on-content-size-change #(handler/content-size-change %
|
:on-content-size-change #(handler/content-size-change %
|
||||||
@@ -115,7 +125,8 @@
|
|||||||
:placeholder-text-color (colors/theme-colors colors/neutral-40 colors/neutral-50)
|
:placeholder-text-color (colors/theme-colors colors/neutral-40 colors/neutral-50)
|
||||||
:style (style/input-text props state subs max-height)
|
:style (style/input-text props state subs max-height)
|
||||||
:max-length constants/max-text-size
|
:max-length constants/max-text-size
|
||||||
:accessibility-label :chat-message-input}]]
|
:accessibility-label :chat-message-input}
|
||||||
|
[styled-text-input-content (:input-with-mentions subs)]]]
|
||||||
(when chat-screen-loaded?
|
(when chat-screen-loaded?
|
||||||
[:<>
|
[:<>
|
||||||
[gradients/view props state animations show-bottom-gradient?]
|
[gradients/view props state animations show-bottom-gradient?]
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
||||||
"owner": "status-im",
|
"owner": "status-im",
|
||||||
"repo": "status-go",
|
"repo": "status-go",
|
||||||
"version": "v0.162.9",
|
"version": "fix/issue-relate-to-mobile-pr-16330-2",
|
||||||
"commit-sha1": "6085a05f77354a26d879f476e67aa85cac1e1414",
|
"commit-sha1": "9d36da074f119975dd115d56ada5db55174c0b62",
|
||||||
"src-sha256": "0lb87lnfi49fk7ijppppr79rzkg8xzpwb3xxxmmq6wca2nb1pqp5"
|
"src-sha256": "0hyw8rq6qgw9n198r0vq8pwv5ac1kkyjzcfpvc2bia8xky42z2h6"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user