mirror of
https://github.com/status-im/status-react.git
synced 2025-01-12 12:04:52 +00:00
refactor and move composer to status-im2 (#14758)
refactor and move composer to status-im2
This commit is contained in:
parent
d6c899be3d
commit
685c95591c
@ -134,7 +134,7 @@
|
|||||||
:style {:width outer-dimensions
|
:style {:width outer-dimensions
|
||||||
:height outer-dimensions
|
:height outer-dimensions
|
||||||
:border-radius outer-dimensions}}
|
:border-radius outer-dimensions}}
|
||||||
(when (and ring? identicon?)
|
(when (and false (and ring? identicon?)) ;;TODO not implemented yet
|
||||||
[icons/icon :i/identicon-ring
|
[icons/icon :i/identicon-ring
|
||||||
{:size outer-dimensions
|
{:size outer-dimensions
|
||||||
:no-color true}])
|
:no-color true}])
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
(def container
|
(def container
|
||||||
{:height 40
|
{:height 40
|
||||||
:flex 1
|
|
||||||
:background-color colors/primary-50-opa-20
|
:background-color colors/primary-50-opa-20
|
||||||
:flex-direction :row
|
:flex-direction :row
|
||||||
:align-items :center
|
:align-items :center
|
||||||
|
5
src/react_native/blur.cljs
Normal file
5
src/react_native/blur.cljs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
(ns react-native.blur
|
||||||
|
(:require ["@react-native-community/blur" :as blur]
|
||||||
|
[reagent.core :as reagent]))
|
||||||
|
|
||||||
|
(def view (reagent/adapt-react-class (.-BlurView blur)))
|
@ -1,6 +1,5 @@
|
|||||||
(ns react-native.core
|
(ns react-native.core
|
||||||
(:require ["@react-native-community/blur" :as blur]
|
(:require ["react" :as react]
|
||||||
["react" :as react]
|
|
||||||
["react-native" :as react-native]
|
["react-native" :as react-native]
|
||||||
[cljs-bean.core :as bean]
|
[cljs-bean.core :as bean]
|
||||||
[oops.core :as oops]
|
[oops.core :as oops]
|
||||||
@ -10,7 +9,6 @@
|
|||||||
[reagent.core :as reagent]))
|
[reagent.core :as reagent]))
|
||||||
|
|
||||||
(def app-state ^js (.-AppState ^js react-native))
|
(def app-state ^js (.-AppState ^js react-native))
|
||||||
(def blur-view (reagent/adapt-react-class (.-BlurView blur)))
|
|
||||||
|
|
||||||
(def view (reagent/adapt-react-class (.-View ^js react-native)))
|
(def view (reagent/adapt-react-class (.-View ^js react-native)))
|
||||||
(def scroll-view (reagent/adapt-react-class (.-ScrollView ^js react-native)))
|
(def scroll-view (reagent/adapt-react-class (.-ScrollView ^js react-native)))
|
||||||
@ -90,13 +88,22 @@
|
|||||||
props)]
|
props)]
|
||||||
children))
|
children))
|
||||||
|
|
||||||
(defn use-effect
|
(def create-ref react/createRef)
|
||||||
([effect] (use-effect effect []))
|
|
||||||
([effect deps]
|
|
||||||
(react/useEffect effect (bean/->js deps))))
|
|
||||||
|
|
||||||
(def use-ref react/useRef)
|
(def use-ref react/useRef)
|
||||||
(defn use-effect-once [effect] (use-effect effect))
|
|
||||||
|
(defn use-effect
|
||||||
|
([effect-fn]
|
||||||
|
(react/useEffect
|
||||||
|
#(let [ret (effect-fn)]
|
||||||
|
(if (fn? ret) ret js/undefined))))
|
||||||
|
([effect-fn deps]
|
||||||
|
(react/useEffect effect-fn (bean/->js deps))))
|
||||||
|
|
||||||
|
(defn use-effect-once
|
||||||
|
[effect-fn]
|
||||||
|
(use-effect effect-fn))
|
||||||
|
|
||||||
(defn use-unmount
|
(defn use-unmount
|
||||||
[f]
|
[f]
|
||||||
(let [fn-ref (use-ref f)]
|
(let [fn-ref (use-ref f)]
|
||||||
|
@ -5,12 +5,11 @@
|
|||||||
|
|
||||||
(def ^:private consumer-raw (reagent/adapt-react-class (.-Consumer ^js SafeAreaInsetsContext)))
|
(def ^:private consumer-raw (reagent/adapt-react-class (.-Consumer ^js SafeAreaInsetsContext)))
|
||||||
|
|
||||||
|
(def provider (reagent/adapt-react-class SafeAreaProvider))
|
||||||
|
|
||||||
(defn consumer
|
(defn consumer
|
||||||
[component]
|
[component]
|
||||||
[consumer-raw
|
[consumer-raw
|
||||||
(fn [^js insets]
|
(fn [^js insets]
|
||||||
(reagent/as-element
|
(reagent/as-element
|
||||||
[component (js->clj insets :keywordize-keys true)]))])
|
[component (js->clj insets :keywordize-keys true)]))])
|
||||||
|
|
||||||
(def safe-area-provider (reagent/adapt-react-class SafeAreaProvider))
|
|
||||||
(def safe-area-consumer consumer-raw)
|
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
[i18n.i18n :as i18n]
|
[i18n.i18n :as i18n]
|
||||||
[utils.datetime :as datetime]
|
[utils.datetime :as datetime]
|
||||||
[status-im.utils.utils :as utils]
|
[status-im.utils.utils :as utils]
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log]
|
||||||
|
[status-im.ui.screens.chat.components.input :as input]))
|
||||||
|
|
||||||
(defn text->emoji
|
(defn text->emoji
|
||||||
"Replaces emojis in a specified `text`"
|
"Replaces emojis in a specified `text`"
|
||||||
@ -117,37 +118,36 @@
|
|||||||
(rf/defn reply-to-message
|
(rf/defn reply-to-message
|
||||||
"Sets reference to previous chat message and focuses on input"
|
"Sets reference to previous chat message and focuses on input"
|
||||||
{:events [:chat.ui/reply-to-message]}
|
{:events [:chat.ui/reply-to-message]}
|
||||||
[{:keys [db] :as cofx} message]
|
[{:keys [db]} message]
|
||||||
(let [current-chat-id (:current-chat-id db)]
|
(let [current-chat-id (:current-chat-id db)]
|
||||||
(rf/merge cofx
|
{:db (-> db
|
||||||
{:db (-> db
|
(assoc-in [:chat/inputs current-chat-id :metadata :responding-to-message]
|
||||||
(assoc-in [:chat/inputs current-chat-id :metadata :responding-to-message]
|
message)
|
||||||
message)
|
(assoc-in [:chat/inputs current-chat-id :metadata :editing-message] nil)
|
||||||
(assoc-in [:chat/inputs current-chat-id :metadata :editing-message] nil)
|
(update-in [:chat/inputs current-chat-id :metadata]
|
||||||
(update-in [:chat/inputs current-chat-id :metadata]
|
dissoc
|
||||||
dissoc
|
:sending-image))}))
|
||||||
:sending-image))})))
|
|
||||||
|
|
||||||
(rf/defn edit-message
|
(rf/defn edit-message
|
||||||
"Sets reference to previous chat message and focuses on input"
|
"Sets reference to previous chat message and focuses on input"
|
||||||
{:events [:chat.ui/edit-message]}
|
{:events [:chat.ui/edit-message]}
|
||||||
[{:keys [db] :as cofx} message]
|
[{:keys [db] :as cofx} message]
|
||||||
(let [current-chat-id (:current-chat-id db)
|
(let [current-chat-id (:current-chat-id db)
|
||||||
|
|
||||||
text (get-in message [:content :text])]
|
text (get-in message [:content :text])]
|
||||||
{:dispatch [:chat.ui.input/set-chat-input-text text current-chat-id]
|
(rf/merge cofx
|
||||||
:db (-> db
|
{:db (-> db
|
||||||
(assoc-in [:chat/inputs current-chat-id :metadata :editing-message]
|
(assoc-in [:chat/inputs current-chat-id :metadata :editing-message]
|
||||||
message)
|
message)
|
||||||
(assoc-in [:chat/inputs current-chat-id :metadata :responding-to-message] nil)
|
(assoc-in [:chat/inputs current-chat-id :metadata :responding-to-message] nil)
|
||||||
(update-in [:chat/inputs current-chat-id :metadata]
|
(update-in [:chat/inputs current-chat-id :metadata]
|
||||||
dissoc
|
dissoc
|
||||||
:sending-image))}))
|
:sending-image))}
|
||||||
|
(input/set-input-text text current-chat-id))))
|
||||||
|
|
||||||
(rf/defn show-contact-request-input
|
(rf/defn show-contact-request-input
|
||||||
"Sets reference to previous chat message and focuses on input"
|
"Sets reference to previous chat message and focuses on input"
|
||||||
{:events [:chat.ui/send-contact-request]}
|
{:events [:chat.ui/send-contact-request]}
|
||||||
[{:keys [db] :as cofx}]
|
[{:keys [db]}]
|
||||||
(let [current-chat-id (:current-chat-id db)]
|
(let [current-chat-id (:current-chat-id db)]
|
||||||
{:db (-> db
|
{:db (-> db
|
||||||
(assoc-in [:chat/inputs current-chat-id :metadata :sending-contact-request]
|
(assoc-in [:chat/inputs current-chat-id :metadata :sending-contact-request]
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
|
|
||||||
(defn contact-request-message
|
(defn contact-request-message
|
||||||
[their-public-key]
|
[their-public-key]
|
||||||
(let [{:keys [input-text]} @(re-frame/subscribe [:chats/current-chat-inputs])]
|
(let [{:keys [input-text]} @(re-frame/subscribe [:chats/current-chat-input])]
|
||||||
[rn/view {:style {:flex-direction :row}}
|
[rn/view {:style {:flex-direction :row}}
|
||||||
[rn/view {:style (styles/contact-request-content)}
|
[rn/view {:style (styles/contact-request-content)}
|
||||||
[quo/button
|
[quo/button
|
||||||
|
@ -212,7 +212,7 @@
|
|||||||
"Set input text for current-chat. Takes db and input text and cofx
|
"Set input text for current-chat. Takes db and input text and cofx
|
||||||
as arguments and returns new fx. Always clear all validation messages."
|
as arguments and returns new fx. Always clear all validation messages."
|
||||||
{:events [:chat.ui.input/set-chat-input-text]}
|
{:events [:chat.ui.input/set-chat-input-text]}
|
||||||
[{:keys [db] :as cofx} text chat-id]
|
[{:keys [db]} text chat-id]
|
||||||
(let [text-with-mentions (mentions/->input-field text)
|
(let [text-with-mentions (mentions/->input-field text)
|
||||||
all-contacts (:contacts/contacts db)
|
all-contacts (:contacts/contacts db)
|
||||||
chat (get-in db [:chats chat-id])
|
chat (get-in db [:chats chat-id])
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
[status-im.ui2.screens.chat.components.edit.style :as style]))
|
[status-im.ui2.screens.chat.components.edit.style :as style]))
|
||||||
|
|
||||||
(defn edit-message
|
(defn edit-message
|
||||||
[reset-composer-callback]
|
[on-cancel]
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style style/container
|
{:style style/container
|
||||||
:accessibility-label :edit-message}
|
:accessibility-label :edit-message}
|
||||||
@ -24,7 +24,7 @@
|
|||||||
(i18n/label :t/editing-message)]]]
|
(i18n/label :t/editing-message)]]]
|
||||||
[gesture-handler/touchable-without-feedback
|
[gesture-handler/touchable-without-feedback
|
||||||
{:accessibility-label :reply-cancel-button
|
{:accessibility-label :reply-cancel-button
|
||||||
:on-press #(do (reset-composer-callback true)
|
:on-press #(do (on-cancel)
|
||||||
(rf/dispatch [:chat.ui/cancel-message-edit]))}
|
(rf/dispatch [:chat.ui/cancel-message-edit]))}
|
||||||
[quo/button
|
[quo/button
|
||||||
{:width 24
|
{:width 24
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
[status-im.ui.screens.chat.sheets :refer [hide-sheet-and-dispatch]]
|
[status-im.ui.screens.chat.sheets :refer [hide-sheet-and-dispatch]]
|
||||||
[status-im.ui.components.toolbar :as toolbar]
|
[status-im.ui.components.toolbar :as toolbar]
|
||||||
[status-im.ui2.screens.common.contact-list.view :as contact-list]
|
[status-im2.common.contact-list.view :as contact-list]
|
||||||
[quo2.components.markdown.text :as text]
|
[quo2.components.markdown.text :as text]
|
||||||
[status-im.ui.components.invite.events :as invite.events]
|
[status-im.ui.components.invite.events :as invite.events]
|
||||||
[status-im.ui2.screens.chat.components.new-chat.styles :as style]))
|
[status-im.ui2.screens.chat.components.new-chat.styles :as style]))
|
||||||
|
17
src/status_im/ui2/screens/chat/components/reply/style.cljs
Normal file
17
src/status_im/ui2/screens/chat/components/reply/style.cljs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
(ns status-im.ui2.screens.chat.components.reply.style)
|
||||||
|
|
||||||
|
(defn reply-content
|
||||||
|
[pin?]
|
||||||
|
{:padding-horizontal (when-not pin? 10)
|
||||||
|
:flex 1
|
||||||
|
:flex-direction :row})
|
||||||
|
|
||||||
|
(defn quoted-message
|
||||||
|
[pin?]
|
||||||
|
(merge {:flex-direction :row
|
||||||
|
:align-items :center
|
||||||
|
:width "45%"}
|
||||||
|
(when-not pin?
|
||||||
|
{:position :absolute
|
||||||
|
:left 34
|
||||||
|
:top 3})))
|
@ -1,4 +1,4 @@
|
|||||||
(ns status-im.ui2.screens.chat.components.reply
|
(ns status-im.ui2.screens.chat.components.reply.view
|
||||||
(:require [clojure.string :as string]
|
(:require [clojure.string :as string]
|
||||||
[i18n.i18n :as i18n]
|
[i18n.i18n :as i18n]
|
||||||
[quo.react-native :as rn]
|
[quo.react-native :as rn]
|
||||||
@ -10,8 +10,8 @@
|
|||||||
[status-im.ethereum.stateofus :as stateofus]
|
[status-im.ethereum.stateofus :as stateofus]
|
||||||
[status-im.ui.components.icons.icons :as icons]
|
[status-im.ui.components.icons.icons :as icons]
|
||||||
[status-im.ui.screens.chat.photos :as photos]
|
[status-im.ui.screens.chat.photos :as photos]
|
||||||
[status-im.ui2.screens.chat.composer.style :as styles]
|
[utils.re-frame :as rf]
|
||||||
[utils.re-frame :as rf]))
|
[status-im.ui2.screens.chat.components.reply.style :as style]))
|
||||||
|
|
||||||
(defn get-quoted-text-with-mentions
|
(defn get-quoted-text-with-mentions
|
||||||
[parsed-text]
|
[parsed-text]
|
||||||
@ -73,16 +73,16 @@
|
|||||||
{:style {:flex-direction :row
|
{:style {:flex-direction :row
|
||||||
:height (when-not pin? 24)
|
:height (when-not pin? 24)
|
||||||
:accessibility-label :reply-message}}
|
:accessibility-label :reply-message}}
|
||||||
[rn/view {:style (styles/reply-content pin?)}
|
[rn/view {:style (style/reply-content pin?)}
|
||||||
(when-not pin?
|
(when-not pin?
|
||||||
;;TODO quo2 icon should be used
|
;;TODO quo2 icon should be used
|
||||||
[icons/icon :main-icons/connector
|
[icons/icon :main-icons/connector
|
||||||
{:color (colors/theme-colors colors/neutral-40 colors/neutral-60)
|
{:color (colors/theme-colors colors/neutral-40 colors/neutral-60)
|
||||||
:container-style {:position :absolute :left 10 :bottom -4 :width 16 :height 16}}])
|
:container-style {:position :absolute :left 10 :bottom -4 :width 16 :height 16}}])
|
||||||
(if (or deleted? deleted-for-me?)
|
(if (or deleted? deleted-for-me?)
|
||||||
[rn/view {:style (styles/quoted-message pin?)}
|
[rn/view {:style (style/quoted-message pin?)}
|
||||||
[reply-deleted-message]]
|
[reply-deleted-message]]
|
||||||
[rn/view {:style (styles/quoted-message pin?)}
|
[rn/view {:style (style/quoted-message pin?)}
|
||||||
[photos/member-photo from identicon 16]
|
[photos/member-photo from identicon 16]
|
||||||
[quo2.text/text
|
[quo2.text/text
|
||||||
{:weight :semi-bold
|
{:weight :semi-bold
|
@ -16,8 +16,8 @@
|
|||||||
(defn edit-message-auto-focus-wrapper
|
(defn edit-message-auto-focus-wrapper
|
||||||
[text-input-ref _]
|
[text-input-ref _]
|
||||||
(let [had-edit (atom nil)]
|
(let [had-edit (atom nil)]
|
||||||
(fn [_ edit cleanup-composer-callback]
|
(fn [_ edit on-cancel]
|
||||||
(focus-input-on-edit edit had-edit text-input-ref)
|
(focus-input-on-edit edit had-edit text-input-ref)
|
||||||
(when edit
|
(when edit
|
||||||
[rn/view {:style style/container}
|
[rn/view {:style style/container}
|
||||||
[edit/edit-message cleanup-composer-callback]]))))
|
[edit/edit-message on-cancel]]))))
|
||||||
|
18
src/status_im/ui2/screens/chat/composer/images/style.cljs
Normal file
18
src/status_im/ui2/screens/chat/composer/images/style.cljs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
(ns status-im.ui2.screens.chat.composer.images.style
|
||||||
|
(:require [quo2.foundations.colors :as colors]))
|
||||||
|
|
||||||
|
(def remove-photo-container
|
||||||
|
{:width 14
|
||||||
|
:height 14
|
||||||
|
:border-radius 7
|
||||||
|
:background-color colors/neutral-50
|
||||||
|
:position :absolute
|
||||||
|
:top 5
|
||||||
|
:right 5
|
||||||
|
:justify-content :center
|
||||||
|
:align-items :center})
|
||||||
|
|
||||||
|
(def small-image
|
||||||
|
{:width 56
|
||||||
|
:height 56
|
||||||
|
:border-radius 8})
|
@ -1,32 +1,33 @@
|
|||||||
(ns status-im.ui2.screens.chat.composer.images.view
|
(ns status-im.ui2.screens.chat.composer.images.view
|
||||||
(:require [quo2.core :as quo2]
|
(:require [quo2.core :as quo]
|
||||||
[quo2.foundations.colors :as colors]
|
[quo2.foundations.colors :as colors]
|
||||||
[re-frame.core :as rf]
|
[re-frame.core :as rf]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[status-im.ui2.screens.chat.composer.style :as style]))
|
[status-im.ui2.screens.chat.composer.images.style :as style]))
|
||||||
|
|
||||||
(defn image
|
(defn image
|
||||||
[item]
|
[item]
|
||||||
[rn/view
|
;; there is a bug on Android https://github.com/facebook/react-native/issues/12534
|
||||||
|
;; so we need some magic here with paddings so close button isn't cut
|
||||||
|
[rn/view {:padding-top 12 :padding-bottom 8 :padding-right 12}
|
||||||
[rn/image
|
[rn/image
|
||||||
{:source {:uri (first item)}
|
{:source {:uri (first item)}
|
||||||
:style style/small-image}]
|
:style style/small-image}]
|
||||||
[rn/touchable-opacity
|
[rn/touchable-opacity
|
||||||
{:on-press (fn [] (rf/dispatch [:chat.ui/image-unselected (first item)]))
|
{:on-press #(rf/dispatch [:chat.ui/image-unselected (first item)])
|
||||||
:style style/remove-photo-container
|
:style style/remove-photo-container
|
||||||
:hit-slop {:right 5
|
:hit-slop {:right 5
|
||||||
:left 5
|
:left 5
|
||||||
:top 10
|
:top 10
|
||||||
:bottom 10}}
|
:bottom 10}}
|
||||||
[quo2/icon :i/close {:color colors/white :size 12}]]])
|
[quo/icon :i/close {:color colors/white :size 12}]]])
|
||||||
|
|
||||||
(defn images-list
|
(defn images-list
|
||||||
[images]
|
[images]
|
||||||
[rn/flat-list
|
(when (seq images)
|
||||||
{:key-fn first
|
[rn/flat-list
|
||||||
:render-fn image
|
{:key-fn first
|
||||||
:data images
|
:render-fn image
|
||||||
:horizontal true
|
:data images
|
||||||
:style {:bottom 50 :position :absolute :z-index 5 :elevation 5}
|
:horizontal true
|
||||||
:content-container-style {:padding-horizontal 20 :margin-top 12 :padding-top 8}
|
:keyboard-should-persist-taps :handled}]))
|
||||||
:separator [rn/view {:style {:width 12}}]}])
|
|
||||||
|
@ -12,13 +12,14 @@
|
|||||||
[status-im.chat.models.mentions :as mentions]
|
[status-im.chat.models.mentions :as mentions]
|
||||||
[i18n.i18n :as i18n]
|
[i18n.i18n :as i18n]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.ui2.screens.chat.composer.style :as style]
|
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
[status-im.utils.platform :as platform]
|
[status-im.utils.platform :as platform]
|
||||||
[status-im.utils.utils :as utils.utils]
|
[status-im.utils.utils :as utils.utils]
|
||||||
[utils.transforms :as transforms]))
|
[utils.transforms :as transforms]
|
||||||
|
[quo2.foundations.typography :as typography]))
|
||||||
|
|
||||||
(defonce input-texts (atom {}))
|
(defonce input-texts (atom {}))
|
||||||
|
(defonce input-text-content-heights (atom {}))
|
||||||
(defonce mentions-enabled? (reagent/atom {}))
|
(defonce mentions-enabled? (reagent/atom {}))
|
||||||
(defonce chat-input-key (reagent/atom 1))
|
(defonce chat-input-key (reagent/atom 1))
|
||||||
(defonce text-input-ref (reagent/atom nil))
|
(defonce text-input-ref (reagent/atom nil))
|
||||||
@ -29,6 +30,7 @@
|
|||||||
:chat.ui/clear-inputs
|
:chat.ui/clear-inputs
|
||||||
(fn []
|
(fn []
|
||||||
(reset! input-texts {})
|
(reset! input-texts {})
|
||||||
|
(reset! input-text-content-heights {})
|
||||||
(reset! mentions-enabled? {})
|
(reset! mentions-enabled? {})
|
||||||
(reset! chat-input-key 1)))
|
(reset! chat-input-key 1)))
|
||||||
|
|
||||||
@ -58,7 +60,8 @@
|
|||||||
(some-> ^js (quo.react/current-ref (:text-input-ref refs))
|
(some-> ^js (quo.react/current-ref (:text-input-ref refs))
|
||||||
.clear)
|
.clear)
|
||||||
(swap! mentions-enabled? update :render not)
|
(swap! mentions-enabled? update :render not)
|
||||||
(swap! input-texts dissoc chat-id))
|
(swap! input-texts dissoc chat-id)
|
||||||
|
(swap! input-text-content-heights dissoc chat-id))
|
||||||
|
|
||||||
(defn clear-input
|
(defn clear-input
|
||||||
[chat-id refs]
|
[chat-id refs]
|
||||||
@ -75,6 +78,7 @@
|
|||||||
|
|
||||||
(defn on-text-change
|
(defn on-text-change
|
||||||
[val chat-id]
|
[val chat-id]
|
||||||
|
(println "on=text-change" val)
|
||||||
(swap! input-texts assoc chat-id val)
|
(swap! input-texts assoc chat-id val)
|
||||||
;;we still store it in app-db for mentions, we don't have reactions in views
|
;;we still store it in app-db for mentions, we don't have reactions in views
|
||||||
(rf/dispatch [:chat.ui/set-chat-input-text val]))
|
(rf/dispatch [:chat.ui/set-chat-input-text val]))
|
||||||
@ -157,16 +161,31 @@
|
|||||||
(when platform/android?
|
(when platform/android?
|
||||||
(rf/dispatch [::mentions/calculate-suggestions mentionable-users]))))
|
(rf/dispatch [::mentions/calculate-suggestions mentionable-users]))))
|
||||||
|
|
||||||
|
(defn text-input-style
|
||||||
|
[]
|
||||||
|
(merge typography/font-regular
|
||||||
|
typography/paragraph-1
|
||||||
|
{:flex 1
|
||||||
|
:min-height 34
|
||||||
|
:margin 0
|
||||||
|
:flex-shrink 1
|
||||||
|
:color (:text-01 @quo.colors/theme)
|
||||||
|
:margin-horizontal 20}
|
||||||
|
(if platform/android?
|
||||||
|
{:padding-vertical 8
|
||||||
|
:text-align-vertical :top}
|
||||||
|
{:margin-top 8
|
||||||
|
:margin-bottom 8})))
|
||||||
|
|
||||||
(defn text-input
|
(defn text-input
|
||||||
[{:keys [set-active-panel refs chat-id sending-image on-content-size-change initial-value]}]
|
[{:keys [refs chat-id sending-image on-content-size-change]}]
|
||||||
(let [_ (reset! text-input-ref (:text-input-ref refs))
|
(let [cooldown-enabled? (rf/sub [:chats/current-chat-cooldown-enabled?])
|
||||||
cooldown-enabled? (rf/sub [:chats/current-chat-cooldown-enabled?])
|
|
||||||
mentionable-users (rf/sub [:chats/mentionable-users])
|
mentionable-users (rf/sub [:chats/mentionable-users])
|
||||||
timeout-id (reagent/atom nil)
|
timeout-id (reagent/atom nil)
|
||||||
last-text-change (reagent/atom nil)
|
last-text-change (reagent/atom nil)
|
||||||
mentions-enabled? (get @mentions-enabled? chat-id)
|
mentions-enabled? (get @mentions-enabled? chat-id)
|
||||||
props
|
props
|
||||||
{:style (style/text-input)
|
{:style (text-input-style)
|
||||||
:ref (:text-input-ref refs)
|
:ref (:text-input-ref refs)
|
||||||
:max-font-size-multiplier 1
|
:max-font-size-multiplier 1
|
||||||
:accessibility-label :chat-message-input
|
:accessibility-label :chat-message-input
|
||||||
@ -175,13 +194,12 @@
|
|||||||
:editable (not cooldown-enabled?)
|
:editable (not cooldown-enabled?)
|
||||||
:blur-on-submit false
|
:blur-on-submit false
|
||||||
:auto-focus false
|
:auto-focus false
|
||||||
:default-value initial-value
|
|
||||||
:on-focus #(set-active-panel nil)
|
|
||||||
:max-length chat.constants/max-text-size
|
:max-length chat.constants/max-text-size
|
||||||
:placeholder-text-color (:text-02 @quo.colors/theme)
|
:placeholder-text-color (:text-02 @quo.colors/theme)
|
||||||
:placeholder (if cooldown-enabled?
|
:placeholder (if cooldown-enabled?
|
||||||
(i18n/label :cooldown/text-input-disabled)
|
(i18n/label :cooldown/text-input-disabled)
|
||||||
(i18n/label :t/type-a-message))
|
(i18n/label :t/type-a-message))
|
||||||
|
:default-value (get @input-texts chat-id)
|
||||||
:underline-color-android :transparent
|
:underline-color-android :transparent
|
||||||
:auto-capitalize :sentences
|
:auto-capitalize :sentences
|
||||||
:auto-correct false
|
:auto-correct false
|
||||||
@ -232,13 +250,12 @@
|
|||||||
(fn [[chat-id text local-text-input-ref]]
|
(fn [[chat-id text local-text-input-ref]]
|
||||||
(when local-text-input-ref
|
(when local-text-input-ref
|
||||||
(reset! text-input-ref local-text-input-ref))
|
(reset! text-input-ref local-text-input-ref))
|
||||||
|
(on-text-change text chat-id)
|
||||||
(if platform/ios?
|
(if platform/ios?
|
||||||
(.setNativeProps ^js (quo.react/current-ref @text-input-ref) (clj->js {:text text}))
|
(.setNativeProps ^js (quo.react/current-ref @text-input-ref) (clj->js {:text text}))
|
||||||
(do
|
(if (string/blank? text)
|
||||||
(on-text-change text chat-id)
|
(.clear ^js (quo.react/current-ref @text-input-ref))
|
||||||
(if (string/blank? text)
|
(.setNativeProps ^js (quo.react/current-ref @text-input-ref) (clj->js {:text text}))))))
|
||||||
(.clear ^js (quo.react/current-ref @text-input-ref))
|
|
||||||
(.setNativeProps ^js (quo.react/current-ref @text-input-ref) (clj->js {:text text})))))))
|
|
||||||
|
|
||||||
(defn calculate-input-text
|
(defn calculate-input-text
|
||||||
[{:keys [full-text selection-start selection-end]} content]
|
[{:keys [full-text selection-start selection-end]} content]
|
||||||
@ -318,7 +335,7 @@
|
|||||||
(action params)))
|
(action params)))
|
||||||
|
|
||||||
(defn selectable-text-input
|
(defn selectable-text-input
|
||||||
[chat-id {:keys [style ref on-selection-change] :as props} children]
|
[_ _ _]
|
||||||
(let [text-input-ref (reagent/atom nil)
|
(let [text-input-ref (reagent/atom nil)
|
||||||
menu-items (reagent/atom first-level-menu-items)
|
menu-items (reagent/atom first-level-menu-items)
|
||||||
first-level (reagent/atom true)
|
first-level (reagent/atom true)
|
||||||
@ -338,7 +355,7 @@
|
|||||||
(oops/ocall manager :startActionMode text-input-handle))))
|
(oops/ocall manager :startActionMode text-input-handle))))
|
||||||
|
|
||||||
:reagent-render
|
:reagent-render
|
||||||
(fn [_]
|
(fn [chat-id {:keys [style ref on-selection-change] :as props} children]
|
||||||
(let [ref #(do (reset! text-input-ref %)
|
(let [ref #(do (reset! text-input-ref %)
|
||||||
(when ref
|
(when ref
|
||||||
(quo.react/set-ref-val! ref %)))
|
(quo.react/set-ref-val! ref %)))
|
||||||
@ -361,7 +378,7 @@
|
|||||||
(let [native-event (.-nativeEvent event)
|
(let [native-event (.-nativeEvent event)
|
||||||
native-event (transforms/js->clj native-event)
|
native-event (transforms/js->clj native-event)
|
||||||
{:keys [eventType content selectionStart selectionEnd]} native-event
|
{:keys [eventType content selectionStart selectionEnd]} native-event
|
||||||
full-text (:input-text (rf/sub [:chats/current-chat-inputs]))]
|
full-text (:input-text (rf/sub [:chats/current-chat-input]))]
|
||||||
(on-menu-item-touched {:first-level first-level
|
(on-menu-item-touched {:first-level first-level
|
||||||
:event-type eventType
|
:event-type eventType
|
||||||
:content content
|
:content content
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
[quo.components.text :as text]
|
[quo.components.text :as text]
|
||||||
[quo.react]
|
[quo.react]
|
||||||
[quo.react-native :as rn]
|
[quo.react-native :as rn]
|
||||||
[react-native.reanimated :as reanimated]
|
|
||||||
[status-im.ui.components.list.views :as list]
|
[status-im.ui.components.list.views :as list]
|
||||||
[status-im.ui.screens.chat.photos :as photos]
|
[status-im.ui.screens.chat.photos :as photos]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
@ -42,20 +41,11 @@
|
|||||||
|
|
||||||
(defn autocomplete-mentions
|
(defn autocomplete-mentions
|
||||||
[suggestions text-input-ref]
|
[suggestions text-input-ref]
|
||||||
[:f>
|
[list/flat-list
|
||||||
(fn []
|
{:keyboardShouldPersistTaps :always
|
||||||
(let [animation (reanimated/use-shared-value 0)]
|
:data suggestions
|
||||||
(quo.react/effect!
|
:key-fn first
|
||||||
#(reanimated/set-shared-value animation (reanimated/with-timing (if (seq suggestions) 0 200))))
|
:render-fn mention-item
|
||||||
[reanimated/view
|
:render-data text-input-ref
|
||||||
{:style (reanimated/apply-animations-to-style
|
:content-container-style {:padding-bottom 12}
|
||||||
{:transform [{:translateY animation}]}
|
:accessibility-label :mentions-list}])
|
||||||
{:bottom 0 :position :absolute :z-index 5 :elevation 5 :max-height 180})}
|
|
||||||
[list/flat-list
|
|
||||||
{:keyboardShouldPersistTaps :always
|
|
||||||
:data suggestions
|
|
||||||
:key-fn first
|
|
||||||
:render-fn mention-item
|
|
||||||
:render-data text-input-ref
|
|
||||||
:content-container-style {:padding-bottom 12}
|
|
||||||
:accessibility-label :mentions-list}]]))])
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
(ns status-im.ui2.screens.chat.composer.reply
|
(ns status-im.ui2.screens.chat.composer.reply
|
||||||
(:require [quo.react-native :as rn]
|
(:require [quo.react-native :as rn]
|
||||||
[status-im.ui2.screens.chat.components.reply :as reply]
|
[status-im.ui2.screens.chat.components.reply.view :as reply]
|
||||||
[status-im.ui2.screens.chat.composer.input :as input]))
|
[status-im.ui2.screens.chat.composer.input :as input]))
|
||||||
|
|
||||||
(defn focus-input-on-reply
|
(defn focus-input-on-reply
|
||||||
|
@ -1,106 +0,0 @@
|
|||||||
(ns status-im.ui2.screens.chat.composer.style
|
|
||||||
(:require [quo.design-system.colors :as quo.colors]
|
|
||||||
[quo2.foundations.colors :as colors]
|
|
||||||
[quo2.foundations.typography :as quo2.typography]
|
|
||||||
[status-im.utils.platform :as platform]))
|
|
||||||
|
|
||||||
(defn text-input
|
|
||||||
[]
|
|
||||||
(merge quo2.typography/font-regular
|
|
||||||
quo2.typography/paragraph-1
|
|
||||||
{:flex 1
|
|
||||||
:min-height 34
|
|
||||||
:margin 0
|
|
||||||
:flex-shrink 1
|
|
||||||
:color (:text-01 @quo.colors/theme)
|
|
||||||
:margin-horizontal 20}
|
|
||||||
(if platform/android?
|
|
||||||
{:padding-vertical 8
|
|
||||||
:text-align-vertical :top}
|
|
||||||
{:margin-top 8
|
|
||||||
:margin-bottom 8})))
|
|
||||||
|
|
||||||
(defn input-bottom-sheet
|
|
||||||
[window-height]
|
|
||||||
(merge {:border-top-left-radius 20
|
|
||||||
:border-top-right-radius 20
|
|
||||||
:position :absolute
|
|
||||||
:left 0
|
|
||||||
:right 0
|
|
||||||
:bottom (- window-height)
|
|
||||||
:height window-height
|
|
||||||
:flex 1
|
|
||||||
:background-color (colors/theme-colors colors/white colors/neutral-90)
|
|
||||||
:z-index 2}
|
|
||||||
(if platform/ios?
|
|
||||||
{:shadow-radius 16
|
|
||||||
:shadow-opacity 1
|
|
||||||
:shadow-color "rgba(9, 16, 28, 0.04)"
|
|
||||||
:shadow-offset {:width 0 :height -2}}
|
|
||||||
{:elevation 2})))
|
|
||||||
|
|
||||||
(defn bottom-sheet-handle
|
|
||||||
[]
|
|
||||||
{:width 32
|
|
||||||
:height 4
|
|
||||||
:background-color (colors/theme-colors colors/neutral-100 colors/white)
|
|
||||||
:opacity 0.05
|
|
||||||
:border-radius 100
|
|
||||||
:align-self :center
|
|
||||||
:margin-top 8})
|
|
||||||
|
|
||||||
(defn bottom-sheet-controls
|
|
||||||
[insets]
|
|
||||||
{:flex-direction :row
|
|
||||||
:padding-horizontal 20
|
|
||||||
:elevation 2
|
|
||||||
:z-index 3
|
|
||||||
:position :absolute
|
|
||||||
:background-color (colors/theme-colors colors/white colors/neutral-90)
|
|
||||||
;these 3 props play together, we need this magic to hide message text in the safe area
|
|
||||||
:padding-top 10
|
|
||||||
:padding-bottom (+ 12 (:bottom insets))
|
|
||||||
:bottom (- 2 (:bottom insets))})
|
|
||||||
|
|
||||||
(defn bottom-sheet-background
|
|
||||||
[window-height]
|
|
||||||
{:position :absolute
|
|
||||||
:left 0
|
|
||||||
:right 0
|
|
||||||
:bottom 0
|
|
||||||
:height window-height
|
|
||||||
:background-color colors/neutral-95-opa-70
|
|
||||||
:z-index 1})
|
|
||||||
|
|
||||||
(defn reply-content
|
|
||||||
[pin?]
|
|
||||||
{:padding-horizontal (when-not pin? 10)
|
|
||||||
:flex 1
|
|
||||||
:flex-direction :row})
|
|
||||||
|
|
||||||
(defn quoted-message
|
|
||||||
[pin?]
|
|
||||||
(merge {:flex-direction :row
|
|
||||||
:align-items :center
|
|
||||||
:width "45%"}
|
|
||||||
(when-not pin?
|
|
||||||
{:position :absolute
|
|
||||||
:left 34
|
|
||||||
:top 3})))
|
|
||||||
|
|
||||||
(def remove-photo-container
|
|
||||||
{:width 14
|
|
||||||
:height 14
|
|
||||||
:border-radius 7
|
|
||||||
:background-color colors/neutral-50
|
|
||||||
:position :absolute
|
|
||||||
:top -7
|
|
||||||
:right -7
|
|
||||||
:justify-content :center
|
|
||||||
:align-items :center})
|
|
||||||
|
|
||||||
(def small-image
|
|
||||||
{:width 56
|
|
||||||
:height 56
|
|
||||||
:border-radius 8
|
|
||||||
:margin-bottom 20})
|
|
@ -1,345 +0,0 @@
|
|||||||
(ns status-im.ui2.screens.chat.composer.view
|
|
||||||
(:require [clojure.string :as string]
|
|
||||||
[i18n.i18n :as i18n]
|
|
||||||
[oops.core :refer [oget]]
|
|
||||||
[quo.components.safe-area :as safe-area]
|
|
||||||
[quo.react]
|
|
||||||
[quo.react-native :as rn :refer [navigation-const]]
|
|
||||||
[quo2.components.buttons.button :as quo2.button]
|
|
||||||
[react-native.gesture :as gesture]
|
|
||||||
[react-native.reanimated :as reanimated]
|
|
||||||
[status-im.ui.components.permissions :as permissions]
|
|
||||||
[status-im.ui2.screens.chat.composer.edit.view :as edit]
|
|
||||||
[status-im.ui2.screens.chat.composer.images.view :as composer-images]
|
|
||||||
[status-im.ui2.screens.chat.composer.input :as input]
|
|
||||||
[status-im.ui2.screens.chat.composer.mentions :as mentions]
|
|
||||||
[status-im.ui2.screens.chat.composer.reply :as reply]
|
|
||||||
[status-im.ui2.screens.chat.composer.style :as style]
|
|
||||||
[status-im2.contexts.chat.photo-selector.view :as photo-selector]
|
|
||||||
[utils.re-frame :as rf]
|
|
||||||
[status-im.utils.utils :as utils]
|
|
||||||
[status-im2.contexts.chat.messages.list.view :refer [scroll-to-bottom]]
|
|
||||||
[status-im.utils.platform :as platform]
|
|
||||||
[status-im2.common.not-implemented :as not-implemented]))
|
|
||||||
|
|
||||||
(defn calculate-y
|
|
||||||
[context min-y max-y added-value chat-id set-bg-opacity]
|
|
||||||
(let [input-text (:input-text (get (rf/sub [:chat/inputs]) chat-id))
|
|
||||||
num-lines (count (string/split input-text "\n"))]
|
|
||||||
(if (<= 5 num-lines)
|
|
||||||
(do (when-not (:minimized-from-handlebar? @context)
|
|
||||||
(swap! context assoc :state :max)
|
|
||||||
(set-bg-opacity 1))
|
|
||||||
max-y)
|
|
||||||
(when (:minimized-from-handlebar? @context)
|
|
||||||
(swap! context assoc :state :min :minimized-from-handlebar? false)
|
|
||||||
(set-bg-opacity 0)
|
|
||||||
min-y))
|
|
||||||
(if (= (:state @context) :max)
|
|
||||||
(do
|
|
||||||
(set-bg-opacity 1)
|
|
||||||
max-y)
|
|
||||||
(when (< (:y @context) max-y)
|
|
||||||
(+ (:y @context) added-value)))))
|
|
||||||
|
|
||||||
(defn calculate-y-with-mentions
|
|
||||||
[y max-y max-height chat-id suggestions reply]
|
|
||||||
(let [input-text (:input-text (get (rf/sub [:chat/inputs]) chat-id))
|
|
||||||
num-lines (count (string/split input-text "\n"))
|
|
||||||
text-height (* num-lines 22)
|
|
||||||
mentions-height (min 132 (+ 16 (* 46 (- (count suggestions) 1))))
|
|
||||||
should-translate? (if (< (- max-height text-height) mentions-height) true false)
|
|
||||||
min-value (if-not reply mentions-height (+ mentions-height 44))
|
|
||||||
; translate value when mentions list appear while at bottom of expanded input sheet
|
|
||||||
mentions-translate-value (if should-translate?
|
|
||||||
(min min-value (- mentions-height (- max-height text-height)))
|
|
||||||
mentions-height)]
|
|
||||||
(when (or (< y max-y) should-translate?) mentions-translate-value)))
|
|
||||||
|
|
||||||
(defn get-y-value
|
|
||||||
[context min-y max-y added-value max-height chat-id suggestions reply edit images set-bg-opacity]
|
|
||||||
(let [y (calculate-y context min-y max-y added-value chat-id set-bg-opacity)
|
|
||||||
y-with-mentions (calculate-y-with-mentions y max-y max-height chat-id suggestions reply)]
|
|
||||||
(+ y (when (seq suggestions) y-with-mentions) (when (seq images) 80) (when edit 38))))
|
|
||||||
|
|
||||||
(defn- clean-and-minimize-composer
|
|
||||||
([context chat-id refs min-y]
|
|
||||||
(clean-and-minimize-composer context chat-id refs min-y false))
|
|
||||||
([context chat-id refs min-y edit?]
|
|
||||||
(input/clear-input chat-id refs)
|
|
||||||
(swap! context assoc
|
|
||||||
:y
|
|
||||||
(if edit?
|
|
||||||
(- min-y 38)
|
|
||||||
min-y))
|
|
||||||
(swap! context assoc :clear true :state :min)))
|
|
||||||
|
|
||||||
(defn get-bottom-sheet-gesture
|
|
||||||
[context translate-y text-input-ref keyboard-shown min-y max-y shared-height max-height set-bg-opacity]
|
|
||||||
(-> (gesture/gesture-pan)
|
|
||||||
(gesture/on-start
|
|
||||||
(fn [_]
|
|
||||||
(if keyboard-shown
|
|
||||||
(swap! context assoc :pan-y (reanimated/get-shared-value translate-y))
|
|
||||||
(input/input-focus text-input-ref))))
|
|
||||||
(gesture/on-update
|
|
||||||
(fn [evt]
|
|
||||||
(when keyboard-shown
|
|
||||||
(swap! context assoc :dy (- (.-translationY evt) (:pdy @context)))
|
|
||||||
(swap! context assoc :pdy (.-translationY evt))
|
|
||||||
(reanimated/set-shared-value
|
|
||||||
translate-y
|
|
||||||
(max (min (+ (.-translationY evt) (:pan-y @context)) (- min-y)) (- max-y))))))
|
|
||||||
(gesture/on-end
|
|
||||||
(fn [_]
|
|
||||||
(when keyboard-shown
|
|
||||||
(if (< (:dy @context) 0)
|
|
||||||
(do
|
|
||||||
(swap! context assoc :minimized-from-handlebar? false)
|
|
||||||
(swap! context assoc :state :max)
|
|
||||||
(input/input-focus text-input-ref)
|
|
||||||
(reanimated/set-shared-value translate-y (reanimated/with-timing (- max-y)))
|
|
||||||
(reanimated/set-shared-value shared-height (reanimated/with-timing max-height))
|
|
||||||
(set-bg-opacity 1))
|
|
||||||
(do
|
|
||||||
(swap! context assoc :minimized-from-handlebar? true)
|
|
||||||
(reanimated/set-shared-value translate-y (reanimated/with-timing (- min-y)))
|
|
||||||
(reanimated/set-shared-value shared-height (reanimated/with-timing min-y))
|
|
||||||
(set-bg-opacity 0)
|
|
||||||
(rf/dispatch [:dismiss-keyboard]))))))))
|
|
||||||
|
|
||||||
(defn get-input-content-change
|
|
||||||
[context translate-y shared-height max-height set-bg-opacity keyboard-shown min-y max-y blank-composer?
|
|
||||||
initial-value]
|
|
||||||
(fn [evt]
|
|
||||||
(when-not (or blank-composer? (some? initial-value))
|
|
||||||
(swap! context assoc :clear false))
|
|
||||||
(if (:clear @context)
|
|
||||||
(do
|
|
||||||
(swap! context dissoc :clear)
|
|
||||||
(swap! context assoc :state :min)
|
|
||||||
(swap! context assoc :y min-y)
|
|
||||||
(reanimated/set-shared-value translate-y (reanimated/with-timing (- min-y)))
|
|
||||||
(reanimated/set-shared-value shared-height (reanimated/with-timing min-y))
|
|
||||||
(set-bg-opacity 0))
|
|
||||||
(when (not= (:state @context) :max)
|
|
||||||
(let [offset-value (if platform/ios? 22 40)
|
|
||||||
new-y (+ min-y
|
|
||||||
(- (max (oget evt "nativeEvent" "contentSize" "height") offset-value)
|
|
||||||
offset-value))]
|
|
||||||
(if (< new-y max-y)
|
|
||||||
(do
|
|
||||||
(if (> (- max-y new-y) 120)
|
|
||||||
(do
|
|
||||||
(swap! context assoc :state :custom-chat-available)
|
|
||||||
(set-bg-opacity 0))
|
|
||||||
(do
|
|
||||||
(set-bg-opacity 1)
|
|
||||||
(swap! context assoc :state :custom-chat-unavailable)))
|
|
||||||
(swap! context assoc :y new-y)
|
|
||||||
(when keyboard-shown
|
|
||||||
(reanimated/set-shared-value
|
|
||||||
translate-y
|
|
||||||
(reanimated/with-timing (- new-y)))
|
|
||||||
(reanimated/set-shared-value
|
|
||||||
shared-height
|
|
||||||
(reanimated/with-timing (min new-y max-height)))))
|
|
||||||
(do
|
|
||||||
(swap! context assoc :state :max)
|
|
||||||
(swap! context assoc :y max-y)
|
|
||||||
(if keyboard-shown
|
|
||||||
(do (set-bg-opacity 1)
|
|
||||||
(reanimated/set-shared-value
|
|
||||||
translate-y
|
|
||||||
(reanimated/with-timing (- max-y))))
|
|
||||||
(set-bg-opacity 0)))))))))
|
|
||||||
|
|
||||||
(defn composer
|
|
||||||
[chat-id]
|
|
||||||
[safe-area/consumer
|
|
||||||
(fn [insets]
|
|
||||||
(let [min-y 112
|
|
||||||
context (atom {:y min-y ;current y value
|
|
||||||
:min-y min-y ;minimum y value
|
|
||||||
:dy 0 ;used for gesture
|
|
||||||
:pdy 0 ;used for gesture
|
|
||||||
:state :min ;:min, :custom-chat-available,
|
|
||||||
;:custom-chat-unavailable, :max
|
|
||||||
:clear false
|
|
||||||
:minimized-from-handlebar? false})
|
|
||||||
keyboard-was-shown? (atom false)
|
|
||||||
text-input-ref (quo.react/create-ref)
|
|
||||||
send-ref (quo.react/create-ref)
|
|
||||||
refs {:send-ref send-ref
|
|
||||||
:text-input-ref text-input-ref}]
|
|
||||||
(fn []
|
|
||||||
[:f>
|
|
||||||
(fn []
|
|
||||||
(let [reply (rf/sub [:chats/reply-message])
|
|
||||||
edit (rf/sub [:chats/edit-message])
|
|
||||||
suggestions (rf/sub [:chat/mention-suggestions])
|
|
||||||
images (get-in (rf/sub [:chat/inputs])
|
|
||||||
[chat-id :metadata :sending-image])
|
|
||||||
{window-height :height} (rn/use-window-dimensions)
|
|
||||||
{:keys [keyboard-shown keyboard-height]} (rn/use-keyboard)
|
|
||||||
max-y (- window-height
|
|
||||||
(if (> keyboard-height 0)
|
|
||||||
keyboard-height
|
|
||||||
360)
|
|
||||||
(:top insets)
|
|
||||||
(:status-bar-height @navigation-const)) ; 360
|
|
||||||
; -
|
|
||||||
; default
|
|
||||||
; height
|
|
||||||
max-height (Math/abs (- max-y 56 (:bottom insets))) ; 56
|
|
||||||
; -
|
|
||||||
; top-bar
|
|
||||||
; height
|
|
||||||
added-value (if (and (not (seq suggestions))
|
|
||||||
(or edit reply))
|
|
||||||
38
|
|
||||||
0) ; increased height
|
|
||||||
; of input box
|
|
||||||
; needed when reply
|
|
||||||
min-y (+ min-y (when (or edit reply) 38))
|
|
||||||
bg-opacity (reanimated/use-shared-value 0)
|
|
||||||
bg-bottom (reanimated/use-shared-value (-
|
|
||||||
window-height))
|
|
||||||
set-bg-opacity
|
|
||||||
(fn [value]
|
|
||||||
(reanimated/set-shared-value bg-bottom (if (= value 1) 0 (- window-height)))
|
|
||||||
(reanimated/set-shared-value bg-opacity (reanimated/with-timing value)))
|
|
||||||
y (get-y-value
|
|
||||||
context
|
|
||||||
min-y
|
|
||||||
max-y
|
|
||||||
added-value
|
|
||||||
max-height
|
|
||||||
chat-id
|
|
||||||
suggestions
|
|
||||||
reply
|
|
||||||
edit
|
|
||||||
images
|
|
||||||
set-bg-opacity)
|
|
||||||
translate-y (reanimated/use-shared-value 0)
|
|
||||||
shared-height (reanimated/use-shared-value min-y)
|
|
||||||
clean-and-minimize-composer-fn
|
|
||||||
#(clean-and-minimize-composer context chat-id refs min-y %)
|
|
||||||
blank-composer? (string/blank? (get @input/input-texts
|
|
||||||
chat-id))
|
|
||||||
initial-value (or (get @input/input-texts chat-id) nil)
|
|
||||||
input-content-change (get-input-content-change
|
|
||||||
context
|
|
||||||
translate-y
|
|
||||||
shared-height
|
|
||||||
max-height
|
|
||||||
set-bg-opacity
|
|
||||||
keyboard-shown
|
|
||||||
min-y
|
|
||||||
max-y
|
|
||||||
blank-composer?
|
|
||||||
initial-value)
|
|
||||||
bottom-sheet-gesture (get-bottom-sheet-gesture
|
|
||||||
context
|
|
||||||
translate-y
|
|
||||||
text-input-ref
|
|
||||||
keyboard-shown
|
|
||||||
min-y
|
|
||||||
max-y
|
|
||||||
shared-height
|
|
||||||
max-height
|
|
||||||
set-bg-opacity)]
|
|
||||||
(quo.react/effect!
|
|
||||||
(fn []
|
|
||||||
(let [input-text (-> [:chat/inputs]
|
|
||||||
rf/sub
|
|
||||||
(get chat-id)
|
|
||||||
:input-text)
|
|
||||||
edited? (not= input-text (-> edit :content :text))]
|
|
||||||
(when (and @keyboard-was-shown? (not keyboard-shown))
|
|
||||||
(swap! context assoc :state :min)
|
|
||||||
(set-bg-opacity 0))
|
|
||||||
(when (and blank-composer? (empty? images) (not edit))
|
|
||||||
(clean-and-minimize-composer-fn false))
|
|
||||||
(if (or (seq images) (and (not blank-composer?) edited?))
|
|
||||||
(input/show-send refs)
|
|
||||||
(input/hide-send refs))
|
|
||||||
(reset! keyboard-was-shown? keyboard-shown)
|
|
||||||
(if (#{:max :custom-chat-unavailable} (:state @context))
|
|
||||||
(set-bg-opacity 1)
|
|
||||||
(set-bg-opacity 0))
|
|
||||||
(reanimated/set-shared-value translate-y (reanimated/with-timing (- y)))
|
|
||||||
(reanimated/set-shared-value shared-height
|
|
||||||
(reanimated/with-timing (min y max-height))))))
|
|
||||||
[reanimated/view
|
|
||||||
{:style (reanimated/apply-animations-to-style
|
|
||||||
{:height shared-height}
|
|
||||||
{:z-index 2})}
|
|
||||||
;;INPUT MESSAGE bottom sheet
|
|
||||||
[gesture/gesture-detector {:gesture bottom-sheet-gesture}
|
|
||||||
[reanimated/view
|
|
||||||
{:style (reanimated/apply-animations-to-style
|
|
||||||
{:transform [{:translateY translate-y}]}
|
|
||||||
(style/input-bottom-sheet window-height))}
|
|
||||||
;handle
|
|
||||||
[rn/view {:style (style/bottom-sheet-handle)}]
|
|
||||||
[edit/edit-message-auto-focus-wrapper text-input-ref edit
|
|
||||||
clean-and-minimize-composer-fn]
|
|
||||||
[reply/reply-message-auto-focus-wrapper text-input-ref reply]
|
|
||||||
[rn/view {:style {:height (- max-y 80 added-value)}}
|
|
||||||
[input/text-input
|
|
||||||
{:chat-id chat-id
|
|
||||||
:on-content-size-change input-content-change
|
|
||||||
:sending-image (seq images)
|
|
||||||
:initial-value initial-value
|
|
||||||
:refs refs
|
|
||||||
:set-active-panel #()}]]]]
|
|
||||||
;CONTROLS
|
|
||||||
(when-not (seq suggestions)
|
|
||||||
[rn/view {:style (style/bottom-sheet-controls insets)}
|
|
||||||
[quo2.button/button
|
|
||||||
{:on-press (fn []
|
|
||||||
(permissions/request-permissions
|
|
||||||
{:permissions [:read-external-storage :write-external-storage]
|
|
||||||
:on-allowed #(rf/dispatch
|
|
||||||
[:bottom-sheet/show-sheet
|
|
||||||
{:content (fn []
|
|
||||||
(photo-selector/photo-selector chat-id))}])
|
|
||||||
:on-denied (fn []
|
|
||||||
(utils/set-timeout
|
|
||||||
#(utils/show-popup (i18n/label :t/error)
|
|
||||||
(i18n/label
|
|
||||||
:t/external-storage-denied))
|
|
||||||
50))}))
|
|
||||||
:icon true
|
|
||||||
:type :outline
|
|
||||||
:size 32} :i/image]
|
|
||||||
[rn/view {:width 12}]
|
|
||||||
[not-implemented/not-implemented
|
|
||||||
[quo2.button/button
|
|
||||||
{:icon true
|
|
||||||
:type :outline
|
|
||||||
:size 32} :i/reaction]]
|
|
||||||
[rn/view {:flex 1}]
|
|
||||||
;;SEND button
|
|
||||||
[rn/view
|
|
||||||
{:ref send-ref
|
|
||||||
:style (when (seq images)
|
|
||||||
{:width 0
|
|
||||||
:right -100})}
|
|
||||||
[quo2.button/button
|
|
||||||
{:icon true
|
|
||||||
:size 32
|
|
||||||
:accessibility-label :send-message-button
|
|
||||||
:on-press #(do (clean-and-minimize-composer-fn (some? edit))
|
|
||||||
(scroll-to-bottom)
|
|
||||||
(rf/dispatch [:chat.ui/send-current-message]))}
|
|
||||||
:i/arrow-up]]])
|
|
||||||
;black background
|
|
||||||
[reanimated/view
|
|
||||||
{:style (reanimated/apply-animations-to-style
|
|
||||||
{:opacity bg-opacity
|
|
||||||
:transform [{:translateY bg-bottom}]}
|
|
||||||
(style/bottom-sheet-background window-height))}]
|
|
||||||
[composer-images/images-list images]
|
|
||||||
[mentions/autocomplete-mentions suggestions text-input-ref]]))])))])
|
|
@ -23,7 +23,7 @@
|
|||||||
[status-im.ui.screens.chat.styles.message.message :as style]
|
[status-im.ui.screens.chat.styles.message.message :as style]
|
||||||
[status-im.ui.screens.chat.utils :as chat.utils]
|
[status-im.ui.screens.chat.utils :as chat.utils]
|
||||||
[status-im.ui.screens.communities.icon :as communities.icon]
|
[status-im.ui.screens.communities.icon :as communities.icon]
|
||||||
[status-im.ui2.screens.chat.components.reply :as components.reply]
|
[status-im.ui2.screens.chat.components.reply.view :as components.reply]
|
||||||
[status-im.utils.config :as config]
|
[status-im.utils.config :as config]
|
||||||
[utils.datetime :as datetime]
|
[utils.datetime :as datetime]
|
||||||
[status-im.utils.utils :as utils]
|
[status-im.utils.utils :as utils]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
(ns status-im.ui2.screens.common.contact-list.view
|
(ns status-im2.common.contact-list.view
|
||||||
(:require [quo2.core :as quo]
|
(:require [quo2.core :as quo]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[status-im2.common.contact-list-item.view :as contact-list-item]
|
[status-im2.common.contact-list-item.view :as contact-list-item]
|
@ -3,6 +3,7 @@
|
|||||||
[quo2.core :as quo]
|
[quo2.core :as quo]
|
||||||
[quo2.foundations.colors :as colors]
|
[quo2.foundations.colors :as colors]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
|
[react-native.blur :as blur]
|
||||||
[react-native.platform :as platform]
|
[react-native.platform :as platform]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im2.common.scroll-page.style :as style]
|
[status-im2.common.scroll-page.style :as style]
|
||||||
@ -68,7 +69,7 @@
|
|||||||
{:source cover
|
{:source cover
|
||||||
:position :absolute
|
:position :absolute
|
||||||
:style (style/image-slider (get-header-size @scroll-height))}]
|
:style (style/image-slider (get-header-size @scroll-height))}]
|
||||||
[rn/blur-view (style/blur-slider (get-header-size @scroll-height))]]
|
[blur/view (style/blur-slider (get-header-size @scroll-height))]]
|
||||||
[rn/view {:style {:z-index 6 :margin-top (if platform/ios? 44 0)}}
|
[rn/view {:style {:z-index 6 :margin-top (if platform/ios? 44 0)}}
|
||||||
[quo/page-nav
|
[quo/page-nav
|
||||||
{:horizontal-description? true
|
{:horizontal-description? true
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[status-im.chat.models :as chat.models]
|
[status-im.chat.models :as chat.models]
|
||||||
[status-im2.contexts.chat.group-details.style :as style]
|
[status-im2.contexts.chat.group-details.style :as style]
|
||||||
[status-im.ui2.screens.common.contact-list.view :as contact-list]
|
[status-im2.common.contact-list.view :as contact-list]
|
||||||
[status-im2.common.contact-list-item.view :as contact-list-item]
|
[status-im2.common.contact-list-item.view :as contact-list-item]
|
||||||
[status-im2.common.home.actions.view :as actions]
|
[status-im2.common.home.actions.view :as actions]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im.ui2.screens.common.contact-list.view :as contact-list]
|
[status-im2.common.contact-list.view :as contact-list]
|
||||||
[status-im2.common.home.view :as common.home]
|
[status-im2.common.home.view :as common.home]
|
||||||
[status-im2.contexts.chat.home.chat-list-item.view :as chat-list-item]
|
[status-im2.contexts.chat.home.chat-list-item.view :as chat-list-item]
|
||||||
[status-im2.contexts.chat.home.contact-request.view :as contact-request]
|
[status-im2.contexts.chat.home.contact-request.view :as contact-request]
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
(ns status-im2.contexts.chat.messages.composer.controls.style
|
||||||
|
(:require [quo2.foundations.colors :as colors]))
|
||||||
|
|
||||||
|
(defn controls
|
||||||
|
[insets]
|
||||||
|
{:padding-horizontal 20
|
||||||
|
:elevation 4
|
||||||
|
:z-index 3
|
||||||
|
:position :absolute
|
||||||
|
:background-color (colors/theme-colors colors/white colors/neutral-90)
|
||||||
|
:padding-bottom (+ 12 (:bottom insets))
|
||||||
|
:bottom 0
|
||||||
|
:left 0
|
||||||
|
:right 0})
|
@ -0,0 +1,71 @@
|
|||||||
|
(ns status-im2.contexts.chat.messages.composer.controls.view
|
||||||
|
(:require [react-native.core :as rn]
|
||||||
|
[react-native.background-timer :as background-timer]
|
||||||
|
[utils.re-frame :as rf]
|
||||||
|
[i18n.i18n :as i18n]
|
||||||
|
[quo2.core :as quo]
|
||||||
|
[status-im2.common.not-implemented :as not-implemented]
|
||||||
|
[status-im2.contexts.chat.photo-selector.view :as photo-selector]
|
||||||
|
[status-im2.contexts.chat.messages.composer.controls.style :as style]
|
||||||
|
[status-im2.contexts.chat.messages.list.view :as messages.list]
|
||||||
|
[status-im.ui.components.permissions :as permissions]
|
||||||
|
[status-im.ui2.screens.chat.composer.images.view :as composer-images]
|
||||||
|
[status-im.utils.utils :as utils-old]
|
||||||
|
[status-im.ui2.screens.chat.composer.input :as input]))
|
||||||
|
|
||||||
|
(defn send-button
|
||||||
|
[send-ref {:keys [chat-id images]} on-send]
|
||||||
|
[rn/view
|
||||||
|
{:ref send-ref
|
||||||
|
:style (when-not (or (seq (get @input/input-texts chat-id)) (seq images))
|
||||||
|
{:width 0
|
||||||
|
:right -100})}
|
||||||
|
[quo/button
|
||||||
|
{:icon true
|
||||||
|
:size 32
|
||||||
|
:accessibility-label :send-message-button
|
||||||
|
:on-press (fn []
|
||||||
|
(on-send)
|
||||||
|
(messages.list/scroll-to-bottom)
|
||||||
|
(rf/dispatch [:chat.ui/send-current-message]))}
|
||||||
|
:i/arrow-up]])
|
||||||
|
|
||||||
|
(defn reactions-button
|
||||||
|
[]
|
||||||
|
[not-implemented/not-implemented
|
||||||
|
[quo/button
|
||||||
|
{:icon true
|
||||||
|
:type :outline
|
||||||
|
:size 32} :i/reaction]])
|
||||||
|
|
||||||
|
(defn image-button
|
||||||
|
[chat-id]
|
||||||
|
[quo/button
|
||||||
|
{:on-press (fn []
|
||||||
|
(permissions/request-permissions
|
||||||
|
{:permissions [:read-external-storage :write-external-storage]
|
||||||
|
:on-allowed #(rf/dispatch
|
||||||
|
[:bottom-sheet/show-sheet
|
||||||
|
{:content (fn []
|
||||||
|
(photo-selector/photo-selector chat-id))}])
|
||||||
|
:on-denied (fn []
|
||||||
|
(background-timer/set-timeout
|
||||||
|
#(utils-old/show-popup (i18n/label :t/error)
|
||||||
|
(i18n/label
|
||||||
|
:t/external-storage-denied))
|
||||||
|
50))}))
|
||||||
|
:icon true
|
||||||
|
:type :outline
|
||||||
|
:size 32}
|
||||||
|
:i/image])
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[send-ref params insets chat-id images on-send]
|
||||||
|
[rn/view {:style (style/controls insets)}
|
||||||
|
[composer-images/images-list images]
|
||||||
|
[rn/view {:style {:flex-direction :row :margin-top 12}}
|
||||||
|
[image-button chat-id]
|
||||||
|
[rn/view {:width 12}]
|
||||||
|
[reactions-button]
|
||||||
|
[rn/view {:flex 1}]
|
||||||
|
[send-button send-ref params on-send]]])
|
42
src/status_im2/contexts/chat/messages/composer/style.cljs
Normal file
42
src/status_im2/contexts/chat/messages/composer/style.cljs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
(ns status-im2.contexts.chat.messages.composer.style
|
||||||
|
(:require [quo2.foundations.colors :as colors]
|
||||||
|
[status-im.utils.platform :as platform]))
|
||||||
|
|
||||||
|
(defn input-bottom-sheet
|
||||||
|
[window-height]
|
||||||
|
(merge {:border-top-left-radius 20
|
||||||
|
:border-top-right-radius 20
|
||||||
|
:position :absolute
|
||||||
|
:left 0
|
||||||
|
:right 0
|
||||||
|
:bottom (- window-height)
|
||||||
|
:height window-height
|
||||||
|
:flex 1
|
||||||
|
:background-color (colors/theme-colors colors/white colors/neutral-90)
|
||||||
|
:z-index 2}
|
||||||
|
(if platform/ios?
|
||||||
|
{:shadow-radius 16
|
||||||
|
:shadow-opacity 1
|
||||||
|
:shadow-color "rgba(9, 16, 28, 0.04)"
|
||||||
|
:shadow-offset {:width 0 :height -2}}
|
||||||
|
{:elevation 4})))
|
||||||
|
|
||||||
|
(defn bottom-sheet-handle
|
||||||
|
[]
|
||||||
|
{:width 32
|
||||||
|
:height 4
|
||||||
|
:background-color (colors/theme-colors colors/neutral-100 colors/white)
|
||||||
|
:opacity 0.05
|
||||||
|
:border-radius 100
|
||||||
|
:align-self :center
|
||||||
|
:margin-top 8})
|
||||||
|
|
||||||
|
(defn bottom-sheet-background
|
||||||
|
[window-height]
|
||||||
|
{:position :absolute
|
||||||
|
:left 0
|
||||||
|
:right 0
|
||||||
|
:bottom 0
|
||||||
|
:height window-height
|
||||||
|
:background-color colors/neutral-95-opa-70
|
||||||
|
:z-index 1})
|
250
src/status_im2/contexts/chat/messages/composer/view.cljs
Normal file
250
src/status_im2/contexts/chat/messages/composer/view.cljs
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
(ns status-im2.contexts.chat.messages.composer.view
|
||||||
|
(:require [clojure.string :as string]
|
||||||
|
[oops.core :refer [oget]]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[react-native.hooks :as hooks]
|
||||||
|
[react-native.gesture :as gesture]
|
||||||
|
[react-native.reanimated :as reanimated]
|
||||||
|
[react-native.background-timer :as background-timer]
|
||||||
|
[utils.re-frame :as rf]
|
||||||
|
[status-im2.contexts.chat.messages.composer.style :as style]
|
||||||
|
[status-im2.contexts.chat.messages.composer.controls.view :as controls]
|
||||||
|
[status-im.ui2.screens.chat.composer.edit.view :as edit]
|
||||||
|
[status-im.ui2.screens.chat.composer.input :as input]
|
||||||
|
[status-im.ui2.screens.chat.composer.mentions :as mentions]
|
||||||
|
[status-im.ui2.screens.chat.composer.reply :as reply]))
|
||||||
|
|
||||||
|
(def initial-content-height (atom nil))
|
||||||
|
(def keyboard-hiding? (atom false))
|
||||||
|
|
||||||
|
(defn minimize
|
||||||
|
[{:keys [min-y set-bg-opacity set-translate-y set-parent-height]}]
|
||||||
|
(set-bg-opacity 0)
|
||||||
|
(set-translate-y (- min-y))
|
||||||
|
(set-parent-height min-y))
|
||||||
|
|
||||||
|
(defn maximize
|
||||||
|
[{:keys [max-y set-bg-opacity set-translate-y set-parent-height max-parent-height]}]
|
||||||
|
(set-bg-opacity 1)
|
||||||
|
(set-translate-y (- max-y))
|
||||||
|
(set-parent-height max-parent-height))
|
||||||
|
|
||||||
|
(defn clean-and-minimize
|
||||||
|
[{:keys [chat-id refs] :as params}]
|
||||||
|
(input/clear-input chat-id refs)
|
||||||
|
(minimize params))
|
||||||
|
|
||||||
|
(def gesture-values (atom {}))
|
||||||
|
|
||||||
|
(defn get-bottom-sheet-gesture
|
||||||
|
[{:keys [translate-y refs keyboard-shown min-y max-y] :as params}]
|
||||||
|
(let [{:keys [text-input-ref]} refs]
|
||||||
|
(-> (gesture/gesture-pan)
|
||||||
|
(gesture/on-start
|
||||||
|
(fn [_]
|
||||||
|
(if keyboard-shown
|
||||||
|
(swap! gesture-values assoc :pan-y (reanimated/get-shared-value translate-y))
|
||||||
|
(input/input-focus text-input-ref))))
|
||||||
|
(gesture/on-update
|
||||||
|
(fn [evt]
|
||||||
|
(when keyboard-shown
|
||||||
|
(let [tY (oget evt "translationY")]
|
||||||
|
(swap! gesture-values assoc :dy (- tY (:pdy @gesture-values)))
|
||||||
|
(swap! gesture-values assoc :pdy tY)
|
||||||
|
(reanimated/set-shared-value
|
||||||
|
translate-y
|
||||||
|
(max (min (+ tY (:pan-y @gesture-values)) (- min-y)) (- max-y)))))))
|
||||||
|
(gesture/on-end
|
||||||
|
(fn [_]
|
||||||
|
(when keyboard-shown
|
||||||
|
(if (< (:dy @gesture-values) 0)
|
||||||
|
(maximize params)
|
||||||
|
(do
|
||||||
|
(reset! keyboard-hiding? true)
|
||||||
|
(minimize params)
|
||||||
|
(background-timer/set-timeout #(rf/dispatch [:dismiss-keyboard]) 200)))))))))
|
||||||
|
|
||||||
|
(defn update-y
|
||||||
|
[{:keys [max-parent-height set-bg-opacity keyboard-shown max-y set-translate-y set-parent-height
|
||||||
|
min-y chat-id]
|
||||||
|
:as params}]
|
||||||
|
(let [content-height (get @input/input-text-content-heights chat-id)
|
||||||
|
new-y (+ min-y
|
||||||
|
(if (and content-height @initial-content-height)
|
||||||
|
(- content-height
|
||||||
|
@initial-content-height)
|
||||||
|
0))]
|
||||||
|
(if (< new-y max-y)
|
||||||
|
(when keyboard-shown
|
||||||
|
(if (> new-y max-parent-height)
|
||||||
|
(set-bg-opacity 1)
|
||||||
|
(set-bg-opacity 0))
|
||||||
|
(set-translate-y (- new-y))
|
||||||
|
(set-parent-height (min new-y max-parent-height)))
|
||||||
|
(if keyboard-shown
|
||||||
|
(maximize params)
|
||||||
|
(set-bg-opacity 0)))))
|
||||||
|
|
||||||
|
(defn get-input-content-change
|
||||||
|
[{:keys [chat-id] :as params}]
|
||||||
|
(fn [evt]
|
||||||
|
(let [new-height (oget evt "nativeEvent.contentSize.height")]
|
||||||
|
(swap! input/input-text-content-heights assoc chat-id new-height)
|
||||||
|
(if @initial-content-height
|
||||||
|
(do
|
||||||
|
;;on Android when last symbol removed, height value is wrong, like 300px
|
||||||
|
(when (string/blank? (get @input/input-texts chat-id))
|
||||||
|
(swap! input/input-text-content-heights assoc chat-id @initial-content-height))
|
||||||
|
(update-y params))
|
||||||
|
(reset! initial-content-height new-height)))))
|
||||||
|
|
||||||
|
(defn mentions
|
||||||
|
[{:keys [refs suggestions max-y]} insets]
|
||||||
|
[:f>
|
||||||
|
(fn []
|
||||||
|
(let [translate-y (reanimated/use-shared-value 0)]
|
||||||
|
(rn/use-effect
|
||||||
|
(fn []
|
||||||
|
(reanimated/set-shared-value translate-y
|
||||||
|
(reanimated/with-timing (if (seq suggestions) 0 200)))))
|
||||||
|
[reanimated/view
|
||||||
|
{:style (reanimated/apply-animations-to-style
|
||||||
|
{:transform [{:translateY translate-y}]}
|
||||||
|
{:bottom (or (:bottom insets) 0)
|
||||||
|
:position :absolute
|
||||||
|
:z-index 5
|
||||||
|
:elevation 5
|
||||||
|
:max-height (/ max-y 2)})}
|
||||||
|
[mentions/autocomplete-mentions suggestions (:text-input-ref refs)]]))])
|
||||||
|
|
||||||
|
(defn effect!
|
||||||
|
[{:keys [keyboard-shown] :as params}]
|
||||||
|
(rn/use-effect
|
||||||
|
(fn []
|
||||||
|
(when (or (not @keyboard-hiding?)
|
||||||
|
(and @keyboard-hiding? (not keyboard-shown)))
|
||||||
|
(reset! keyboard-hiding? false)
|
||||||
|
(if (not keyboard-shown)
|
||||||
|
(minimize params)
|
||||||
|
(update-y params))))))
|
||||||
|
|
||||||
|
(defn prepare-params
|
||||||
|
[[refs window-height translate-y bg-opacity bg-bottom min-y max-y parent-height
|
||||||
|
max-parent-height chat-id suggestions reply edit images keyboard-shown]]
|
||||||
|
{:chat-id chat-id
|
||||||
|
:translate-y translate-y
|
||||||
|
:min-y min-y
|
||||||
|
:max-y max-y
|
||||||
|
:max-parent-height max-parent-height
|
||||||
|
:parent-height parent-height
|
||||||
|
:suggestions suggestions
|
||||||
|
:reply reply
|
||||||
|
:edit edit
|
||||||
|
:images images
|
||||||
|
:refs refs
|
||||||
|
:keyboard-shown keyboard-shown
|
||||||
|
:bg-opacity bg-opacity
|
||||||
|
:bg-bottom bg-bottom
|
||||||
|
:window-height window-height
|
||||||
|
:set-bg-opacity (fn [value]
|
||||||
|
(reanimated/set-shared-value bg-bottom (if (= value 1) 0 (- window-height)))
|
||||||
|
(reanimated/set-shared-value bg-opacity (reanimated/with-timing value)))
|
||||||
|
:set-translate-y (fn [value]
|
||||||
|
(reanimated/set-shared-value translate-y (reanimated/with-timing value)))
|
||||||
|
:set-parent-height (fn [value]
|
||||||
|
(reanimated/set-shared-value parent-height (reanimated/with-timing value)))})
|
||||||
|
|
||||||
|
;; IMPORTANT! PLEASE READ BEFORE MAKING CHANGES
|
||||||
|
|
||||||
|
;; 1) insets are not stable so we can't rely on the first values and we have to use it from render
|
||||||
|
;; function, so effect will be triggered a few times, for example first time it will be 0 and second
|
||||||
|
;; time 38 on ios, and 400 and 0 on Android
|
||||||
|
;; 2) for keyboard we use hooks, for some reason it triggers effect a few times with the same values,
|
||||||
|
;; also it changes value only when keyboard completely closed or opened, that's why its not visually
|
||||||
|
;; smooth, there is a small visible delay between keyboard and sheet animations
|
||||||
|
;; 3) when we minimize sheet and hide keyboard in `sheet-gesture` function, keyboard hook triggers
|
||||||
|
;; effect and there is a visual glitch when we have more than one line of text, so we use
|
||||||
|
;; `keyboard-hiding?` flag
|
||||||
|
;; 4) we store input content height in `input/input-text-content-heights` atom , we need it when chat
|
||||||
|
;; screen is reopened
|
||||||
|
(defn composer
|
||||||
|
[_ _]
|
||||||
|
(let [text-input-ref (rn/create-ref)
|
||||||
|
send-ref (rn/create-ref)
|
||||||
|
refs {:send-ref send-ref
|
||||||
|
:text-input-ref text-input-ref}]
|
||||||
|
(fn [chat-id insets]
|
||||||
|
[:f>
|
||||||
|
(fn []
|
||||||
|
(let [reply (rf/sub [:chats/reply-message])
|
||||||
|
edit (rf/sub [:chats/edit-message])
|
||||||
|
suggestions (rf/sub [:chat/mention-suggestions])
|
||||||
|
images (rf/sub [:chats/sending-image])
|
||||||
|
|
||||||
|
{window-height :height} (rn/use-window-dimensions)
|
||||||
|
{:keys [keyboard-shown keyboard-height]} (hooks/use-keyboard)
|
||||||
|
translate-y (reanimated/use-shared-value 0)
|
||||||
|
bg-opacity (reanimated/use-shared-value 0)
|
||||||
|
bg-bottom (reanimated/use-shared-value (- window-height))
|
||||||
|
|
||||||
|
suggestions? (and (seq suggestions)
|
||||||
|
keyboard-shown
|
||||||
|
(not @keyboard-hiding?))
|
||||||
|
|
||||||
|
max-y (- window-height
|
||||||
|
(- (if (> keyboard-height 0)
|
||||||
|
keyboard-height
|
||||||
|
360)
|
||||||
|
(:bottom insets))
|
||||||
|
46)
|
||||||
|
|
||||||
|
min-y (+ 108
|
||||||
|
(:bottom insets)
|
||||||
|
(if suggestions?
|
||||||
|
(min (/ max-y 2)
|
||||||
|
(+ 16
|
||||||
|
(* 46 (dec (count suggestions)))))
|
||||||
|
(+ 0
|
||||||
|
(when (or edit reply) 38)
|
||||||
|
(when (seq images) 80))))
|
||||||
|
|
||||||
|
parent-height (reanimated/use-shared-value min-y)
|
||||||
|
max-parent-height (Math/abs (- max-y 110 (:bottom insets)))
|
||||||
|
|
||||||
|
params
|
||||||
|
(prepare-params
|
||||||
|
[refs window-height translate-y bg-opacity bg-bottom min-y max-y parent-height
|
||||||
|
max-parent-height chat-id suggestions reply edit images keyboard-shown])
|
||||||
|
|
||||||
|
input-content-change (get-input-content-change params)
|
||||||
|
bottom-sheet-gesture (get-bottom-sheet-gesture params)]
|
||||||
|
(effect! params)
|
||||||
|
[reanimated/view
|
||||||
|
{:style (reanimated/apply-animations-to-style
|
||||||
|
{:height parent-height}
|
||||||
|
{})}
|
||||||
|
;;;;input
|
||||||
|
[gesture/gesture-detector {:gesture bottom-sheet-gesture}
|
||||||
|
[reanimated/view
|
||||||
|
{:style (reanimated/apply-animations-to-style
|
||||||
|
{:transform [{:translateY translate-y}]}
|
||||||
|
(style/input-bottom-sheet window-height))}
|
||||||
|
[rn/view {:style (style/bottom-sheet-handle)}]
|
||||||
|
[edit/edit-message-auto-focus-wrapper text-input-ref edit #(clean-and-minimize params)]
|
||||||
|
[reply/reply-message-auto-focus-wrapper text-input-ref reply]
|
||||||
|
[rn/view
|
||||||
|
{:style {:height (- max-y (- min-y 38))}}
|
||||||
|
[input/text-input
|
||||||
|
{:chat-id chat-id
|
||||||
|
:on-content-size-change input-content-change
|
||||||
|
:sending-image (seq images)
|
||||||
|
:refs refs}]]]]
|
||||||
|
(if suggestions?
|
||||||
|
[mentions params insets]
|
||||||
|
[controls/view send-ref params insets chat-id images #(clean-and-minimize params)])
|
||||||
|
;;;;black background
|
||||||
|
[reanimated/view
|
||||||
|
{:style (reanimated/apply-animations-to-style
|
||||||
|
{:opacity bg-opacity
|
||||||
|
:transform [{:translateY bg-bottom}]}
|
||||||
|
(style/bottom-sheet-background window-height))}]]))])))
|
@ -6,7 +6,7 @@
|
|||||||
[i18n.i18n :as i18n]
|
[i18n.i18n :as i18n]
|
||||||
[status-im2.setup.config :as config]
|
[status-im2.setup.config :as config]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.ui2.screens.chat.components.reply :as components.reply]
|
[status-im.ui2.screens.chat.components.reply.view :as components.reply]
|
||||||
[status-im2.common.not-implemented :as not-implemented]))
|
[status-im2.common.not-implemented :as not-implemented]))
|
||||||
|
|
||||||
(defn pin-message
|
(defn pin-message
|
||||||
|
@ -2,19 +2,19 @@
|
|||||||
(:require [quo2.core :as quo]
|
(:require [quo2.core :as quo]
|
||||||
[re-frame.db]
|
[re-frame.db]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
|
[react-native.safe-area :as safe-area]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im.ui2.screens.chat.composer.view :as composer]
|
[status-im2.contexts.chat.messages.composer.view :as composer]
|
||||||
[status-im.ui2.screens.chat.pin-limit-popover.view :as pin-limit-popover]
|
|
||||||
[status-im2.common.constants :as constants]
|
[status-im2.common.constants :as constants]
|
||||||
[status-im2.contexts.chat.messages.list.view :as messages.list]
|
[status-im2.contexts.chat.messages.list.view :as messages.list]
|
||||||
[status-im2.contexts.chat.messages.contact-requests.bottom-drawer :as
|
[status-im2.contexts.chat.messages.contact-requests.bottom-drawer :as
|
||||||
contact-requests.bottom-drawer]
|
contact-requests.bottom-drawer]
|
||||||
[status-im2.contexts.chat.messages.pin.banner.view :as pin.banner] ;;TODO move to status-im2
|
[status-im2.contexts.chat.messages.pin.banner.view :as pin.banner]
|
||||||
[status-im2.navigation.state :as navigation.state]
|
[status-im2.navigation.state :as navigation.state]
|
||||||
|
[status-im2.common.not-implemented :as not-implemented]
|
||||||
[utils.debounce :as debounce]
|
[utils.debounce :as debounce]
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
[status-im2.common.not-implemented :as not-implemented]
|
[status-im.ui2.screens.chat.pin-limit-popover.view :as pin-limit-popover]))
|
||||||
[quo2.foundations.colors :as colors]))
|
|
||||||
|
|
||||||
(defn navigate-back-handler
|
(defn navigate-back-handler
|
||||||
[]
|
[]
|
||||||
@ -64,30 +64,25 @@
|
|||||||
|
|
||||||
(defn chat-render
|
(defn chat-render
|
||||||
[]
|
[]
|
||||||
(let [{:keys [chat-id
|
(let [;;NOTE: we want to react only on these fields, do not use full chat map here
|
||||||
contact-request-state
|
{:keys [chat-id contact-request-state show-input?] :as chat}
|
||||||
show-input?]
|
|
||||||
:as chat}
|
|
||||||
(rf/sub [:chats/current-chat-chat-view])]
|
(rf/sub [:chats/current-chat-chat-view])]
|
||||||
[rn/keyboard-avoiding-view {:style {:position :relative :flex 1}}
|
[safe-area/consumer
|
||||||
[rn/view
|
(fn [insets]
|
||||||
{:style {:position :absolute
|
[rn/keyboard-avoiding-view
|
||||||
:top 56
|
{:style {:position :relative :flex 1}
|
||||||
:z-index 2
|
:keyboardVerticalOffset (- (:bottom insets))}
|
||||||
:background-color (colors/theme-colors colors/white colors/neutral-100)
|
[page-nav]
|
||||||
:width "100%"}}
|
[pin.banner/banner chat-id]
|
||||||
|
[not-implemented/not-implemented
|
||||||
|
[pin-limit-popover/pin-limit-popover chat-id]]
|
||||||
|
[messages.list/messages-list {:chat chat :show-input? show-input?}]
|
||||||
|
(cond (and (not show-input?)
|
||||||
|
contact-request-state)
|
||||||
|
[contact-requests.bottom-drawer/view chat-id contact-request-state]
|
||||||
|
|
||||||
[pin.banner/banner chat-id]
|
show-input?
|
||||||
[not-implemented/not-implemented
|
[composer/composer chat-id insets])])]))
|
||||||
[pin-limit-popover/pin-limit-popover chat-id]]]
|
|
||||||
[page-nav]
|
|
||||||
[messages.list/messages-list {:chat chat :show-input? show-input?}]
|
|
||||||
(cond (and (not show-input?)
|
|
||||||
contact-request-state)
|
|
||||||
[contact-requests.bottom-drawer/view chat-id contact-request-state]
|
|
||||||
|
|
||||||
show-input?
|
|
||||||
[composer/composer chat-id])]))
|
|
||||||
|
|
||||||
(defn chat
|
(defn chat
|
||||||
[]
|
[]
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
[quo2.core :as quo]
|
[quo2.core :as quo]
|
||||||
[quo2.foundations.colors :as colors]
|
[quo2.foundations.colors :as colors]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
|
[react-native.blur :as blur]
|
||||||
[react-native.platform :as platform]
|
[react-native.platform :as platform]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im2.common.constants :as constants]
|
[status-im2.common.constants :as constants]
|
||||||
@ -307,7 +308,7 @@
|
|||||||
[channel-heights first-channel-height]
|
[channel-heights first-channel-height]
|
||||||
(fn [scroll-height]
|
(fn [scroll-height]
|
||||||
(when (> scroll-height @first-channel-height)
|
(when (> scroll-height @first-channel-height)
|
||||||
[rn/blur-view
|
[blur/view
|
||||||
{:blur-amount 32
|
{:blur-amount 32
|
||||||
:blur-type :xlight
|
:blur-type :xlight
|
||||||
:overlay-color (if platform/ios? colors/white-opa-70 :transparent)
|
:overlay-color (if platform/ios? colors/white-opa-70 :transparent)
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
[react-native.reanimated :as reanimated]
|
[react-native.reanimated :as reanimated]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im.async-storage.core :as async-storage]
|
[status-im.async-storage.core :as async-storage]
|
||||||
[status-im2.contexts.shell.constants :as shell.constants] ;;TODO remove when not used anymore
|
[status-im2.contexts.shell.constants :as shell.constants])) ;;TODO remove when not used anymore
|
||||||
))
|
|
||||||
|
|
||||||
;; Atoms
|
;; Atoms
|
||||||
(def selected-stack-id (atom nil))
|
(def selected-stack-id (atom nil))
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
(ns status-im2.navigation.view
|
(ns status-im2.navigation.view
|
||||||
(:require [oops.core :refer [oget]]
|
(:require [quo2.foundations.colors :as colors]
|
||||||
[quo2.foundations.colors :as colors]
|
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.safe-area :as safe-area]
|
[react-native.safe-area :as safe-area]
|
||||||
@ -38,19 +37,14 @@
|
|||||||
(concat screens/components)))
|
(concat screens/components)))
|
||||||
|
|
||||||
(defn wrapped-screen-style
|
(defn wrapped-screen-style
|
||||||
[{:keys [insets style]} insets-obj]
|
[screen-insets safe-insets]
|
||||||
(merge
|
(merge
|
||||||
{:flex 1
|
{:flex 1
|
||||||
:background-color (colors/theme-colors colors/white colors/neutral-100)}
|
:background-color (colors/theme-colors colors/white colors/neutral-100)}
|
||||||
style
|
(when (get screen-insets :bottom)
|
||||||
(when (get insets :bottom)
|
{:padding-bottom (:bottom safe-insets)})
|
||||||
{:padding-bottom (+ (oget insets-obj "bottom")
|
(when (get screen-insets :top true)
|
||||||
(get style :padding-bottom)
|
{:padding-top (:top safe-insets)})))
|
||||||
(get style :padding-vertical))})
|
|
||||||
(when (get insets :top true)
|
|
||||||
{:padding-top (+ (oget insets-obj "top")
|
|
||||||
(get style :padding-top)
|
|
||||||
(get style :padding-vertical))})))
|
|
||||||
|
|
||||||
(defn inactive
|
(defn inactive
|
||||||
[]
|
[]
|
||||||
@ -75,16 +69,13 @@
|
|||||||
screens)
|
screens)
|
||||||
(keyword key))]
|
(keyword key))]
|
||||||
^{:key (str "root" key @reloader/cnt)}
|
^{:key (str "root" key @reloader/cnt)}
|
||||||
[safe-area/safe-area-provider
|
[safe-area/provider
|
||||||
[safe-area/safe-area-consumer
|
[safe-area/consumer
|
||||||
(fn [safe-insets]
|
(fn [safe-insets]
|
||||||
(reagent/as-element
|
[rn/view
|
||||||
[rn/view
|
{:style (wrapped-screen-style insets safe-insets)}
|
||||||
{:style (wrapped-screen-style
|
[inactive]
|
||||||
{:insets insets}
|
[component]])]
|
||||||
safe-insets)}
|
|
||||||
[inactive]
|
|
||||||
[component]]))]
|
|
||||||
(when js/goog.DEBUG
|
(when js/goog.DEBUG
|
||||||
[reloader/reload-view])]))))
|
[reloader/reload-view])]))))
|
||||||
|
|
||||||
@ -99,7 +90,7 @@
|
|||||||
(reagent/reactify-component
|
(reagent/reactify-component
|
||||||
(fn []
|
(fn []
|
||||||
^{:key (str "popover" @reloader/cnt)}
|
^{:key (str "popover" @reloader/cnt)}
|
||||||
[safe-area/safe-area-provider
|
[safe-area/provider
|
||||||
[inactive]
|
[inactive]
|
||||||
[popover/popover]
|
[popover/popover]
|
||||||
(when js/goog.DEBUG
|
(when js/goog.DEBUG
|
||||||
@ -116,7 +107,7 @@
|
|||||||
(reagent/reactify-component
|
(reagent/reactify-component
|
||||||
(fn []
|
(fn []
|
||||||
^{:key (str "visibility-status-popover" @reloader/cnt)}
|
^{:key (str "visibility-status-popover" @reloader/cnt)}
|
||||||
[safe-area/safe-area-provider
|
[safe-area/provider
|
||||||
[inactive]
|
[inactive]
|
||||||
[visibility-status-views/visibility-status-popover]
|
[visibility-status-views/visibility-status-popover]
|
||||||
(when js/goog.DEBUG
|
(when js/goog.DEBUG
|
||||||
@ -126,7 +117,7 @@
|
|||||||
(reagent/reactify-component
|
(reagent/reactify-component
|
||||||
(fn []
|
(fn []
|
||||||
^{:key (str "sheet" @reloader/cnt)}
|
^{:key (str "sheet" @reloader/cnt)}
|
||||||
[safe-area/safe-area-provider
|
[safe-area/provider
|
||||||
[inactive]
|
[inactive]
|
||||||
[bottom-sheets/bottom-sheet]
|
[bottom-sheets/bottom-sheet]
|
||||||
(when js/goog.DEBUG
|
(when js/goog.DEBUG
|
||||||
@ -138,7 +129,7 @@
|
|||||||
(reagent/reactify-component
|
(reagent/reactify-component
|
||||||
(fn []
|
(fn []
|
||||||
^{:key (str "signing-sheet" @reloader/cnt)}
|
^{:key (str "signing-sheet" @reloader/cnt)}
|
||||||
[safe-area/safe-area-provider
|
[safe-area/provider
|
||||||
[inactive]
|
[inactive]
|
||||||
[signing/signing]
|
[signing/signing]
|
||||||
(when js/goog.DEBUG
|
(when js/goog.DEBUG
|
||||||
@ -148,7 +139,7 @@
|
|||||||
(reagent/reactify-component
|
(reagent/reactify-component
|
||||||
(fn []
|
(fn []
|
||||||
^{:key (str "select-acc-sheet" @reloader/cnt)}
|
^{:key (str "select-acc-sheet" @reloader/cnt)}
|
||||||
[safe-area/safe-area-provider
|
[safe-area/provider
|
||||||
[inactive]
|
[inactive]
|
||||||
[wallet.send.views/select-account]
|
[wallet.send.views/select-account]
|
||||||
(when js/goog.DEBUG
|
(when js/goog.DEBUG
|
||||||
@ -158,7 +149,7 @@
|
|||||||
(reagent/reactify-component
|
(reagent/reactify-component
|
||||||
(fn []
|
(fn []
|
||||||
^{:key (str "wallet-connect-sheet" @reloader/cnt)}
|
^{:key (str "wallet-connect-sheet" @reloader/cnt)}
|
||||||
[safe-area/safe-area-provider
|
[safe-area/provider
|
||||||
[inactive]
|
[inactive]
|
||||||
[wallet-connect/wallet-connect-proposal-sheet]
|
[wallet-connect/wallet-connect-proposal-sheet]
|
||||||
(when js/goog.DEBUG
|
(when js/goog.DEBUG
|
||||||
@ -168,7 +159,7 @@
|
|||||||
(reagent/reactify-component
|
(reagent/reactify-component
|
||||||
(fn []
|
(fn []
|
||||||
^{:key (str "wallet-connect-success-sheet" @reloader/cnt)}
|
^{:key (str "wallet-connect-success-sheet" @reloader/cnt)}
|
||||||
[safe-area/safe-area-provider
|
[safe-area/provider
|
||||||
[inactive]
|
[inactive]
|
||||||
[wallet-connect/wallet-connect-success-sheet-view]
|
[wallet-connect/wallet-connect-success-sheet-view]
|
||||||
(when js/goog.DEBUG
|
(when js/goog.DEBUG
|
||||||
@ -178,7 +169,7 @@
|
|||||||
(reagent/reactify-component
|
(reagent/reactify-component
|
||||||
(fn []
|
(fn []
|
||||||
^{:key (str "wallet-connect-app-management-sheet" @reloader/cnt)}
|
^{:key (str "wallet-connect-app-management-sheet" @reloader/cnt)}
|
||||||
[safe-area/safe-area-provider
|
[safe-area/provider
|
||||||
[inactive]
|
[inactive]
|
||||||
[wallet-connect/wallet-connect-app-management-sheet-view]
|
[wallet-connect/wallet-connect-app-management-sheet-view]
|
||||||
(when js/goog.DEBUG
|
(when js/goog.DEBUG
|
||||||
|
@ -132,7 +132,7 @@
|
|||||||
(get chats current-chat-id)))
|
(get chats current-chat-id)))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:chats/current-chat-inputs
|
:chats/current-chat-input
|
||||||
:<- [:chats/current-chat-id]
|
:<- [:chats/current-chat-id]
|
||||||
:<- [:chat/inputs]
|
:<- [:chat/inputs]
|
||||||
(fn [[chat-id inputs]]
|
(fn [[chat-id inputs]]
|
||||||
@ -285,19 +285,19 @@
|
|||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:chats/reply-message
|
:chats/reply-message
|
||||||
:<- [:chats/current-chat-inputs]
|
:<- [:chats/current-chat-input]
|
||||||
(fn [{:keys [metadata]}]
|
(fn [{:keys [metadata]}]
|
||||||
(:responding-to-message metadata)))
|
(:responding-to-message metadata)))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:chats/edit-message
|
:chats/edit-message
|
||||||
:<- [:chats/current-chat-inputs]
|
:<- [:chats/current-chat-input]
|
||||||
(fn [{:keys [metadata]}]
|
(fn [{:keys [metadata]}]
|
||||||
(:editing-message metadata)))
|
(:editing-message metadata)))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:chats/sending-contact-request
|
:chats/sending-contact-request
|
||||||
:<- [:chats/current-chat-inputs]
|
:<- [:chats/current-chat-input]
|
||||||
(fn [{:keys [metadata]}]
|
(fn [{:keys [metadata]}]
|
||||||
(:sending-contact-request metadata)))
|
(:sending-contact-request metadata)))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user