parent
daa78b4171
commit
f9255100a1
|
@ -85,6 +85,7 @@
|
||||||
;;100 with transparency
|
;;100 with transparency
|
||||||
(def neutral-100-opa-0 (alpha neutral-100 0))
|
(def neutral-100-opa-0 (alpha neutral-100 0))
|
||||||
(def neutral-100-opa-10 (alpha neutral-100 0.1))
|
(def neutral-100-opa-10 (alpha neutral-100 0.1))
|
||||||
|
(def neutral-100-opa-30 (alpha neutral-100 0.3))
|
||||||
(def neutral-100-opa-60 (alpha neutral-100 0.6))
|
(def neutral-100-opa-60 (alpha neutral-100 0.6))
|
||||||
(def neutral-100-opa-70 (alpha neutral-100 0.7))
|
(def neutral-100-opa-70 (alpha neutral-100 0.7))
|
||||||
(def neutral-100-opa-80 (alpha neutral-100 0.8))
|
(def neutral-100-opa-80 (alpha neutral-100 0.8))
|
||||||
|
|
|
@ -6,3 +6,7 @@
|
||||||
(let [kb (.useKeyboard hooks)]
|
(let [kb (.useKeyboard hooks)]
|
||||||
{:keyboard-shown (.-keyboardShown ^js kb)
|
{:keyboard-shown (.-keyboardShown ^js kb)
|
||||||
:keyboard-height (.-keyboardHeight ^js kb)}))
|
:keyboard-height (.-keyboardHeight ^js kb)}))
|
||||||
|
|
||||||
|
(defn use-back-handler
|
||||||
|
[handler]
|
||||||
|
(.useBackHandler hooks handler))
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
[utils.collection]
|
[utils.collection]
|
||||||
[utils.worklets.core :as worklets.core]))
|
[utils.worklets.core :as worklets.core]))
|
||||||
|
|
||||||
|
(def ^:const default-duration 300)
|
||||||
|
|
||||||
;; Animations
|
;; Animations
|
||||||
(def slide-in-up-animation SlideInUp)
|
(def slide-in-up-animation SlideInUp)
|
||||||
(def slide-out-up-animation SlideOutUp)
|
(def slide-out-up-animation SlideOutUp)
|
||||||
|
@ -65,6 +67,7 @@
|
||||||
(def in-out
|
(def in-out
|
||||||
(.-inOut ^js Easing))
|
(.-inOut ^js Easing))
|
||||||
|
|
||||||
|
;; trying to put default-easing inside easings map causes test to fail
|
||||||
(defn default-easing [] (in-out (.-quad ^js Easing)))
|
(defn default-easing [] (in-out (.-quad ^js Easing)))
|
||||||
|
|
||||||
(def easings
|
(def easings
|
||||||
|
@ -115,13 +118,15 @@
|
||||||
(js-obj "duration" duration
|
(js-obj "duration" duration
|
||||||
"easing" (get easings easing))))))
|
"easing" (get easings easing))))))
|
||||||
|
|
||||||
(defn animate-shared-value-with-delay-default-easing
|
(defn animate-delay
|
||||||
[anim val duration delay]
|
([animation val delay]
|
||||||
(set-shared-value anim
|
(animate-delay animation val delay default-duration))
|
||||||
(with-delay delay
|
([animation val delay duration]
|
||||||
(with-timing val
|
(set-shared-value animation
|
||||||
(js-obj "duration" duration
|
(with-delay delay
|
||||||
"easing" (in-out (.-quad ^js Easing)))))))
|
(with-timing val
|
||||||
|
(clj->js {:duration duration
|
||||||
|
:easing (default-easing)}))))))
|
||||||
|
|
||||||
(defn animate-shared-value-with-repeat
|
(defn animate-shared-value-with-repeat
|
||||||
[anim val duration easing number-of-repetitions reverse?]
|
[anim val duration easing number-of-repetitions reverse?]
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
(ns status-im2.common.bottom-sheet-screen.style
|
||||||
|
(:require
|
||||||
|
[quo2.foundations.colors :as colors]
|
||||||
|
[react-native.reanimated :as reanimated]))
|
||||||
|
|
||||||
|
(defn background
|
||||||
|
[opacity]
|
||||||
|
(reanimated/apply-animations-to-style
|
||||||
|
{:opacity opacity}
|
||||||
|
{:background-color colors/neutral-100-opa-70
|
||||||
|
:position :absolute
|
||||||
|
:top 0
|
||||||
|
:bottom 0
|
||||||
|
:left 0
|
||||||
|
:right 0}))
|
||||||
|
|
||||||
|
(defn main-view
|
||||||
|
[translate-y]
|
||||||
|
(reanimated/apply-animations-to-style
|
||||||
|
{:transform [{:translate-y translate-y}]}
|
||||||
|
{:background-color (colors/theme-colors colors/white colors/neutral-95)
|
||||||
|
:border-top-left-radius 20
|
||||||
|
:border-top-right-radius 20
|
||||||
|
:flex 1
|
||||||
|
:overflow :hidden}))
|
||||||
|
|
||||||
|
(def handle-container
|
||||||
|
{:left 0
|
||||||
|
:right 0
|
||||||
|
:top 0
|
||||||
|
:height 20
|
||||||
|
:z-index 1
|
||||||
|
:position :absolute
|
||||||
|
:justify-content :center
|
||||||
|
:align-items :center})
|
||||||
|
|
||||||
|
(defn handle
|
||||||
|
[]
|
||||||
|
{:width 32
|
||||||
|
:height 4
|
||||||
|
:border-radius 100
|
||||||
|
:background-color (colors/theme-colors colors/neutral-100-opa-30 colors/white-opa-30)})
|
|
@ -0,0 +1,81 @@
|
||||||
|
(ns status-im2.common.bottom-sheet-screen.view
|
||||||
|
(:require
|
||||||
|
[react-native.gesture :as gesture]
|
||||||
|
[react-native.hooks :as hooks]
|
||||||
|
[react-native.navigation :as navigation]
|
||||||
|
[react-native.platform :as platform]
|
||||||
|
[react-native.reanimated :as reanimated]
|
||||||
|
[oops.core :as oops]
|
||||||
|
[react-native.safe-area :as safe-area]
|
||||||
|
[status-im2.common.bottom-sheet-screen.style :as style]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[reagent.core :as reagent]
|
||||||
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
(def ^:const drag-threshold 100)
|
||||||
|
|
||||||
|
(defn drag-gesture
|
||||||
|
[translate-y opacity scroll-enabled curr-scroll]
|
||||||
|
(->
|
||||||
|
(gesture/gesture-pan)
|
||||||
|
(gesture/on-start (fn [e]
|
||||||
|
(when (< (oops/oget e "velocityY") 0)
|
||||||
|
(reset! scroll-enabled true))))
|
||||||
|
(gesture/on-update (fn [e]
|
||||||
|
(let [translation (oops/oget e "translationY")
|
||||||
|
progress (Math/abs (/ translation drag-threshold))]
|
||||||
|
(when (pos? translation)
|
||||||
|
(reanimated/set-shared-value translate-y translation)
|
||||||
|
(reanimated/set-shared-value opacity (- 1 (/ progress 5)))))))
|
||||||
|
(gesture/on-end (fn [e]
|
||||||
|
(if (> (oops/oget e "translationY") drag-threshold)
|
||||||
|
(do
|
||||||
|
(reanimated/set-shared-value opacity (reanimated/with-timing-duration 0 100))
|
||||||
|
(rf/dispatch [:navigate-back]))
|
||||||
|
(do
|
||||||
|
(reanimated/set-shared-value opacity (reanimated/with-timing 1))
|
||||||
|
(reanimated/set-shared-value translate-y (reanimated/with-timing 0))
|
||||||
|
(reset! scroll-enabled true)))))
|
||||||
|
(gesture/on-finalize (fn [e]
|
||||||
|
(when (and (>= (oops/oget e "velocityY") 0)
|
||||||
|
(<= @curr-scroll (if platform/ios? -1 0)))
|
||||||
|
(reset! scroll-enabled false))))))
|
||||||
|
|
||||||
|
(defn on-scroll
|
||||||
|
[e curr-scroll]
|
||||||
|
(let [y (oops/oget e "nativeEvent.contentOffset.y")]
|
||||||
|
(reset! curr-scroll y)))
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[content skip-background?]
|
||||||
|
[:f>
|
||||||
|
(let [scroll-enabled (reagent/atom true)
|
||||||
|
curr-scroll (atom 0)]
|
||||||
|
(fn []
|
||||||
|
(let [sb-height (navigation/status-bar-height)
|
||||||
|
insets (safe-area/use-safe-area)
|
||||||
|
padding-top (Math/max sb-height (:top insets))
|
||||||
|
padding-top (if platform/ios? padding-top (+ padding-top 10))
|
||||||
|
opacity (reanimated/use-shared-value 0)
|
||||||
|
translate-y (reanimated/use-shared-value 0)
|
||||||
|
close (fn []
|
||||||
|
(reanimated/set-shared-value opacity (reanimated/with-timing-duration 0 100))
|
||||||
|
(rf/dispatch [:navigate-back]))]
|
||||||
|
(rn/use-effect
|
||||||
|
(fn []
|
||||||
|
(reanimated/animate-delay opacity 1 (if platform/ios? 300 100))))
|
||||||
|
(hooks/use-back-handler close)
|
||||||
|
[rn/view
|
||||||
|
{:style {:flex 1
|
||||||
|
:padding-top padding-top}}
|
||||||
|
(when-not skip-background?
|
||||||
|
[reanimated/view {:style (style/background opacity)}])
|
||||||
|
[gesture/gesture-detector
|
||||||
|
{:gesture (drag-gesture translate-y opacity scroll-enabled curr-scroll)}
|
||||||
|
[reanimated/view {:style (style/main-view translate-y)}
|
||||||
|
[rn/view {:style style/handle-container}
|
||||||
|
[rn/view {:style (style/handle)}]]
|
||||||
|
[content
|
||||||
|
{:close close
|
||||||
|
:scroll-enabled @scroll-enabled
|
||||||
|
:on-scroll #(on-scroll % curr-scroll)}]]]])))])
|
|
@ -41,13 +41,13 @@
|
||||||
:size 32} :i/reaction]])
|
:size 32} :i/reaction]])
|
||||||
|
|
||||||
(defn image-button
|
(defn image-button
|
||||||
[chat-id]
|
[insets]
|
||||||
[quo/button
|
[quo/button
|
||||||
{:on-press (fn []
|
{:on-press (fn []
|
||||||
(permissions/request-permissions
|
(permissions/request-permissions
|
||||||
{:permissions [:read-external-storage :write-external-storage]
|
{:permissions [:read-external-storage :write-external-storage]
|
||||||
:on-allowed #(rf/dispatch
|
:on-allowed #(rf/dispatch
|
||||||
[:open-modal :photo-selector {:chat-id chat-id}])
|
[:open-modal :photo-selector {:insets insets}])
|
||||||
:on-denied (fn []
|
:on-denied (fn []
|
||||||
(background-timer/set-timeout
|
(background-timer/set-timeout
|
||||||
#(utils-old/show-popup (i18n/label :t/error)
|
#(utils-old/show-popup (i18n/label :t/error)
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
(when (and (not @input/recording-audio?)
|
(when (and (not @input/recording-audio?)
|
||||||
(nil? (get @input/reviewing-audio-filepath chat-id)))
|
(nil? (get @input/reviewing-audio-filepath chat-id)))
|
||||||
[:<>
|
[:<>
|
||||||
[image-button chat-id]
|
[image-button insets]
|
||||||
[rn/view {:width 12}]
|
[rn/view {:width 12}]
|
||||||
[reactions-button]
|
[reactions-button]
|
||||||
[rn/view {:flex 1}]
|
[rn/view {:flex 1}]
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
:flex-direction :row
|
:flex-direction :row
|
||||||
:left 0
|
:left 0
|
||||||
:right 0
|
:right 0
|
||||||
:margin-top 20
|
:top 20
|
||||||
:margin-bottom 12
|
|
||||||
:justify-content :center
|
:justify-content :center
|
||||||
:z-index 1})
|
:z-index 1})
|
||||||
|
|
||||||
|
@ -66,8 +65,8 @@
|
||||||
:height (/ window-width 3)
|
:height (/ window-width 3)
|
||||||
:margin-left (when (not= (mod index 3) 0) 1)
|
:margin-left (when (not= (mod index 3) 0) 1)
|
||||||
:margin-bottom 1
|
:margin-bottom 1
|
||||||
:border-top-left-radius (when (= index 0) 10)
|
:border-top-left-radius (when (= index 0) 20)
|
||||||
:border-top-right-radius (when (= index 2) 10)})
|
:border-top-right-radius (when (= index 2) 20)})
|
||||||
|
|
||||||
(defn overlay
|
(defn overlay
|
||||||
[window-width]
|
[window-width]
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
(ns status-im2.contexts.chat.photo-selector.view
|
(ns status-im2.contexts.chat.photo-selector.view
|
||||||
(:require
|
(:require
|
||||||
|
[react-native.gesture :as gesture]
|
||||||
[react-native.platform :as platform]
|
[react-native.platform :as platform]
|
||||||
[status-im2.constants :as constants]
|
[status-im2.constants :as constants]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[react-native.safe-area :as safe-area]
|
|
||||||
[quo2.components.notifications.info-count :as info-count]
|
[quo2.components.notifications.info-count :as info-count]
|
||||||
[quo2.core :as quo]
|
[quo2.core :as quo]
|
||||||
[quo2.foundations.colors :as colors]
|
[quo2.foundations.colors :as colors]
|
||||||
|
@ -13,6 +13,7 @@
|
||||||
[status-im2.contexts.chat.photo-selector.style :as style]
|
[status-im2.contexts.chat.photo-selector.style :as style]
|
||||||
[status-im.utils.core :as utils]
|
[status-im.utils.core :as utils]
|
||||||
[quo.react]
|
[quo.react]
|
||||||
|
[status-im2.common.bottom-sheet-screen.view :as bottom-sheet-screen]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(defn on-press-confirm-selection
|
(defn on-press-confirm-selection
|
||||||
|
@ -80,31 +81,38 @@
|
||||||
(inc (utils/first-index #(= (:uri item) (:uri %)) @selected))])])
|
(inc (utils/first-index #(= (:uri item) (:uri %)) @selected))])])
|
||||||
|
|
||||||
(defn album-title
|
(defn album-title
|
||||||
[photos? selected-album selected temporary-selected]
|
[photos? selected-album]
|
||||||
[rn/touchable-opacity
|
(fn []
|
||||||
{:style (style/title-container)
|
[rn/touchable-opacity
|
||||||
:active-opacity 1
|
{:style (style/title-container)
|
||||||
:accessibility-label :album-title
|
:active-opacity 1
|
||||||
:on-press (fn []
|
:accessibility-label :album-title
|
||||||
(if photos?
|
:on-press (fn []
|
||||||
(do
|
;; TODO: album-selector issue:
|
||||||
(reset! temporary-selected @selected)
|
;; https://github.com/status-im/status-mobile/issues/15398
|
||||||
(rf/dispatch [:open-modal :album-selector]))
|
(js/alert "currently disabled")
|
||||||
(rf/dispatch [:navigate-back])))}
|
;(if photos?
|
||||||
[quo/text
|
; (do
|
||||||
{:weight :medium
|
; (reset! temporary-selected @selected)
|
||||||
:ellipsize-mode :tail
|
; (rf/dispatch [:open-modal :album-selector {:insets insets}]))
|
||||||
:number-of-lines 1
|
; (rf/dispatch [:navigate-back]))
|
||||||
:style {:max-width 150}}
|
)}
|
||||||
selected-album]
|
[quo/text
|
||||||
[rn/view {:style (style/chevron-container)}
|
{:weight :medium
|
||||||
[quo/icon (if photos? :i/chevron-down :i/chevron-up)
|
:ellipsize-mode :tail
|
||||||
{:color (colors/theme-colors colors/neutral-100 colors/white)}]]])
|
:number-of-lines 1
|
||||||
|
:style {:max-width 150}}
|
||||||
|
selected-album]
|
||||||
|
[rn/view {:style (style/chevron-container)}
|
||||||
|
[quo/icon (if photos? :i/chevron-down :i/chevron-up)
|
||||||
|
{:color (colors/theme-colors colors/neutral-100 colors/white)}]]]))
|
||||||
|
|
||||||
|
|
||||||
(defn photo-selector
|
(defn photo-selector
|
||||||
[]
|
[]
|
||||||
[:f>
|
[:f>
|
||||||
(let [temporary-selected (reagent/atom [])] ; used when switching albums
|
(let [{:keys [insets]} (rf/sub [:get-screen-params])
|
||||||
|
temporary-selected (reagent/atom [])] ; used when switching albums
|
||||||
(fn []
|
(fn []
|
||||||
(let [selected (reagent/atom []) ; currently selected
|
(let [selected (reagent/atom []) ; currently selected
|
||||||
selected-images (rf/sub [:chats/sending-image]) ; already selected and dispatched
|
selected-images (rf/sub [:chats/sending-image]) ; already selected and dispatched
|
||||||
|
@ -116,26 +124,19 @@
|
||||||
(reset! selected (vec (vals selected-images)))
|
(reset! selected (vec (vals selected-images)))
|
||||||
(reset! selected @temporary-selected)))
|
(reset! selected @temporary-selected)))
|
||||||
[selected-album])
|
[selected-album])
|
||||||
[safe-area/consumer
|
[bottom-sheet-screen/view
|
||||||
(fn [insets]
|
(fn [{:keys [scroll-enabled on-scroll]}]
|
||||||
(let [window-width (:width (rn/get-window))
|
(let [window-width (:width (rn/get-window))
|
||||||
camera-roll-photos (rf/sub [:camera-roll/photos])
|
camera-roll-photos (rf/sub [:camera-roll/photos])
|
||||||
end-cursor (rf/sub [:camera-roll/end-cursor])
|
end-cursor (rf/sub [:camera-roll/end-cursor])
|
||||||
loading? (rf/sub [:camera-roll/loading-more])
|
loading? (rf/sub [:camera-roll/loading-more])
|
||||||
has-next-page? (rf/sub [:camera-roll/has-next-page])]
|
has-next-page? (rf/sub [:camera-roll/has-next-page])]
|
||||||
[rn/view {:style {:flex 1}}
|
[:<>
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style style/buttons-container}
|
{:style style/buttons-container}
|
||||||
(when platform/android?
|
[album-title true selected-album selected temporary-selected insets]
|
||||||
[rn/touchable-opacity
|
|
||||||
{:active-opacity 1
|
|
||||||
:on-press #(rf/dispatch [:navigate-back])
|
|
||||||
:style (style/close-button-container)}
|
|
||||||
[quo/icon :i/close
|
|
||||||
{:size 20 :color (colors/theme-colors colors/black colors/white)}]])
|
|
||||||
[album-title true selected-album selected temporary-selected]
|
|
||||||
[clear-button selected]]
|
[clear-button selected]]
|
||||||
[rn/flat-list
|
[gesture/flat-list
|
||||||
{:key-fn identity
|
{:key-fn identity
|
||||||
:render-fn image
|
:render-fn image
|
||||||
:render-data {:window-width window-width :selected selected}
|
:render-data {:window-width window-width :selected selected}
|
||||||
|
@ -143,7 +144,9 @@
|
||||||
:num-columns 3
|
:num-columns 3
|
||||||
:content-container-style {:width "100%"
|
:content-container-style {:width "100%"
|
||||||
:padding-bottom (+ (:bottom insets) 100)
|
:padding-bottom (+ (:bottom insets) 100)
|
||||||
:padding-top 80}
|
:padding-top 64}
|
||||||
|
:on-scroll on-scroll
|
||||||
|
:scroll-enabled scroll-enabled
|
||||||
:on-end-reached #(rf/dispatch [:camera-roll/on-end-reached end-cursor
|
:on-end-reached #(rf/dispatch [:camera-roll/on-end-reached end-cursor
|
||||||
selected-album loading?
|
selected-album loading?
|
||||||
has-next-page?])}]
|
has-next-page?])}]
|
||||||
|
|
|
@ -43,6 +43,15 @@
|
||||||
:drawBehind true}}
|
:drawBehind true}}
|
||||||
{:statusBar {:style :light}})))
|
{:statusBar {:style :light}})))
|
||||||
|
|
||||||
|
(def bottom-sheet-options
|
||||||
|
{:topBar {:visible false}
|
||||||
|
:layout {:componentBackgroundColor :transparent
|
||||||
|
:backgroundColor :transparent}
|
||||||
|
:modalPresentationStyle :overCurrentContext})
|
||||||
|
|
||||||
|
(def bottom-sheet-insets
|
||||||
|
{:top false})
|
||||||
|
|
||||||
(defn screens
|
(defn screens
|
||||||
[]
|
[]
|
||||||
(concat
|
(concat
|
||||||
|
@ -87,7 +96,8 @@
|
||||||
:factor 1.5}}]}}}
|
:factor 1.5}}]}}}
|
||||||
:component lightbox/lightbox}
|
:component lightbox/lightbox}
|
||||||
{:name :photo-selector
|
{:name :photo-selector
|
||||||
:options {:topBar {:visible false}}
|
:insets bottom-sheet-insets
|
||||||
|
:options bottom-sheet-options
|
||||||
:component photo-selector/photo-selector}
|
:component photo-selector/photo-selector}
|
||||||
|
|
||||||
{:name :album-selector
|
{:name :album-selector
|
||||||
|
|
Loading…
Reference in New Issue