Compare commits
19
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f33335517 | ||
|
|
a1a49bb9d5 | ||
|
|
bc4e80352c | ||
|
|
7f5cbc6504 | ||
|
|
d496645725 | ||
|
|
1fb9de6f77 | ||
|
|
29a0ada60a | ||
|
|
485ced2028 | ||
|
|
ee7d11c89e | ||
|
|
9abf680571 | ||
|
|
53fb04719f | ||
|
|
9884232134 | ||
|
|
fb20a2b712 | ||
|
|
2d9d98654d | ||
|
|
94ba7284f8 | ||
|
|
121d1aded5 | ||
|
|
6bc3757c42 | ||
|
|
221809a137 | ||
|
|
6055d27f4c |
@@ -319,7 +319,7 @@ run-visual-test-ios: XCODE_DERIVED_DATA := $(HOME)/Library/Developer/Xcode/Deriv
|
||||
run-visual-test-ios: APPLICATION_NAME := StatusIm-brfnruzfrkkycpbndmdoeyrigthc
|
||||
run-visual-test-ios: export TEST_BINARY_PATH := $(XCODE_DERIVED_DATA)/$(APPLICATION_NAME)/Build/Products/Debug-iphonesimulator/StatusIm.app
|
||||
run-visual-test-ios: ##@test Run tests once in NodeJS
|
||||
detox test --configuration ios.sim.debug
|
||||
detox test --configuration ios.sim.debug
|
||||
|
||||
component-test-watch: export TARGET := clojure
|
||||
component-test-watch: export COMPONENT_TEST := true
|
||||
|
||||
@@ -82,6 +82,8 @@
|
||||
:output-dir "target/test"
|
||||
:optimizations :simple
|
||||
:target :node-test
|
||||
;; When running tests without a REPL you can uncomment the below line to `make test-watch` a specific file
|
||||
;:ns-regexp "status-im.chat.models-test$"
|
||||
:main status-im.test-runner/main
|
||||
;; set :ui-driven to true to let shadow-cljs inject node-repl
|
||||
:ui-driven true
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
(defn download-image-http [base64-uri on-success]
|
||||
(-> (.config ReactNativeBlobUtil (clj->js {:trusty platform/ios?
|
||||
:path temp-image-url}))
|
||||
:path temp-image-url}))
|
||||
(.fetch "GET" base64-uri)
|
||||
(.then #(on-success (.path %)))
|
||||
(.catch #(log/error "could not save image"))))
|
||||
@@ -77,8 +77,8 @@
|
||||
(fn [chat-id]
|
||||
(react/show-image-picker
|
||||
(fn [^js images]
|
||||
;; NOTE(Ferossgp): Because we can't highlight the already selected images inside
|
||||
;; gallery, we just clean previous state and set all newly picked images
|
||||
;; NOTE(Ferossgp): Because we can't highlight the already selected images inside
|
||||
;; gallery, we just clean previous state and set all newly picked images
|
||||
(when (and platform/ios? (pos? (count images)))
|
||||
(re-frame/dispatch [:chat.ui/clear-sending-images chat-id]))
|
||||
(doseq [^js result (if platform/ios?
|
||||
@@ -86,8 +86,8 @@
|
||||
[images])]
|
||||
(resize-and-call (.-path result)
|
||||
#(re-frame/dispatch [:chat.ui/image-selected chat-id (result->id result) %]))))
|
||||
;; NOTE(Ferossgp): On android you cannot set max limit on images, when a user
|
||||
;; selects too many images the app crashes.
|
||||
;; NOTE(Ferossgp): On android you cannot set max limit on images, when a user
|
||||
;; selects too many images the app crashes.
|
||||
{:media-type "photo"
|
||||
:multiple platform/ios?})))
|
||||
|
||||
@@ -100,13 +100,16 @@
|
||||
|
||||
(re-frame/reg-fx
|
||||
::camera-roll-get-photos
|
||||
(fn [num]
|
||||
(fn [[num end-cursor]]
|
||||
(permissions/request-permissions
|
||||
{:permissions [:read-external-storage]
|
||||
:on-allowed (fn []
|
||||
(-> (.getPhotos CameraRoll #js {:first num :assetType "Photos" :groupTypes "All"})
|
||||
(.then #(re-frame/dispatch [:on-camera-roll-get-photos (:edges (types/js->clj %))]))
|
||||
(.catch #(log/warn "could not get cameraroll photos"))))})))
|
||||
(-> (if end-cursor
|
||||
(.getPhotos CameraRoll #js {:first num :after end-cursor :assetType "Photos" :groupTypes "All"})
|
||||
(.getPhotos CameraRoll #js {:first num :assetType "Photos" :groupTypes "All"}))
|
||||
(.then #(let [response (types/js->clj %)]
|
||||
(re-frame/dispatch [:on-camera-roll-get-photos (:edges response) (:page_info response) end-cursor])))
|
||||
(.catch #(log/warn "could not get camera roll photos"))))})))
|
||||
|
||||
(fx/defn image-captured
|
||||
{:events [:chat.ui/image-captured]}
|
||||
@@ -119,13 +122,23 @@
|
||||
|
||||
(fx/defn camera-roll-get-photos
|
||||
{:events [:chat.ui/camera-roll-get-photos]}
|
||||
[_ num]
|
||||
{::camera-roll-get-photos num})
|
||||
[_ num end-cursor]
|
||||
{::camera-roll-get-photos [num end-cursor]})
|
||||
|
||||
(fx/defn camera-roll-loading-more
|
||||
{:events [:chat.ui/camera-roll-loading-more]}
|
||||
[{:keys [db]} is-loading]
|
||||
{:db (assoc db :camera-roll/loading-more is-loading)})
|
||||
|
||||
(fx/defn on-camera-roll-get-photos
|
||||
{:events [:on-camera-roll-get-photos]}
|
||||
[{db :db} photos]
|
||||
{:db (assoc db :camera-roll-photos (mapv #(get-in % [:node :image :uri]) photos))})
|
||||
[{:keys [db] :as cofx} photos page-info end-cursor]
|
||||
(let [photos_x (when end-cursor (:camera-roll/photos db))]
|
||||
{:db (-> db
|
||||
(assoc :camera-roll/photos (concat photos_x (map #(get-in % [:node :image :uri]) photos)))
|
||||
(assoc :camera-roll/end-cursor (:end_cursor page-info))
|
||||
(assoc :camera-roll/has-next-page (:has_next_page page-info))
|
||||
(assoc :camera-roll/loading-more false))}))
|
||||
|
||||
(fx/defn clear-sending-images
|
||||
{:events [:chat.ui/clear-sending-images]}
|
||||
|
||||
@@ -173,9 +173,11 @@
|
||||
|
||||
(defn build-image-messages
|
||||
[{db :db} chat-id]
|
||||
(let [images (get-in db [:chat/inputs chat-id :metadata :sending-image])]
|
||||
(let [images (get-in db [:chat/inputs chat-id :metadata :sending-image])
|
||||
album-id (str (random-uuid))]
|
||||
(mapv (fn [[_ {:keys [uri]}]]
|
||||
{:chat-id chat-id
|
||||
:album-id album-id
|
||||
:content-type constants/content-type-image
|
||||
:image-path (utils/safe-replace uri #"file://" "")
|
||||
:text (i18n/label :t/update-to-see-image {"locale" "en"})})
|
||||
|
||||
@@ -97,6 +97,24 @@
|
||||
:params [community-id]
|
||||
:on-success #(re-frame/dispatch [::mark-all-read-in-community-successful %])}]}))
|
||||
|
||||
|
||||
|
||||
(defn find-albums [messages]
|
||||
(let [albums-count (atom #{})]
|
||||
(doseq [message messages]
|
||||
(let [album-id (:album-id (:content (val message)))]
|
||||
;(println "ALBUMID" album-id (get @albums-count album-id))
|
||||
(when album-id
|
||||
(if (get @albums-count album-id)
|
||||
;(update-in albums-count album-id #(inc 1))
|
||||
;(assoc albums-count album-id 1)
|
||||
))
|
||||
(if (> (get @albums-count album-id) 3)
|
||||
;(println "COMPLETED AN ALBUMXXXX" (get @albums-count album-id))
|
||||
;(println "NO ALBUMXX" @albums-count)
|
||||
))))
|
||||
messages)
|
||||
|
||||
(fx/defn messages-loaded
|
||||
"Loads more messages for current chat"
|
||||
{:events [::messages-loaded]}
|
||||
@@ -108,7 +126,7 @@
|
||||
;; We remove those messages that are already loaded, as we might get some duplicates
|
||||
{:keys [all-messages new-messages senders contacts]}
|
||||
(reduce (fn [{:keys [all-messages] :as acc}
|
||||
{:keys [message-id from]
|
||||
{:keys [message-id from content]
|
||||
:as message}]
|
||||
(cond-> acc
|
||||
(not (get-in db [:chats chat-id :users from]))
|
||||
@@ -124,8 +142,10 @@
|
||||
:contacts {}
|
||||
:new-messages []}
|
||||
messages)
|
||||
;result (find-albums all-messages)
|
||||
current-clock-value (get-in db [:pagination-info chat-id :cursor-clock-value])
|
||||
clock-value (when cursor (cursor->clock-value cursor))]
|
||||
;(println "ccc222" (count all-messages) (count new-messages) (count already-loaded-messages))
|
||||
{:dispatch [:chat/add-senders-to-chat-users (vals senders)]
|
||||
:db (-> db
|
||||
(update-in [:pagination-info chat-id :cursor-clock-value]
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
(ns status-im.chat.models-test
|
||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||
[status-im.utils.clocks :as utils.clocks]
|
||||
[status-im.chat.models :as chat]))
|
||||
[status-im.chat.models :as chat]
|
||||
[status-im.chat.models.images :as images]))
|
||||
|
||||
(deftest clear-history-test
|
||||
(let [chat-id "1"
|
||||
@@ -91,3 +92,8 @@
|
||||
(testing "Pagination info should be reset on navigation"
|
||||
(let [res (chat/navigate-to-chat-nav2 {:db db} chat-id false)]
|
||||
(is (nil? (get-in res [:db :pagination-info chat-id :all-loaded?])))))))
|
||||
|
||||
(deftest camera-roll-loading-more-test
|
||||
(let [cofx {:db {:camera-roll/loading-more false}}]
|
||||
(is (= {:db {:camera-roll/loading-more true}}
|
||||
(images/camera-roll-loading-more cofx true)))))
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
(assoc :content {:chat-id (:chatId message)
|
||||
:text (:text message)
|
||||
:image (:image message)
|
||||
:album-id (:albumId message)
|
||||
:sticker (:sticker message)
|
||||
:ens-name (:ensName message)
|
||||
:line-count (:lineCount message)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(defn build-message [{:keys [chat-id
|
||||
album-id
|
||||
text
|
||||
response-to
|
||||
ens-name
|
||||
@@ -16,6 +17,7 @@
|
||||
sticker
|
||||
content-type]}]
|
||||
{:chatId chat-id
|
||||
:albumId album-id
|
||||
:text text
|
||||
:responseTo response-to
|
||||
:ensName ens-name
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
[quo/radio {:value true}]])]]))
|
||||
|
||||
(defview photos []
|
||||
(letsubs [camera-roll-photos [:camera-roll-photos]
|
||||
(letsubs [camera-roll-photos [:camera-roll/photos]
|
||||
selected [:chats/sending-image]
|
||||
panel-height (reagent/atom nil)]
|
||||
[react/view {:style {:flex 1
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
:source {:uri uri}}]])
|
||||
|
||||
(defview photos []
|
||||
(letsubs [camera-roll-photos [:camera-roll-photos]]
|
||||
(letsubs [camera-roll-photos [:camera-roll/photos]]
|
||||
{:component-did-mount #(re-frame/dispatch [:chat.ui/camera-roll-get-photos 20])}
|
||||
[react/scroll-view {:horizontal true
|
||||
:style {:max-height 88}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
(ns status-im.ui2.screens.chat.composer.composer-images.composer-images
|
||||
(:require [react-native.core :as rn]
|
||||
[status-im.ui2.screens.chat.composer.style :as style]
|
||||
[quo2.core :as quo2]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[re-frame.core :as rf]))
|
||||
|
||||
(defn image [item]
|
||||
[rn/view
|
||||
[rn/image {:source {:uri (first item)}
|
||||
:style style/small-image}]
|
||||
[rn/touchable-opacity
|
||||
{:on-press (fn [] (rf/dispatch [:chat.ui/image-unselected (first item)]))
|
||||
:style style/remove-photo-container}
|
||||
[quo2/icon :i/close {:color colors/white :size 12}]]])
|
||||
|
||||
(defn images-list [images]
|
||||
[rn/flat-list {:key-fn first
|
||||
:render-fn image
|
||||
:data images
|
||||
:horizontal true
|
||||
:style {:bottom 50 :position :absolute :z-index 5}
|
||||
:content-container-style {:padding-horizontal 20 :margin-top 12}
|
||||
:separator [rn/view {:style {:width 12}}]}])
|
||||
@@ -79,3 +79,20 @@
|
||||
(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})
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
[re-frame.core :as re-frame]
|
||||
[quo.components.safe-area :as safe-area]
|
||||
[quo.react-native :as rn :refer [navigation-const]]
|
||||
[status-im.ui2.screens.chat.composer.style :as styles]
|
||||
[status-im.ui2.screens.chat.composer.reply :as reply]
|
||||
[quo2.components.buttons.button :as quo2.button]
|
||||
[status-im.utils.handlers :refer [<sub]]
|
||||
@@ -17,7 +16,10 @@
|
||||
[status-im.ui2.screens.chat.photo-selector.view :as photo-selector]
|
||||
[status-im.utils.utils :as utils]
|
||||
[i18n.i18n :as i18n]
|
||||
[status-im.ui2.screens.chat.composer.edit.view :as edit]))
|
||||
[status-im.ui2.screens.chat.composer.edit.view :as edit]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im.ui2.screens.chat.composer.composer-images.composer-images :as composer-images]
|
||||
[status-im.ui2.screens.chat.composer.style :as style]))
|
||||
|
||||
(defn calculate-y [context min-y max-y added-value chat-id]
|
||||
(let [input-text (:input-text (get (<sub [:chat/inputs]) chat-id))
|
||||
@@ -41,8 +43,9 @@
|
||||
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]
|
||||
(defn get-y-value [context min-y max-y added-value max-height chat-id suggestions reply images]
|
||||
(let [y (calculate-y context min-y max-y added-value chat-id)
|
||||
y (+ y (when (seq images) 80))
|
||||
y-with-mentions (calculate-y-with-mentions y max-y max-height chat-id suggestions reply)]
|
||||
(+ y (when (seq suggestions) y-with-mentions))))
|
||||
|
||||
@@ -59,33 +62,33 @@
|
||||
(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))))
|
||||
(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))))))
|
||||
(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 :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
|
||||
(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)
|
||||
(re-frame/dispatch [:dismiss-keyboard]))))))))
|
||||
(fn [_]
|
||||
(when keyboard-shown
|
||||
(if (< (:dy @context) 0)
|
||||
(do
|
||||
(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
|
||||
(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)
|
||||
(re-frame/dispatch [:dismiss-keyboard]))))))))
|
||||
|
||||
(defn get-input-content-change [context translate-y shared-height max-height set-bg-opacity keyboard-shown min-y max-y]
|
||||
(fn [evt]
|
||||
@@ -111,19 +114,19 @@
|
||||
(swap! context assoc :y new-y)
|
||||
(when keyboard-shown
|
||||
(reanimated/set-shared-value
|
||||
translate-y
|
||||
(reanimated/with-timing (- new-y)))
|
||||
translate-y
|
||||
(reanimated/with-timing (- new-y)))
|
||||
(reanimated/set-shared-value
|
||||
shared-height
|
||||
(reanimated/with-timing (min new-y max-height)))))
|
||||
shared-height
|
||||
(reanimated/with-timing (min new-y max-height)))))
|
||||
(do
|
||||
(swap! context assoc :state :max)
|
||||
(swap! context assoc :y max-y)
|
||||
(when keyboard-shown
|
||||
(set-bg-opacity 1)
|
||||
(reanimated/set-shared-value
|
||||
translate-y
|
||||
(reanimated/with-timing (- max-y)))))))))))
|
||||
translate-y
|
||||
(reanimated/with-timing (- max-y)))))))))))
|
||||
|
||||
(defn composer [chat-id]
|
||||
[safe-area/consumer
|
||||
@@ -146,13 +149,14 @@
|
||||
(let [reply (<sub [:chats/reply-message])
|
||||
edit (<sub [:chats/edit-message])
|
||||
suggestions (<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))
|
||||
y (get-y-value context min-y max-y added-value max-height chat-id suggestions reply)
|
||||
y (get-y-value context min-y max-y added-value max-height chat-id suggestions reply images)
|
||||
translate-y (reanimated/use-shared-value 0)
|
||||
shared-height (reanimated/use-shared-value min-y)
|
||||
bg-opacity (reanimated/use-shared-value 0)
|
||||
@@ -179,15 +183,15 @@
|
||||
(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})}
|
||||
{: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}]}
|
||||
(styles/input-bottom-sheet window-height))}
|
||||
{:transform [{:translateY translate-y}]}
|
||||
(style/input-bottom-sheet window-height))}
|
||||
;handle
|
||||
[rn/view {:style (styles/bottom-sheet-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)}}
|
||||
@@ -199,16 +203,16 @@
|
||||
:set-active-panel #()}]]]]
|
||||
;CONTROLS
|
||||
(when-not (seq suggestions)
|
||||
[rn/view {:style (styles/bottom-sheet-controls insets)}
|
||||
[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 #(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||
{:content [photo-selector/photo-selector]}])
|
||||
:on-denied (fn []
|
||||
(utils/set-timeout
|
||||
#(utils/show-popup (i18n/label :t/error)
|
||||
(i18n/label :t/external-storage-denied)) 50))}))
|
||||
{:permissions [:read-external-storage :write-external-storage]
|
||||
:on-allowed #(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||
{:content [photo-selector/photo-selector]}])
|
||||
: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]
|
||||
@@ -229,7 +233,8 @@
|
||||
:i/arrow-up]]])
|
||||
;black background
|
||||
[reanimated/view {:style (reanimated/apply-animations-to-style
|
||||
{:opacity bg-opacity
|
||||
:transform [{:translateY bg-bottom}]}
|
||||
(styles/bottom-sheet-background window-height))}]
|
||||
{: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]]))])))])
|
||||
|
||||
@@ -1,20 +1,9 @@
|
||||
(ns status-im.ui2.screens.chat.photo-selector.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn 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})
|
||||
|
||||
(defn gradient-container [safe-area]
|
||||
{:width "100%"
|
||||
:height (+ (:bottom safe-area) 161)
|
||||
:height (+ (:bottom safe-area) 65)
|
||||
:position :absolute
|
||||
:bottom 0})
|
||||
|
||||
|
||||
@@ -13,18 +13,6 @@
|
||||
|
||||
(def selected (reagent/atom []))
|
||||
|
||||
(defn small-image [item]
|
||||
[rn/view
|
||||
[rn/image {:source {:uri item}
|
||||
:style {:width 56
|
||||
:height 56
|
||||
:border-radius 8
|
||||
:margin-bottom 20}}]
|
||||
[rn/touchable-opacity
|
||||
{:on-press (fn [] (reset! selected (vec (remove #(= % item) @selected))))
|
||||
:style (style/remove-photo-container)}
|
||||
[quo2/icon :i/close {:color colors/white :size 12}]]])
|
||||
|
||||
(defn bottom-gradient []
|
||||
[:f>
|
||||
(fn []
|
||||
@@ -35,24 +23,12 @@
|
||||
:start {:x 0 :y 1}
|
||||
:end {:x 0 :y 0}
|
||||
:style (style/gradient-container safe-area)}
|
||||
[rn/flat-list {:key-fn (fn [item] item)
|
||||
:render-fn small-image
|
||||
:data @selected
|
||||
:horizontal true
|
||||
:content-container-style {:padding-horizontal 20 :margin-top 12}
|
||||
:separator [rn/view {:style {:width 12}}]}]
|
||||
[rn/view {:style (style/buttons-container safe-area)}
|
||||
[quo2/button {:type :grey
|
||||
:style {:flex 0.48}
|
||||
:on-press #(js/alert "Add text: to be implemented")}
|
||||
(i18n/label :t/add-text)]
|
||||
[quo2/button {:style {:flex 0.48}
|
||||
:before :send
|
||||
:on-press #(do
|
||||
(rf/dispatch [:chat.ui/send-current-message])
|
||||
(reset! selected [])
|
||||
(rf/dispatch [:bottom-sheet/hide]))}
|
||||
(str (i18n/label :t/send) " " (when (> (count @selected) 1) (count @selected)))]]])))])
|
||||
[quo2/button {:style {:align-self :stretch
|
||||
:margin-horizontal 20}
|
||||
:on-press #(do
|
||||
(reset! selected [])
|
||||
(rf/dispatch [:bottom-sheet/hide]))}
|
||||
(i18n/label :t/confirm-selection)]])))])
|
||||
|
||||
(defn clear-button []
|
||||
(when (pos? (count @selected))
|
||||
@@ -78,14 +54,21 @@
|
||||
(when (some #{item} @selected)
|
||||
[info-count/info-count (+ (utils/first-index #(= item %) @selected) 1) (style/image-count)])])
|
||||
|
||||
(defn on-end-reached [end-cursor]
|
||||
(let [loading? (rf/sub [:camera-roll/loading-more])
|
||||
has-next-page? (rf/sub [:camera-roll/has-next-page])]
|
||||
(when (and (not loading?) has-next-page?)
|
||||
(rf/dispatch [:chat.ui/camera-roll-loading-more true])
|
||||
(rf/dispatch [:chat.ui/camera-roll-get-photos 20 end-cursor]))))
|
||||
|
||||
(defn photo-selector []
|
||||
(rf/dispatch [:chat.ui/camera-roll-get-photos 20])
|
||||
[:f>
|
||||
(fn []
|
||||
(let [{window-height :height
|
||||
window-width :width} (rn/use-window-dimensions)
|
||||
(let [{window-height :height window-width :width} (rn/use-window-dimensions)
|
||||
safe-area (safe-area/use-safe-area)
|
||||
camera-roll-photos (rf/sub [:camera-roll-photos])]
|
||||
camera-roll-photos (rf/sub [:camera-roll/photos])
|
||||
end-cursor (rf/sub [:camera-roll/end-cursor])]
|
||||
[rn/view {:style {:height (- window-height (:top safe-area))}}
|
||||
[rn/touchable-opacity
|
||||
{:on-press #(js/alert "Camera: not implemented")
|
||||
@@ -104,5 +87,7 @@
|
||||
:num-columns 3
|
||||
:content-container-style {:width "100%"
|
||||
:padding-bottom (+ (:bottom safe-area) 100)}
|
||||
:style {:border-radius 20}}]
|
||||
:style {:border-radius 20}
|
||||
:on-end-reached (fn []
|
||||
(on-end-reached end-cursor))}]
|
||||
[bottom-gradient]]))])
|
||||
|
||||
@@ -5,17 +5,17 @@
|
||||
["react-native" :refer (DevSettings LogBox)]))
|
||||
|
||||
;; Ignore all logs, because there are lots of temporary warnings when developing and hot reloading
|
||||
(.ignoreAllLogs LogBox)
|
||||
;(.ignoreAllLogs LogBox)
|
||||
|
||||
;; Only ignore warnings/errors that cannot be fixed for the time being.
|
||||
;; When you add a warning to be ignored explain below why it is ignored and how it can be fixed.
|
||||
;; When a warning is fixed make sure to remove it from here.
|
||||
#_(.ignoreLogs ^js LogBox (clj->js ["undefined is not an object (evaluating 'e.message')"
|
||||
"Cannot read property 'message' of undefined"
|
||||
"InternalError Metro has encountered an error"
|
||||
"undefined Unable to resolve module `parse-svg-path`"
|
||||
"group12"
|
||||
"Setting a timer for a long period of time"]))
|
||||
(.ignoreLogs ^js LogBox (clj->js ["undefined is not an object (evaluating 'e.message')"
|
||||
"Cannot read property 'message' of undefined"
|
||||
"InternalError Metro has encountered an error"
|
||||
"undefined Unable to resolve module `parse-svg-path`"
|
||||
"group12"
|
||||
"Setting a timer for a long period of time"]))
|
||||
|
||||
;; List of ignored warnings/errors:
|
||||
;; 1. "evaluating 'e.message'": Not sure why this error is happening, but it is coming from here
|
||||
|
||||
@@ -99,7 +99,10 @@
|
||||
(reg-root-key-sub :selected-participants :selected-participants)
|
||||
(reg-root-key-sub :chat/inputs :chat/inputs)
|
||||
(reg-root-key-sub :chat/memberships :chat/memberships)
|
||||
(reg-root-key-sub :camera-roll-photos :camera-roll-photos)
|
||||
(reg-root-key-sub :camera-roll/photos :camera-roll/photos)
|
||||
(reg-root-key-sub :camera-roll/end-cursor :camera-roll/end-cursor)
|
||||
(reg-root-key-sub :camera-roll/has-next-page :camera-roll/has-next-page)
|
||||
(reg-root-key-sub :camera-roll/loading-more :camera-roll/loading-more)
|
||||
(reg-root-key-sub :group-chat/invitations :group-chat/invitations)
|
||||
(reg-root-key-sub :chats/mention-suggestions :chats/mention-suggestions)
|
||||
(reg-root-key-sub :chat/inputs-with-mentions :chat/inputs-with-mentions)
|
||||
|
||||
@@ -1894,5 +1894,6 @@
|
||||
"unmute-group": "Unmute group",
|
||||
"remove-user-from-group": "Remove {{username}} from the group",
|
||||
"edit-name-image": "Edit name and image",
|
||||
"owner": "Owner"
|
||||
"owner": "Owner",
|
||||
"confirm-selection": "Confirm selection"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user