From 104abf3a8513e94eba37f37da5514424092b2509 Mon Sep 17 00:00:00 2001 From: Omar Basem Date: Tue, 11 Jul 2023 13:17:54 +0400 Subject: [PATCH] # This is a combination of 8 commits. # This is the 1st commit message: feat: camera updates updates updates feat: camera feat: camera updates icons icons icons icons revert # This is the commit message #2: lint # This is the commit message #3: review # This is the commit message #4: revert # This is the commit message #5: lint # This is the commit message #6: review # This is the commit message #7: camera features # This is the commit message #8: feat: camera extra features --- .../contexts/chat/camera/style.cljs | 42 ++++- src/status_im2/contexts/chat/camera/view.cljs | 170 +++++++++++------- translations/en.json | 3 + 3 files changed, 138 insertions(+), 77 deletions(-) diff --git a/src/status_im2/contexts/chat/camera/style.cljs b/src/status_im2/contexts/chat/camera/style.cljs index 4e340a0209e..f6a8ea30fd2 100644 --- a/src/status_im2/contexts/chat/camera/style.cljs +++ b/src/status_im2/contexts/chat/camera/style.cljs @@ -7,10 +7,23 @@ {:flex 1 :background-color colors/black}) -(def flash-container - {:position :absolute - :top 50 - :left 25}) +(defn flash-container + [rotate uri] + (reanimated/apply-animations-to-style + {: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 [width height top] @@ -18,6 +31,12 @@ :height height :top top}) +(defn image + [width height top portrait?] + {:width width + :height (if portrait? height (* width 0.75)) + :top top}) + (def zoom-button-container {:width 37 :height 37 @@ -38,19 +57,22 @@ :bottom (+ top (:bottom insets) (when platform/android? (:top insets)) 18)}) (defn zoom-button - [size] + [size rotate] (reanimated/apply-animations-to-style - {:width size - :height size} + {:width size + :height size + :transform [{:rotate rotate}]} {:background-color colors/black-opa-30 :justify-content :center :align-items :center :border-radius 50})) (defn bottom-area - [top insets] + [top insets uri] {:left 20 :right 20 + :opacity (if uri 0 1) + :z-index (if uri 0 1) :position :absolute :height (+ top (when platform/android? (:top insets))) :bottom (:bottom insets)}) @@ -84,8 +106,10 @@ :background-color colors/white}) (defn confirmation-container - [insets] + [insets uri] {:position :absolute + :opacity (if uri 1 0) + :z-index (if uri 1 0) :bottom 0 :left 0 :right 0 diff --git a/src/status_im2/contexts/chat/camera/view.cljs b/src/status_im2/contexts/chat/camera/view.cljs index 68f1558db38..da4e69310c7 100644 --- a/src/status_im2/contexts/chat/camera/view.cljs +++ b/src/status_im2/contexts/chat/camera/view.cljs @@ -4,6 +4,9 @@ [quo2.foundations.colors :as colors] [react-native.camera-kit :as camera-kit] [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.safe-area :as safe-area] [reagent.core :as reagent] @@ -12,22 +15,22 @@ [utils.re-frame :as rf])) (defn- f-zoom-button - [{:keys [value current-zoom]}] - (let [selected? (= @current-zoom value) - size (reanimated/use-shared-value (if selected? 37 25))] - (rn/use-effect #(reanimated/animate size (if selected? 37 25)) [@current-zoom]) + [{:keys [value current-zoom rotate]}] + (let [selected (= @current-zoom value) + size (reanimated/use-shared-value (if selected 37 25))] + (rn/use-effect #(reanimated/animate size (if selected 37 25)) [@current-zoom]) [rn/touchable-opacity - {:on-press #(reset! current-zoom value) - :style style/zoom-button-container - :accessibility-label (str "zoom-" value)} - [reanimated/view {:style (style/zoom-button size)} + {:on-press #(reset! current-zoom value) + :style style/zoom-button-container} + [reanimated/view {:style (style/zoom-button size rotate)} [quo/text - {:size (if selected? :paragraph-2 :label) - :weight :semi-bold - :style {:color (if selected? - colors/system-yellow - colors/white)}} - (str value (when selected? "x"))]]])) + {:size (if selected :paragraph-2 :label) + :weight :semi-bold + :number-of-lines 1 + :style {:color (if selected + colors/system-yellow + colors/white)}} + (str value (when selected "x"))]]])) (defn zoom-button [args] @@ -35,67 +38,98 @@ (defn snap-button [camera-ref uri] - [rn/view - {:style style/outer-circle - :accessibility-label :snap} + [rn/view {:style style/outer-circle} [rn/touchable-opacity {:on-press (fn [] (camera-kit/capture @camera-ref #(reset! uri %))) :style style/inner-circle}]]) +(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 camera-screen [] - (let [camera-ref (atom nil) - uri (reagent/atom nil) - current-zoom (reagent/atom "1")] - (fn [] - (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)] - [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)] + (let [camera-ref (atom nil) + uri (reagent/atom nil) + current-zoom (reagent/atom "1") + camera-type (reagent/atom camera-kit/camera-type-back) + flash (reagent/atom false) + curr-orientation (atom orientation/portrait)] + [:f> + (fn [] + (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? (= @curr-orientation orientation/portrait) + rotate (reanimated/use-shared-value "0deg")] + (orientation/use-device-orientation-change (fn [result] + (reset! curr-orientation result) + (case result + orientation/landscape-left + (reanimated/animate rotate "90deg") + orientation/landscape-right + (reanimated/animate rotate "-90deg") + (reanimated/animate rotate "0deg")))) + [rn/view {:style style/screen-container} + [reanimated/touchable-opacity + {:active-opacity 1 + :on-press #(reset! flash (not @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 + [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}]]) + [rn/view {:style (style/confirmation-container insets @uri)} + [quo/text + {:on-press #(retake flash uri) + :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 @uri)} + [quo/text {:style style/photo-text} (i18n/label :t/PHOTO)] + [rn/view {:style style/actions-container} [quo/text - {:on-press (fn [] - (rf/dispatch [:photo-selector/camera-roll-pick {:uri @uri}]) - (rf/dispatch [:navigate-back])) + {:on-press #(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}]]])])))) + (i18n/label :t/cancel)] + [snap-button camera-ref uri] + [reanimated/touchable-opacity + {:style (reanimated/apply-animations-to-style {:transform [{:rotate rotate}]} {}) + :on-press (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)))} + [quo/icon :i/rotate-camera {:size 48 :color colors/white}]]]]]))])) diff --git a/translations/en.json b/translations/en.json index 9aefc8b1ea1..9ddf3e12536 100644 --- a/translations/en.json +++ b/translations/en.json @@ -2261,7 +2261,10 @@ "chat-unmuted-successfully": "Chat unmuted successfully! ", "channel-unmuted-successfully": "Channel unmuted successfully! ", "photo-saved": "Photo saved to your device", +<<<<<<< HEAD "community-unmuted": "Community unmuted", +======= +>>>>>>> 02661f242 (feat: camera) "retake": "Retake", "use-photo": "Use Photo", "PHOTO": "PHOTO"