From 6d6e6b1eff0d2b654214e44541bdcd6c215775d9 Mon Sep 17 00:00:00 2001 From: Brian Sztamfater Date: Mon, 26 Jun 2023 11:02:13 -0300 Subject: [PATCH] fix: calibrate duration of recorded audio (#15543) Signed-off-by: Brian Sztamfater --- .../record_audio_component_spec.cljs | 274 ++++++++++-------- .../buttons/record_button_big.cljs | 3 +- .../record_audio/record_audio/view.cljs | 120 ++++---- .../record_audio/soundtrack/view.cljs | 4 +- src/status_im2/constants.cljs | 2 + .../contexts/chat/composer/actions/view.cljs | 22 +- .../chat/messages/content/audio/view.cljs | 27 +- .../record_audio/record_audio.cljs | 6 +- 8 files changed, 265 insertions(+), 193 deletions(-) diff --git a/src/quo2/components/record_audio/record_audio/__tests__/record_audio_component_spec.cljs b/src/quo2/components/record_audio/record_audio/__tests__/record_audio_component_spec.cljs index d6af272bdb..099374057a 100644 --- a/src/quo2/components/record_audio/record_audio/__tests__/record_audio_component_spec.cljs +++ b/src/quo2/components/record_audio/record_audio/__tests__/record_audio_component_spec.cljs @@ -1,7 +1,9 @@ (ns quo2.components.record-audio.record-audio.--tests--.record-audio-component-spec (:require [quo2.components.record-audio.record-audio.view :as record-audio] [react-native.audio-toolkit :as audio] - [test-helpers.component :as h])) + [test-helpers.component :as h] + [reagent.core :as reagent] + [utils.datetime :as datetime])) (h/describe "record audio component" (h/before-each @@ -34,12 +36,16 @@ (.toHaveBeenCalledTimes 1)))) (h/test "record-audio on-reviewing-audio works" - (let [event (js/jest.fn)] + (let [event (js/jest.fn) + on-meter (reagent/atom nil)] (h/render [record-audio/record-audio {:on-reviewing-audio event :record-audio-permission-granted true}]) - (with-redefs [audio/start-recording (fn [_ on-start _] - (on-start)) + (with-redefs [audio/new-recorder (fn [_ on-meter-fn _] + (reset! on-meter on-meter-fn)) + audio/start-recording (fn [_ on-start _] + (on-start) + (js/setInterval #(@on-meter) 100)) audio/get-recorder-file-path (fn [] "file-path")] (h/fire-event :on-start-should-set-responder @@ -48,25 +54,30 @@ :locationY 70 :timestamp 0 :identifier 0}}) - (h/advance-timers-by-time 500) - (h/fire-event - :on-responder-release - (h/get-by-test-id "record-audio") - {:nativeEvent {:locationX 70 - :locationY 70 - :timestamp 200 - :identifier 0}}) - (h/advance-timers-by-time 250) - (-> (h/expect event) - (.toHaveBeenCalledTimes 1))))) + (with-redefs [datetime/timestamp (fn [] (+ (.now js/Date) 1000))] + (h/advance-timers-by-time 100) + (h/fire-event + :on-responder-release + (h/get-by-test-id "record-audio") + {:nativeEvent {:locationX 70 + :locationY 70 + :timestamp 200 + :identifier 0}}) + (h/advance-timers-by-time 250) + (-> (h/expect event) + (.toHaveBeenCalledTimes 1)))))) (h/test "record-audio on-send works after reviewing audio" - (let [event (js/jest.fn)] + (let [event (js/jest.fn) + on-meter (reagent/atom nil)] (h/render [record-audio/record-audio {:on-send event :record-audio-permission-granted true}]) - (with-redefs [audio/start-recording (fn [_ on-start _] - (on-start)) + (with-redefs [audio/new-recorder (fn [_ on-meter-fn _] + (reset! on-meter on-meter-fn)) + audio/start-recording (fn [_ on-start _] + (on-start) + (js/setInterval #(@on-meter) 100)) audio/get-recorder-file-path (fn [] "audio-file-path") audio/get-player-duration (fn [] 5000)] (h/fire-event @@ -76,46 +87,57 @@ :locationY 70 :timestamp 0 :identifier 0}}) - (h/advance-timers-by-time 500) - (h/fire-event - :on-responder-release - (h/get-by-test-id "record-audio") - {:nativeEvent {:locationX 70 - :locationY 70 - :timestamp 200 - :identifier 0}}) - (h/fire-event - :on-start-should-set-responder - (h/get-by-test-id "record-audio") - {:nativeEvent {:locationX 70 - :locationY 70 - :timestamp 0 - :identifier 0}}) - (h/advance-timers-by-time 500) - (h/fire-event - :on-responder-release - (h/get-by-test-id "record-audio") - {:nativeEvent {:locationX 80 - :locationY 80 - :timestamp 200 - :identifier 0}}) - (h/advance-timers-by-time 250) - (-> (js/expect event) - (.toHaveBeenCalledTimes 1)) - (-> (js/expect event) - (.toHaveBeenCalledWith {:file-path "audio-file-path" - :duration 5000}))))) + (with-redefs [datetime/timestamp (fn [] (+ (.now js/Date) 1000))] + (h/advance-timers-by-time 100) + (h/fire-event + :on-responder-release + (h/get-by-test-id "record-audio") + {:nativeEvent {:locationX 70 + :locationY 70 + :timestamp 200 + :identifier 0}}) + (h/fire-event + :on-start-should-set-responder + (h/get-by-test-id "record-audio") + {:nativeEvent {:locationX 70 + :locationY 70 + :timestamp 0 + :identifier 0}}) + (h/advance-timers-by-time 500) + (h/fire-event + :on-responder-release + (h/get-by-test-id "record-audio") + {:nativeEvent {:locationX 80 + :locationY 80 + :timestamp 200 + :identifier 0}}) + (h/advance-timers-by-time 250) + (-> (js/expect event) + (.toHaveBeenCalledTimes 1)) + (-> (js/expect event) + (.toHaveBeenCalledWith {:file-path "audio-file-path" + :duration 5000})))))) (h/test "record-audio on-send works after sliding to the send button" - (let [event (js/jest.fn)] + (let [event (js/jest.fn) + on-meter (reagent/atom nil) + last-now-ms (atom nil) + duration-ms (atom nil)] (h/render [record-audio/record-audio {:on-send event :record-audio-permission-granted true}]) - (with-redefs [audio/start-recording (fn [_ on-start _] - (on-start)) + (with-redefs [audio/new-recorder (fn [_ on-meter-fn _] + (reset! on-meter on-meter-fn)) + audio/start-recording (fn [_ on-start _] + (on-start) + (js/setInterval #(@on-meter) 100)) audio/stop-recording (fn [_ on-stop _] (on-stop)) - audio/get-recorder-file-path (fn [] "audio-file-path")] + audio/get-recorder-file-path (fn [] "audio-file-path") + datetime/timestamp (fn [] + (let [now-ms (.now js/Date)] + (reset! last-now-ms now-ms) + now-ms))] (h/fire-event :on-start-should-set-responder (h/get-by-test-id "record-audio") @@ -123,36 +145,46 @@ :locationY 70 :timestamp 0 :identifier 0}}) - (h/advance-timers-by-time 500) - (h/fire-event - :on-responder-move - (h/get-by-test-id "record-audio") - {:nativeEvent {:locationX 80 - :locationY -30 - :pageX 80 - :pageY -30 - :identifier 0}}) - (h/fire-event - :on-responder-release - (h/get-by-test-id "record-audio") - {:nativeEvent {:locationX 40 - :locationY 80 - :timestamp 200 - :identifier 0}}) - (h/advance-timers-by-time 250) - (-> (js/expect event) - (.toHaveBeenCalledTimes 1)) - (-> (js/expect event) - (.toHaveBeenCalledWith {:file-path "audio-file-path" - :duration 500}))))) + (with-redefs [datetime/timestamp (fn [] + (let [now-plus-ms (+ (.now js/Date) 1000) + time-diff-ms (- now-plus-ms @last-now-ms)] + (when-not @duration-ms + (reset! duration-ms time-diff-ms)) + now-plus-ms))] + (h/advance-timers-by-time 100) + (h/fire-event + :on-responder-move + (h/get-by-test-id "record-audio") + {:nativeEvent {:locationX 80 + :locationY -30 + :pageX 80 + :pageY -30 + :identifier 0}}) + (h/fire-event + :on-responder-release + (h/get-by-test-id "record-audio") + {:nativeEvent {:locationX 40 + :locationY 80 + :timestamp 200 + :identifier 0}}) + (h/advance-timers-by-time 250) + (-> (js/expect event) + (.toHaveBeenCalledTimes 1)) + (-> (js/expect event) + (.toHaveBeenCalledWith {:file-path "audio-file-path" + :duration @duration-ms})))))) (h/test "record-audio on-cancel works after reviewing audio" - (let [event (js/jest.fn)] + (let [event (js/jest.fn) + on-meter (reagent/atom nil)] (h/render [record-audio/record-audio {:on-cancel event :record-audio-permission-granted true}]) - (with-redefs [audio/start-recording (fn [_ on-start _] - (on-start))] + (with-redefs [audio/new-recorder (fn [_ on-meter-fn _] + (reset! on-meter on-meter-fn)) + audio/start-recording (fn [_ on-start _] + (on-start) + (js/setInterval #(@on-meter) 100))] (h/fire-event :on-start-should-set-responder (h/get-by-test-id "record-audio") @@ -160,32 +192,37 @@ :locationY 70 :timestamp 0 :identifier 0}}) - (h/advance-timers-by-time 500) - (h/fire-event - :on-responder-release - (h/get-by-test-id "record-audio") - {:nativeEvent {:locationX 70 - :locationY 70 - :timestamp 200 - :identifier 0}}) - (h/fire-event - :on-responder-release - (h/get-by-test-id "record-audio") - {:nativeEvent {:locationX 40 - :locationY 80 - :timestamp 200 - :identifier 0}}) - (h/advance-timers-by-time 250) - (-> (js/expect event) - (.toHaveBeenCalledTimes 1))))) + (with-redefs [datetime/timestamp (fn [] (+ (.now js/Date) 1000))] + (h/advance-timers-by-time 500) + (h/fire-event + :on-responder-release + (h/get-by-test-id "record-audio") + {:nativeEvent {:locationX 70 + :locationY 70 + :timestamp 200 + :identifier 0}}) + (h/fire-event + :on-responder-release + (h/get-by-test-id "record-audio") + {:nativeEvent {:locationX 40 + :locationY 80 + :timestamp 200 + :identifier 0}}) + (h/advance-timers-by-time 250) + (-> (js/expect event) + (.toHaveBeenCalledTimes 1)))))) - (h/test "cord-audio on-cancel works after sliding to the cancel button" - (let [event (js/jest.fn)] + (h/test "record-audio on-cancel works after sliding to the cancel button" + (let [event (js/jest.fn) + on-meter (reagent/atom nil)] (h/render [record-audio/record-audio {:on-cancel event :record-audio-permission-granted true}]) - (with-redefs [audio/start-recording (fn [_ on-start _] - (on-start)) + (with-redefs [audio/new-recorder (fn [_ on-meter-fn _] + (reset! on-meter on-meter-fn)) + audio/start-recording (fn [_ on-start _] + (on-start) + (js/setInterval #(@on-meter) 100)) audio/stop-recording (fn [_ on-stop _] (on-stop))] (h/fire-event @@ -195,22 +232,25 @@ :locationY 70 :timestamp 0 :identifier 0}}) - (h/advance-timers-by-time 500) - (h/fire-event - :on-responder-move - (h/get-by-test-id "record-audio") - {:nativeEvent {:locationX -30 - :locationY 80 - :pageX -30 - :pageY 80 - :identifier 0}}) - (h/fire-event - :on-responder-release - (h/get-by-test-id "record-audio") - {:nativeEvent {:locationX -10 - :locationY 70 - :timestamp 200 - :identifier 0}}) - (h/advance-timers-by-time 250) - (-> (js/expect event) - (.toHaveBeenCalledTimes 1)))))) + (with-redefs [datetime/timestamp (fn [] (+ (.now js/Date) 1000))] + (h/advance-timers-by-time 500) + (h/fire-event + :on-responder-move + (h/get-by-test-id "record-audio") + {:nativeEvent {:locationX -30 + :locationY 80 + :pageX -30 + :pageY 80 + :identifier 0}}) + (h/fire-event + :on-responder-release + (h/get-by-test-id "record-audio") + {:nativeEvent {:locationX -10 + :locationY 70 + :timestamp 200 + :identifier 0}}) + (h/advance-timers-by-time 250) + (-> (js/expect event) + (.toHaveBeenCalledTimes 1))))))) + + diff --git a/src/quo2/components/record_audio/record_audio/buttons/record_button_big.cljs b/src/quo2/components/record_audio/record_audio/buttons/record_button_big.cljs index bc2ff7746a..3ee2b2e7be 100644 --- a/src/quo2/components/record_audio/record_audio/buttons/record_button_big.cljs +++ b/src/quo2/components/record_audio/record_audio/buttons/record_button_big.cljs @@ -29,7 +29,7 @@ (defn f-record-button-big [recording? ready-to-send? ready-to-lock? ready-to-delete? record-button-is-animating? - record-button-at-initial-position? locked? reviewing-audio? recording-timer recording-length-ms + record-button-at-initial-position? locked? reviewing-audio? recording-length-ms clear-timeout touch-active? recorder-ref reload-recorder-fn idle? on-send on-cancel] (let [scale (reanimated/use-shared-value 1) opacity (reanimated/use-shared-value 0) @@ -82,7 +82,6 @@ (reset! ready-to-lock? false) (reset! idle? true) (js/setTimeout #(reset! idle? false) 1000) - (js/clearInterval @recording-timer) (reset! recording-length-ms 0) (log/debug "[record-audio] stop recording - success")) #(log/error "[record-audio] stop recording - error: " %)))) diff --git a/src/quo2/components/record_audio/record_audio/view.cljs b/src/quo2/components/record_audio/record_audio/view.cljs index 3ee39279b8..c52fbc5528 100644 --- a/src/quo2/components/record_audio/record_audio/view.cljs +++ b/src/quo2/components/record_audio/record_audio/view.cljs @@ -15,11 +15,13 @@ [quo2.components.record-audio.record-audio.buttons.lock-button :as lock-button] [quo2.components.record-audio.record-audio.buttons.delete-button :as delete-button] [quo2.components.record-audio.record-audio.buttons.record-button :as record-button] - [clojure.string :as string])) + [clojure.string :as string] + [utils.datetime :as datetime] + [react-native.platform :as platform])) -(def ^:private min-audio-duration-ms 500) -(def ^:private max-audio-duration-ms 120000) -(def ^:private metering-interval 100) +(def ^:private min-audio-duration-ms 1000) +(def ^:private max-audio-duration-ms (if platform/ios? 120800 120500)) +(def ^:private metering-interval 25) (def ^:private base-filename "am") (def ^:private default-format ".aac") @@ -108,7 +110,7 @@ time-str]])) (defn- f-play-button - [playing-audio? player-ref playing-timer audio-current-time-ms seeking-audio?] + [playing-audio? player-ref playing-timer audio-current-time-ms seeking-audio? max-duration-ms] (let [on-play (fn [] (reset! playing-audio? true) (reset! playing-timer @@ -117,8 +119,22 @@ (let [current-time (audio/get-player-current-time @player-ref) player-state (audio/get-state @player-ref) playing? (= player-state audio/PLAYING)] - (when (and playing? (not @seeking-audio?) (> current-time 0)) - (reset! audio-current-time-ms current-time)))) + (when (and playing? + (not @seeking-audio?) + (> current-time 0) + (< current-time max-duration-ms)) + (reset! audio-current-time-ms current-time)) + (when (>= current-time max-duration-ms) + (audio/stop-playing + @player-ref + (fn [] + (reset! playing-audio? false) + (when @playing-timer + (js/clearInterval @playing-timer) + (reset! playing-timer nil) + (reset! audio-current-time-ms 0) + (reset! seeking-audio? false))) + #(log/error "[record-audio] stop player - error: " %))))) 100))) on-pause (fn [] (reset! playing-audio? false) @@ -143,7 +159,7 @@ [{:keys [on-init on-start-recording on-send on-cancel on-reviewing-audio record-audio-permission-granted on-request-record-audio-permission on-check-audio-permissions - audio-file on-lock]}] + audio-file on-lock max-duration-ms]}] [:f> ;; TODO we need to refactor this, and use :f> with defined function, currenly state is reseted each ;; time parent component @@ -160,6 +176,7 @@ audio-current-time-ms (reagent/atom 0) seeking-audio? (reagent/atom false) force-show-controls? (reagent/atom (some? audio-file)) + recording-start-ms (atom (datetime/timestamp)) clear-timeout (atom nil) record-button-at-initial-position? (atom true) record-button-is-animating? (atom false) @@ -167,7 +184,6 @@ recorder-ref (atom nil) player-ref (atom nil) touch-active? (atom false) - recording-timer (atom nil) playing-timer (atom nil) output-file (atom audio-file) reached-max-duration? (atom false) @@ -178,7 +194,7 @@ rec-options (merge audio/default-recorder-options - {:filename (str base-filename (.now js/Date) default-format) + {:filename (str base-filename (datetime/timestamp) default-format) :meteringInterval metering-interval}) destroy-player (fn [] @@ -209,13 +225,44 @@ (fn [] (audio/destroy-recorder @recorder-ref) (reset! recorder-ref nil)) + recorder-on-meter + (fn [] + (when @recording-start-ms + (let [now-ms (datetime/timestamp) + recording-duration (- now-ms + @recording-start-ms)] + (reset! recording-length-ms recording-duration) + (when (>= recording-duration max-audio-duration-ms) + (reset! reached-max-duration? (not @locked?)) + (reset! reviewing-audio? true) + (reset! idle? false) + (reset! locked? false) + (reset! recording? false) + (reset! ready-to-lock? false) + (reset! ready-to-send? false) + (reset! ready-to-delete? false) + (audio/stop-recording + @recorder-ref + (fn [] + (reset! output-file (audio/get-recorder-file-path + @recorder-ref)) + (reload-player nil) + (log/debug "[record-audio] stop recording - success")) + #(log/error "[record-audio] stop recording - error: " %)) + (js/setTimeout #(reset! idle? false) 1000) + (reset! recording-length-ms 0) + (reset! recording-start-ms nil) + (when on-reviewing-audio + (on-reviewing-audio (audio/get-recorder-file-path + @recorder-ref)))) + (log/debug "[record-audio] new recorder - on meter")))) reload-recorder (fn [] (when @recorder-ref (destroy-recorder)) (reset! recorder-ref (audio/new-recorder rec-options - #(log/debug "[record-audio] new recorder - on meter") + recorder-on-meter #(log/debug "[record-audio] new recorder - on ended")))) reset-recorder (fn [] @@ -238,9 +285,6 @@ (when @clear-timeout (js/clearTimeout @clear-timeout) (reset! clear-timeout nil)) - (when @recording-timer - (js/clearInterval @recording-timer) - (reset! recording-timer nil)) (when @playing-timer (js/clearInterval @playing-timer) (reset! playing-timer nil)) @@ -258,7 +302,7 @@ record-button-area) new-recorder (audio/new-recorder rec-options - #(log/debug "[record-audio] new recorder - on meter") + recorder-on-meter #(log/debug "[record-audio] new recorder - on ended"))] (reset! touch-timestamp (oops/oget e "nativeEvent.timestamp")) (reset! touch-identifier (oops/oget e "nativeEvent.identifier")) @@ -269,44 +313,13 @@ (reset! recording? pressed-record-button?)) (when pressed-record-button? (reset! playing-audio? false) - (when @recording-timer - (js/clearInterval @recording-timer)) (reset! output-file nil) (reset! recorder-ref new-recorder) (audio/start-recording new-recorder (fn [] + (reset! recording-start-ms (datetime/timestamp)) (reset! audio-current-time-ms 0) - (reset! recording-timer - (js/setInterval - (fn [] - (if (< @recording-length-ms max-audio-duration-ms) - (reset! recording-length-ms - (+ @recording-length-ms metering-interval)) - (do - (reset! reached-max-duration? (not @locked?)) - (reset! reviewing-audio? true) - (reset! idle? false) - (reset! locked? false) - (reset! recording? false) - (reset! ready-to-lock? false) - (reset! ready-to-send? false) - (reset! ready-to-delete? false) - (audio/stop-recording - new-recorder - (fn [] - (reset! output-file (audio/get-recorder-file-path - new-recorder)) - (reload-player nil) - (log/debug "[record-audio] stop recording - success")) - #(log/error "[record-audio] stop recording - error: " %)) - (js/setTimeout #(reset! idle? false) 1000) - (js/clearInterval @recording-timer) - (reset! recording-length-ms 0) - (when on-reviewing-audio - (on-reviewing-audio (audio/get-recorder-file-path - new-recorder)))))) - metering-interval)) (log/debug "[record-audio] start recording - success")) #(log/error "[record-audio] start recording - error: " %)) (when on-start-recording @@ -424,7 +437,8 @@ (reset! force-show-controls? false) (when on-send (on-send {:file-path @output-file - :duration (int (audio/get-player-duration @player-ref))})) + :duration (min max-audio-duration-ms + (int (audio/get-player-duration @player-ref)))})) (when @player-ref (audio/stop-playing @player-ref @@ -475,8 +489,8 @@ (log/debug "[record-audio] stop recording - success")) #(log/error "[record-audio] stop recording - error: " %)) (js/setTimeout #(reset! idle? false) 1000) - (js/clearInterval @recording-timer) (reset! recording-length-ms 0) + (reset! recording-start-ms nil) (reset! disabled? false)) (if (> touch-timestamp-diff min-touch-duration) 0 250))) (and (not @locked?) (not @reviewing-audio?) (not @record-button-is-animating?)) @@ -501,8 +515,8 @@ (reset! ready-to-lock? false) (reset! idle? true) (js/setTimeout #(reset! idle? false) 1000) - (js/clearInterval @recording-timer) (reset! recording-length-ms 0) + (reset! recording-start-ms nil) (reset! disabled? false) (log/debug "[record-audio] stop recording - success")) #(log/error "[record-audio] stop recording - error: " %))) @@ -532,11 +546,12 @@ (when @reviewing-audio? [:<> [:f> f-play-button playing-audio? player-ref playing-timer audio-current-time-ms - seeking-audio?] + seeking-audio? max-duration-ms] [:f> soundtrack/f-soundtrack {:audio-current-time-ms audio-current-time-ms :player-ref @player-ref - :seeking-audio? seeking-audio?}]]) + :seeking-audio? seeking-audio? + :max-audio-duration-ms max-duration-ms}]]) (when (or @recording? @reviewing-audio?) [:f> f-time-counter @recording? @recording-length-ms @ready-to-delete? @reviewing-audio? @audio-current-time-ms]) @@ -567,7 +582,6 @@ record-button-at-initial-position? locked? reviewing-audio? - recording-timer recording-length-ms clear-timeout touch-active? diff --git a/src/quo2/components/record_audio/soundtrack/view.cljs b/src/quo2/components/record_audio/soundtrack/view.cljs index 6e6c7279f3..eb75801415 100644 --- a/src/quo2/components/record_audio/soundtrack/view.cljs +++ b/src/quo2/components/record_audio/soundtrack/view.cljs @@ -10,8 +10,8 @@ (def ^:private thumb-dark (js/require "../resources/images/icons2/12x12/thumb-dark.png")) (defn f-soundtrack - [{:keys [audio-current-time-ms player-ref style seeking-audio?]}] - (let [audio-duration-ms (audio/get-player-duration player-ref)] + [{:keys [audio-current-time-ms player-ref style seeking-audio? max-audio-duration-ms]}] + (let [audio-duration-ms (min max-audio-duration-ms (audio/get-player-duration player-ref))] [:<> [slider/slider {:test-ID "soundtrack" diff --git a/src/status_im2/constants.cljs b/src/status_im2/constants.cljs index 23c5543000..bbcd13e8a8 100644 --- a/src/status_im2/constants.cljs +++ b/src/status_im2/constants.cljs @@ -334,3 +334,5 @@ (def ^:const auth-method-none "none") (def ^:const image-description-in-lightbox? false) + +(def ^:const audio-max-duration-ms 120000) diff --git a/src/status_im2/contexts/chat/composer/actions/view.cljs b/src/status_im2/contexts/chat/composer/actions/view.cljs index cf53b25daf..a0f9d3d98d 100644 --- a/src/status_im2/contexts/chat/composer/actions/view.cljs +++ b/src/status_im2/contexts/chat/composer/actions/view.cljs @@ -7,29 +7,30 @@ [react-native.reanimated :as reanimated] [reagent.core :as reagent] [status-im2.common.alert.events :as alert] - [status-im2.contexts.chat.composer.constants :as constants] + [status-im2.contexts.chat.composer.constants :as comp-constants] [status-im2.contexts.chat.messages.list.view :as messages.list] [utils.i18n :as i18n] [utils.re-frame :as rf] - [status-im2.contexts.chat.composer.actions.style :as style])) + [status-im2.contexts.chat.composer.actions.style :as style] + [status-im2.constants :as constants])) (defn send-message [{:keys [sending-images? sending-links?]} {:keys [text-value focused? maximized?]} {:keys [height saved-height last-height opacity background-y container-opacity]} window-height] - (reanimated/animate height constants/input-height) - (reanimated/set-shared-value saved-height constants/input-height) - (reanimated/set-shared-value last-height constants/input-height) + (reanimated/animate height comp-constants/input-height) + (reanimated/set-shared-value saved-height comp-constants/input-height) + (reanimated/set-shared-value last-height comp-constants/input-height) (reanimated/animate opacity 0) (when-not @focused? - (js/setTimeout #(reanimated/animate container-opacity constants/empty-opacity) 300)) + (js/setTimeout #(reanimated/animate container-opacity comp-constants/empty-opacity) 300)) (js/setTimeout #(reanimated/set-shared-value background-y (- window-height)) 300) (rf/dispatch [:chat.ui/send-current-message]) (rf/dispatch [:chat.ui/set-input-maximized false]) - (rf/dispatch [:chat.ui/set-input-content-height constants/input-height]) + (rf/dispatch [:chat.ui/set-input-content-height comp-constants/input-height]) (rf/dispatch [:chat.ui/set-chat-input-text nil]) (reset! maximized? false) (reset! text-value "") @@ -105,7 +106,7 @@ (rf/dispatch [:chat/send-audio file-path duration]) (if-not @focused? (reanimated/animate container-opacity - constants/empty-opacity) + comp-constants/empty-opacity) (js/setTimeout #(when @input-ref (.focus ^js @input-ref)) 300)) (rf/dispatch [:chat.ui/set-input-audio nil])) @@ -116,7 +117,7 @@ (reset! gesture-enabled? true) (if-not @focused? (reanimated/animate container-opacity - constants/empty-opacity) + comp-constants/empty-opacity) (js/setTimeout #(when @input-ref (.focus ^js @input-ref)) 300)) @@ -143,7 +144,8 @@ {:text (i18n/label :t/settings) :accessibility-label :settings-button :onPress (fn [] (permissions/open-settings))})) - 50)}]))}]])) + 50)}])) + :max-duration-ms constants/audio-max-duration-ms}]])) (defn camera-button diff --git a/src/status_im2/contexts/chat/messages/content/audio/view.cljs b/src/status_im2/contexts/chat/messages/content/audio/view.cljs index a337c94b39..4ff9532739 100644 --- a/src/status_im2/contexts/chat/messages/content/audio/view.cljs +++ b/src/status_im2/contexts/chat/messages/content/audio/view.cljs @@ -10,7 +10,8 @@ [quo2.core :as quo] [react-native.core :as rn] [utils.re-frame :as rf] - [utils.i18n :as i18n])) + [utils.i18n :as i18n] + [status-im2.constants :as constants])) (def ^:const media-server-uri-prefix "https://localhost:") (def ^:const audio-path "/messages/audio") @@ -104,8 +105,21 @@ (let [player (@active-players player-key) current-time (audio/get-player-current-time player) playing? (= @player-state :playing)] - (when (and playing? (not @seeking-audio?) (> current-time 0)) - (reset! progress current-time)))) + (when (and playing? + (not @seeking-audio?) + (> current-time 0) + (< current-time constants/audio-max-duration-ms)) + (reset! progress current-time)) + (when (>= current-time constants/audio-max-duration-ms) + (audio/stop-playing + player + (fn [] + (update-state player-state :ready-to-play) + (reset! progress 0) + (when (and @progress-timer (= @current-player-key player-key)) + (js/clearInterval @progress-timer) + (reset! progress-timer nil))) + #(log/error "[audio-message] stop player - error: " %))))) 100))) (fn [] (update-state player-state :ready-to-play) @@ -135,9 +149,7 @@ {:keys [in-pinned-view?]}] (let [player-key (get-player-key message-id in-pinned-view?) player (@active-players player-key) - duration (if (and player (not (#{:preparing :not-loaded :error} @player-state))) - (audio/get-player-duration player) - audio-duration-ms) + duration (min constants/audio-max-duration-ms audio-duration-ms) time-secs (quot (if (or @seeking-audio? (#{:playing :seeking} @player-state)) (if (<= @progress 1) (* duration @progress) @progress) @@ -200,7 +212,8 @@ {:style style/slider-container :audio-current-time-ms progress :player-ref (@active-players player-key) - :seeking-audio? seeking-audio?}] + :seeking-audio? seeking-audio? + :max-audio-duration-ms constants/audio-max-duration-ms}] [quo/text {:style style/timestamp :accessibility-label :audio-duration-label diff --git a/src/status_im2/contexts/quo_preview/record_audio/record_audio.cljs b/src/status_im2/contexts/quo_preview/record_audio/record_audio.cljs index c46fa830f7..dcc9cf6603 100644 --- a/src/status_im2/contexts/quo_preview/record_audio/record_audio.cljs +++ b/src/status_im2/contexts/quo_preview/record_audio/record_audio.cljs @@ -6,7 +6,8 @@ [utils.re-frame :as rf] [status-im2.common.alert.events :as alert] [utils.i18n :as i18n] - [react-native.permissions :as permissions])) + [react-native.permissions :as permissions] + [status-im2.constants :as constants])) (defonce record-audio-permission-granted (reagent/atom false)) @@ -52,7 +53,8 @@ :on-reviewing-audio on-reviewing-audio :on-cancel on-cancel :on-check-audio-permissions on-check-audio-permissions - :on-request-record-audio-permission on-request-record-audio-permission}]] + :on-request-record-audio-permission on-request-record-audio-permission + :max-duration-ms constants/audio-max-duration-ms}]] [quo/text {:style {:margin-horizontal 20}} @message]]))) (defn preview-record-audio