|
20 | 20 | (defonce current-active-state-ref-ref (atom nil))
|
21 | 21 | (defonce progress-timer (atom nil))
|
22 | 22 |
|
23 |
| -(defn start-stop-progress-timer |
24 |
| - [{:keys [state-ref progress-ref progress-anim]} start?] |
25 |
| - (when @progress-timer |
26 |
| - (utils/clear-interval @progress-timer) |
27 |
| - (when-not start? |
28 |
| - (reset! progress-timer nil))) |
29 |
| - (when start? |
30 |
| - (when @progress-timer |
31 |
| - (utils/clear-interval @progress-timer)) |
32 |
| - (reset! progress-timer |
33 |
| - (utils/set-interval |
34 |
| - #(when (and @state-ref (not (:slider-seeking @state-ref))) |
35 |
| - (let [ct (audio/get-player-current-time @player-ref)] |
36 |
| - (reset! progress-ref ct) |
37 |
| - (when ct |
38 |
| - (anim/start (anim/timing progress-anim |
39 |
| - {:toValue @progress-ref |
40 |
| - :duration 100 |
41 |
| - :easing (.-linear ^js anim/easing) |
42 |
| - :useNativeDriver true}))))) |
43 |
| - 100)))) |
44 |
| - |
45 | 23 | (defn update-state
|
46 | 24 | [{:keys [state-ref progress-ref progress-anim message-id seek-to-ms audio-duration-ms
|
47 | 25 | slider-new-state-seeking? unloaded? error]}]
|
|
90 | 68 |
|
91 | 69 | ; update progress UI on slider release
|
92 | 70 | (when (and (some? slider-new-state-seeking?) (not slider-new-state-seeking?) (some? seek-to-ms))
|
93 |
| - (reset! (:progress-ref new-state) seek-to-ms)) |
94 |
| - |
95 |
| - ; update progres anim value to follow the slider |
96 |
| - (when (and slider-seeking (some? seek-to-ms)) |
97 |
| - (anim/set-value (:progress-anim new-state) seek-to-ms)) |
98 |
| - |
99 |
| - ; on unload, reset values |
100 |
| - (when unloaded? |
101 |
| - (reset! (:progress-ref new-state) 0) |
102 |
| - (anim/set-value (:progress-anim new-state) 0)))) |
| 71 | + (reset! (:progress-ref new-state) seek-to-ms)))) |
103 | 72 |
|
104 | 73 | (defn destroy-player
|
105 | 74 | [{:keys [message-id reloading?]}]
|
|
162 | 131 | (update-state params)))))
|
163 | 132 |
|
164 | 133 | (defn play-pause
|
165 |
| - [{:keys [message-id state-ref] :as params} audio] |
| 134 | + [{:keys [message-id state-ref] :as params} audio seeking-audio?] |
166 | 135 | (if (not= message-id @current-player-message-id)
|
167 | 136 | ;; player has audio from another message, we need to reload
|
168 | 137 | (reload-player params
|
169 | 138 | audio
|
170 | 139 | ;; on-success: audio is loaded, do we have an existing value to seek to?
|
171 |
| - #(if-some [seek-time (:seek-to-ms @state-ref)] |
172 |
| - ;; check seek time against real audio duration and play |
173 |
| - (let [checked-seek-time (min (audio/get-player-duration @player-ref) seek-time)] |
174 |
| - (seek params |
175 |
| - checked-seek-time |
176 |
| - true |
177 |
| - (fn [] (play-pause params audio)))) |
178 |
| - |
179 |
| - ;; nothing to seek to, play |
180 |
| - (play-pause params audio))) |
| 140 | + (fn [] |
| 141 | + (reset! seeking-audio? false) |
| 142 | + (if-some [seek-time (:seek-to-ms @state-ref)] |
| 143 | + ;; check seek time against real audio duration and play |
| 144 | + (let [checked-seek-time (min (audio/get-player-duration @player-ref) seek-time)] |
| 145 | + (seek params |
| 146 | + checked-seek-time |
| 147 | + true |
| 148 | + (fn [] (play-pause params audio)))) |
| 149 | + |
| 150 | + ;; nothing to seek to, play |
| 151 | + (play-pause params audio)))) |
181 | 152 |
|
182 | 153 | ;; loaded audio corresponds to current message we can play
|
183 | 154 | (when @player-ref
|
184 | 155 | (audio/toggle-playpause-player
|
185 | 156 | @player-ref
|
186 | 157 | #(do
|
187 |
| - (start-stop-progress-timer params true) |
188 | 158 | (update-state params))
|
189 | 159 | #(do
|
190 |
| - (start-stop-progress-timer params false) |
191 | 160 | (update-state params))
|
192 | 161 | #(update-state (merge params {:error (:message %)}))))))
|
193 | 162 |
|
|
199 | 168 | [quo/icon
|
200 | 169 | (case (:general @state-ref)
|
201 | 170 | :preparing :i/loading
|
202 |
| - :playing :i/play-audio |
203 |
| - :i/pause-audio) |
| 171 | + :playing :i/pause-audio |
| 172 | + :i/play-audio) |
204 | 173 | {:size 20
|
205 | 174 | :accessibility-label :play-pause-audio-message-button
|
206 | 175 | :color colors/white}]])
|
207 | 176 |
|
208 | 177 | (defview message-content
|
209 | 178 | [{:keys [audio audio-duration-ms message-id]}]
|
210 |
| - (letsubs [state (reagent/atom nil) |
211 |
| - progress (reagent/atom 0) |
212 |
| - progress-anim (anim/create-value 0) |
213 |
| - width [:dimensions/window-width]] |
| 179 | + (letsubs [state (reagent/atom nil) |
| 180 | + progress (reagent/atom 0) |
| 181 | + seeking-audio? (reagent/atom false)] |
214 | 182 | {:component-did-mount (fn []
|
215 | 183 | (update-state {:state-ref state
|
216 | 184 | :audio-duration-ms audio-duration-ms
|
217 | 185 | :message-id message-id
|
218 | 186 | :unloaded? true
|
219 |
| - :progress-ref progress |
220 |
| - :progress-anim progress-anim})) |
| 187 | + :progress-ref progress})) |
221 | 188 | :component-will-unmount (fn []
|
222 | 189 | (destroy-player {:state-ref state :message-id message-id})
|
223 | 190 | (when (= @current-player-message-id message-id)
|
224 | 191 | (reset! current-active-state-ref-ref nil)
|
225 | 192 | (reset! current-player-message-id nil))
|
226 | 193 | (reset! state nil))}
|
227 | 194 |
|
228 |
| - (let [base-params {:state-ref state |
229 |
| - :message-id message-id |
230 |
| - :progress-ref progress |
231 |
| - :progress-anim progress-anim}] |
| 195 | + (let [base-params {:state-ref state |
| 196 | + :message-id message-id |
| 197 | + :progress-ref progress}] |
232 | 198 | (if (= (:general @state) :error)
|
233 | 199 | [react/text
|
234 | 200 | {:style {:typography :main-medium
|
235 | 201 | :margin-bottom 16}} (:error-msg @state)]
|
236 |
| - [react/view {:style {:width 295 |
237 |
| - :height 56 |
238 |
| - :border-radius 12 |
239 |
| - :border-width 1 |
240 |
| - :padding 12 |
241 |
| - :align-items :center |
242 |
| - :border-color (colors/theme-colors colors/neutral-20 colors/neutral-80) |
243 |
| - :background-color (colors/theme-colors colors/neutral-5 colors/neutral-80-opa-40)}} |
244 |
| - [react/view style/play-pause-slider-container |
245 |
| - [play-pause-button state #(play-pause base-params audio)] |
246 |
| - [react/view style/slider-container |
247 |
| - [quo/soundtrack |
248 |
| - {:audio-current-time-ms (:progress-ref base-params) |
249 |
| - :player-ref player-ref |
250 |
| - :seeking-audio? (:slider-seeking @state)}]]] |
251 |
| - |
252 |
| - [react/view style/times-container |
253 |
| - [quo/text {:style (style/timestamp) |
254 |
| - :accessibility-label :audio-duration-label |
255 |
| - :weight :regular |
256 |
| - :size :paragraph-1} |
257 |
| - (let [time (cond |
258 |
| - (or (:slider-seeking @state) (> (:seek-to-ms @state) 0)) (:seek-to-ms @state) |
259 |
| - (#{:playing :paused :seeking} (:general @state)) @progress |
260 |
| - :else (:duration @state)) |
261 |
| - s (quot time 1000)] |
262 |
| - (gstring/format "%02d:%02d" (quot s 60) (mod s 60)))]]])))) |
| 202 | + [react/view {:style (style/container)} |
| 203 | + [play-pause-button state #(play-pause base-params audio seeking-audio?)] |
| 204 | + [quo/soundtrack |
| 205 | + {:style style/slider-container |
| 206 | + :audio-current-time-ms progress |
| 207 | + :player-ref player-ref |
| 208 | + :seeking-audio? seeking-audio?}] |
| 209 | + [quo/text |
| 210 | + {:style style/timestamp |
| 211 | + :accessibility-label :audio-duration-label |
| 212 | + :weight :medium |
| 213 | + :size :paragraph-2} |
| 214 | + (let [duration-ms (:duration @state) |
| 215 | + duration-secs (quot duration-ms 1000)] |
| 216 | + (gstring/format "%02d:%02d" (quot duration-secs 60) (mod duration-secs 60)))]])))) |
0 commit comments