parent
82645f5df4
commit
0ee0137c72
|
@ -7,10 +7,23 @@
|
||||||
{:flex 1
|
{:flex 1
|
||||||
:background-color colors/black})
|
:background-color colors/black})
|
||||||
|
|
||||||
(def flash-container
|
(defn flash-container
|
||||||
{:position :absolute
|
[rotate uri]
|
||||||
:top 50
|
(reanimated/apply-animations-to-style
|
||||||
:left 25})
|
{:transform [{:rotate rotate}]}
|
||||||
|
{:position :absolute
|
||||||
|
:top 50
|
||||||
|
:left (if uri -25 25)}))
|
||||||
|
|
||||||
|
(def cancel-dash
|
||||||
|
{:width 1
|
||||||
|
:height 32
|
||||||
|
:top -4
|
||||||
|
:left 12
|
||||||
|
:z-index 1
|
||||||
|
:transform [{:rotate "-45deg"}]
|
||||||
|
:background-color colors/white
|
||||||
|
:position :absolute})
|
||||||
|
|
||||||
(defn camera-window
|
(defn camera-window
|
||||||
[width height top]
|
[width height top]
|
||||||
|
@ -18,6 +31,12 @@
|
||||||
:height height
|
:height height
|
||||||
:top top})
|
:top top})
|
||||||
|
|
||||||
|
(defn image
|
||||||
|
[width height top portrait?]
|
||||||
|
{:width width
|
||||||
|
:height (if portrait? height (* width 0.75))
|
||||||
|
:top top})
|
||||||
|
|
||||||
(def zoom-button-container
|
(def zoom-button-container
|
||||||
{:width 37
|
{:width 37
|
||||||
:height 37
|
:height 37
|
||||||
|
@ -38,19 +57,22 @@
|
||||||
:bottom (+ top (:bottom insets) (when platform/android? (:top insets)) 18)})
|
:bottom (+ top (:bottom insets) (when platform/android? (:top insets)) 18)})
|
||||||
|
|
||||||
(defn zoom-button
|
(defn zoom-button
|
||||||
[size]
|
[size rotate]
|
||||||
(reanimated/apply-animations-to-style
|
(reanimated/apply-animations-to-style
|
||||||
{:width size
|
{:width size
|
||||||
:height size}
|
:height size
|
||||||
|
:transform [{:rotate rotate}]}
|
||||||
{:background-color colors/black-opa-30
|
{:background-color colors/black-opa-30
|
||||||
:justify-content :center
|
:justify-content :center
|
||||||
:align-items :center
|
:align-items :center
|
||||||
:border-radius 50}))
|
:border-radius 50}))
|
||||||
|
|
||||||
(defn bottom-area
|
(defn bottom-area
|
||||||
[top insets]
|
[top insets uri]
|
||||||
{:left 20
|
{:left 20
|
||||||
:right 20
|
:right 20
|
||||||
|
:opacity (if uri 0 1)
|
||||||
|
:z-index (if uri 0 1)
|
||||||
:position :absolute
|
:position :absolute
|
||||||
:height (+ top (when platform/android? (:top insets)))
|
:height (+ top (when platform/android? (:top insets)))
|
||||||
:bottom (:bottom insets)})
|
:bottom (:bottom insets)})
|
||||||
|
@ -84,8 +106,10 @@
|
||||||
:background-color colors/white})
|
:background-color colors/white})
|
||||||
|
|
||||||
(defn confirmation-container
|
(defn confirmation-container
|
||||||
[insets]
|
[insets uri]
|
||||||
{:position :absolute
|
{:position :absolute
|
||||||
|
:opacity (if uri 1 0)
|
||||||
|
:z-index (if uri 1 0)
|
||||||
:bottom 0
|
:bottom 0
|
||||||
:left 0
|
:left 0
|
||||||
:right 0
|
:right 0
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
[quo2.foundations.colors :as colors]
|
[quo2.foundations.colors :as colors]
|
||||||
[react-native.camera-kit :as camera-kit]
|
[react-native.camera-kit :as camera-kit]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
|
[react-native.fast-image :as fast-image]
|
||||||
|
[react-native.orientation :as orientation]
|
||||||
|
[react-native.platform :as platform]
|
||||||
[react-native.reanimated :as reanimated]
|
[react-native.reanimated :as reanimated]
|
||||||
[react-native.safe-area :as safe-area]
|
[react-native.safe-area :as safe-area]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
|
@ -11,8 +14,28 @@
|
||||||
[status-im2.contexts.chat.camera.style :as style]
|
[status-im2.contexts.chat.camera.style :as style]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
(defn retake
|
||||||
|
[flash uri]
|
||||||
|
(let [current-flash @flash]
|
||||||
|
(when platform/android?
|
||||||
|
(reset! flash false) ; On Android, setting flash needs to be delayed until camera has initialized
|
||||||
|
(js/setTimeout #(reset! flash current-flash) 300))
|
||||||
|
(reset! uri nil)))
|
||||||
|
|
||||||
|
(defn handle-orientation
|
||||||
|
[current-orientation rotate]
|
||||||
|
(orientation/use-device-orientation-change (fn [result]
|
||||||
|
(reset! current-orientation result)
|
||||||
|
(cond
|
||||||
|
(= result orientation/landscape-left)
|
||||||
|
(reanimated/animate rotate "90deg")
|
||||||
|
(= result orientation/landscape-right)
|
||||||
|
(reanimated/animate rotate "-90deg")
|
||||||
|
:else
|
||||||
|
(reanimated/animate rotate "0deg")))))
|
||||||
|
|
||||||
(defn- f-zoom-button
|
(defn- f-zoom-button
|
||||||
[{:keys [value current-zoom]}]
|
[{:keys [value current-zoom rotate]}]
|
||||||
(let [selected? (= @current-zoom value)
|
(let [selected? (= @current-zoom value)
|
||||||
size (reanimated/use-shared-value (if selected? 37 25))]
|
size (reanimated/use-shared-value (if selected? 37 25))]
|
||||||
(rn/use-effect #(reanimated/animate size (if selected? 37 25)) [@current-zoom])
|
(rn/use-effect #(reanimated/animate size (if selected? 37 25)) [@current-zoom])
|
||||||
|
@ -20,13 +43,14 @@
|
||||||
{:on-press #(reset! current-zoom value)
|
{:on-press #(reset! current-zoom value)
|
||||||
:style style/zoom-button-container
|
:style style/zoom-button-container
|
||||||
:accessibility-label (str "zoom-" value)}
|
:accessibility-label (str "zoom-" value)}
|
||||||
[reanimated/view {:style (style/zoom-button size)}
|
[reanimated/view {:style (style/zoom-button size rotate)}
|
||||||
[quo/text
|
[quo/text
|
||||||
{:size (if selected? :paragraph-2 :label)
|
{:size (if selected? :paragraph-2 :label)
|
||||||
:weight :semi-bold
|
:weight :semi-bold
|
||||||
:style {:color (if selected?
|
:number-of-lines 1
|
||||||
colors/system-yellow
|
:style {:color (if selected?
|
||||||
colors/white)}}
|
colors/system-yellow
|
||||||
|
colors/white)}}
|
||||||
(str value (when selected? "x"))]]]))
|
(str value (when selected? "x"))]]]))
|
||||||
|
|
||||||
(defn zoom-button
|
(defn zoom-button
|
||||||
|
@ -43,59 +67,108 @@
|
||||||
(camera-kit/capture @camera-ref #(reset! uri %)))
|
(camera-kit/capture @camera-ref #(reset! uri %)))
|
||||||
:style style/inner-circle}]])
|
:style style/inner-circle}]])
|
||||||
|
|
||||||
|
(defn zoom-buttons
|
||||||
|
[]
|
||||||
|
(let [current-zoom (reagent/atom 1)]
|
||||||
|
(fn [top insets rotate]
|
||||||
|
[rn/view {:style (style/zoom-container top insets)}
|
||||||
|
[zoom-button {:value 0.5 :current-zoom current-zoom :rotate rotate}]
|
||||||
|
[zoom-button {:value 1 :current-zoom current-zoom :rotate rotate}]
|
||||||
|
[zoom-button {:value 2 :current-zoom current-zoom :rotate rotate}]
|
||||||
|
[zoom-button {:value 3 :current-zoom current-zoom :rotate rotate}]])))
|
||||||
|
|
||||||
|
|
||||||
|
(defn- f-bottom-area
|
||||||
|
[{:keys [top insets uri camera-ref rotate]} back flip-camera]
|
||||||
|
[rn/view {:style (style/bottom-area top insets @uri)}
|
||||||
|
[quo/text {:style style/photo-text} (i18n/label :t/photo-caps)]
|
||||||
|
[rn/view {:style style/actions-container}
|
||||||
|
[quo/text
|
||||||
|
{:on-press back
|
||||||
|
:style {:font-size 17
|
||||||
|
:color colors/white}
|
||||||
|
:accessibility-label :cancel}
|
||||||
|
(i18n/label :t/cancel)]
|
||||||
|
[snap-button camera-ref uri]
|
||||||
|
[reanimated/touchable-opacity
|
||||||
|
{:style (reanimated/apply-animations-to-style {:transform [{:rotate rotate}]} {})
|
||||||
|
:on-press flip-camera}
|
||||||
|
[quo/icon :i/rotate-camera
|
||||||
|
{:size 48 :color colors/white :accessibility-label :flip-camera}]]]])
|
||||||
|
|
||||||
|
(defn bottom-area
|
||||||
|
[{:keys [flash camera-type] :as args}]
|
||||||
|
(let [back #(rf/dispatch [:navigate-back])
|
||||||
|
flip-camera (fn []
|
||||||
|
(reset! flash false)
|
||||||
|
(reset! camera-type (if (= @camera-type camera-kit/camera-type-back)
|
||||||
|
camera-kit/camera-type-front
|
||||||
|
camera-kit/camera-type-back)))]
|
||||||
|
[:f> f-bottom-area args back flip-camera]))
|
||||||
|
|
||||||
|
(defn- f-camera-screen
|
||||||
|
[{:keys [camera-ref uri camera-type current-orientation flash toggle-flash]}]
|
||||||
|
(let [window (rn/get-window)
|
||||||
|
{:keys [width height]} window
|
||||||
|
camera-window-height (* width 1.33)
|
||||||
|
insets (safe-area/get-insets)
|
||||||
|
top (/ (- height camera-window-height (:bottom insets)) 2)
|
||||||
|
top-landscape (/ (- height (* width 0.75) (:bottom insets)) 2)
|
||||||
|
portrait? (= @current-orientation orientation/portrait)
|
||||||
|
rotate (reanimated/use-shared-value "0deg")
|
||||||
|
retake #(retake flash uri)
|
||||||
|
use-photo (fn []
|
||||||
|
(rf/dispatch [:photo-selector/camera-roll-pick {:uri @uri}])
|
||||||
|
(rf/dispatch [:navigate-back]))]
|
||||||
|
(handle-orientation current-orientation rotate)
|
||||||
|
[rn/view {:style style/screen-container}
|
||||||
|
[reanimated/touchable-opacity
|
||||||
|
{:active-opacity 1
|
||||||
|
:on-press toggle-flash
|
||||||
|
:style (style/flash-container rotate @uri)}
|
||||||
|
(when-not @flash
|
||||||
|
[rn/view {:style style/cancel-dash}])
|
||||||
|
[quo/icon :i/flash-camera
|
||||||
|
{:color colors/white
|
||||||
|
:size 24}]]
|
||||||
|
(if @uri
|
||||||
|
[fast-image/fast-image
|
||||||
|
{:style (style/image width camera-window-height (if portrait? top top-landscape) portrait?)
|
||||||
|
:source {:uri @uri}}]
|
||||||
|
[camera-kit/camera
|
||||||
|
{:ref #(reset! camera-ref %)
|
||||||
|
:style (style/camera-window width camera-window-height top)
|
||||||
|
:flash-mode (if @flash :on :off)
|
||||||
|
:camera-type @camera-type}])
|
||||||
|
(when-not @uri
|
||||||
|
[zoom-buttons top insets rotate])
|
||||||
|
[rn/view {:style (style/confirmation-container insets @uri)}
|
||||||
|
[quo/text
|
||||||
|
{:on-press retake
|
||||||
|
:style {:font-size 17
|
||||||
|
:color colors/white}}
|
||||||
|
(i18n/label :t/retake)]
|
||||||
|
[quo/text
|
||||||
|
{:on-press use-photo
|
||||||
|
:style {:font-size 17
|
||||||
|
:color colors/white}}
|
||||||
|
(i18n/label :t/use-photo)]]
|
||||||
|
[bottom-area
|
||||||
|
{:top top
|
||||||
|
:insets insets
|
||||||
|
:uri uri
|
||||||
|
:camera-type camera-type
|
||||||
|
:camera-ref camera-ref
|
||||||
|
:flash flash
|
||||||
|
:rotate rotate}]]))
|
||||||
|
|
||||||
(defn camera-screen
|
(defn camera-screen
|
||||||
[]
|
[]
|
||||||
(let [camera-ref (atom nil)
|
(let [flash (reagent/atom false)
|
||||||
uri (reagent/atom nil)
|
args {:camera-ref (atom nil)
|
||||||
current-zoom (reagent/atom "1")]
|
:uri (reagent/atom nil)
|
||||||
(fn []
|
:camera-type (reagent/atom camera-kit/camera-type-back)
|
||||||
(let [window (rn/get-window)
|
:current-orientation (atom orientation/portrait)
|
||||||
{:keys [width height]} window
|
:flash flash
|
||||||
camera-window-height (* width 1.33)
|
:toggle-flash #(swap! flash not)}]
|
||||||
insets (safe-area/get-insets)
|
[:f> f-camera-screen args]))
|
||||||
top (/ (- height camera-window-height (:bottom insets)) 2)]
|
|
||||||
[rn/view {:style style/screen-container}
|
|
||||||
(when-not @uri
|
|
||||||
[rn/view {:style style/flash-container}
|
|
||||||
[quo/icon :i/flash-camera
|
|
||||||
{:color colors/white
|
|
||||||
:size 24}]])
|
|
||||||
(if @uri
|
|
||||||
[rn/image
|
|
||||||
{:style (style/camera-window width camera-window-height top)
|
|
||||||
:source {:uri @uri}}]
|
|
||||||
[camera-kit/camera
|
|
||||||
{:ref #(reset! camera-ref %)
|
|
||||||
:style (style/camera-window width camera-window-height top)}])
|
|
||||||
(when-not @uri
|
|
||||||
[rn/view {:style (style/zoom-container top insets)}
|
|
||||||
[zoom-button {:value "0.5" :current-zoom current-zoom}]
|
|
||||||
[zoom-button {:value "1" :current-zoom current-zoom}]
|
|
||||||
[zoom-button {:value "2" :current-zoom current-zoom}]
|
|
||||||
[zoom-button {:value "3" :current-zoom current-zoom}]])
|
|
||||||
(if @uri
|
|
||||||
[rn/view {:style (style/confirmation-container insets)}
|
|
||||||
[quo/text
|
|
||||||
{:on-press #(reset! uri nil)
|
|
||||||
:style {:font-size 17
|
|
||||||
:color colors/white}}
|
|
||||||
(i18n/label :t/retake)]
|
|
||||||
[quo/text
|
|
||||||
{:on-press (fn []
|
|
||||||
(rf/dispatch [:photo-selector/camera-roll-pick {:uri @uri}])
|
|
||||||
(rf/dispatch [:navigate-back]))
|
|
||||||
:style {:font-size 17
|
|
||||||
:color colors/white}}
|
|
||||||
(i18n/label :t/use-photo)]]
|
|
||||||
[rn/view {:style (style/bottom-area top insets)}
|
|
||||||
[quo/text {:style style/photo-text} (i18n/label :t/PHOTO)]
|
|
||||||
[rn/view {:style style/actions-container}
|
|
||||||
[quo/text
|
|
||||||
{:on-press #(rf/dispatch [:navigate-back])
|
|
||||||
:style {:font-size 17
|
|
||||||
:color colors/white}
|
|
||||||
:accessibility-label :cancel}
|
|
||||||
(i18n/label :t/cancel)]
|
|
||||||
[snap-button camera-ref uri]
|
|
||||||
[quo/icon :i/rotate-camera
|
|
||||||
{:size 48 :color colors/white :accessibility-label :flip-camera}]]])]))))
|
|
||||||
|
|
|
@ -2264,5 +2264,5 @@
|
||||||
"community-unmuted": "Community unmuted",
|
"community-unmuted": "Community unmuted",
|
||||||
"retake": "Retake",
|
"retake": "Retake",
|
||||||
"use-photo": "Use Photo",
|
"use-photo": "Use Photo",
|
||||||
"PHOTO": "PHOTO"
|
"photo-caps": "PHOTO"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue