Poder controlar el audio y su velocidad
This commit is contained in:
parent
61bd6fca46
commit
1801de0a54
1 changed files with 132 additions and 0 deletions
132
patches/0009-show-audio-controls-and-speed.diff
Normal file
132
patches/0009-show-audio-controls-and-speed.diff
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
diff -Naur orig.orig/components/commons/Audio.jsx orig/components/commons/Audio.jsx
|
||||||
|
--- orig.orig/components/commons/Audio.jsx 1969-12-31 21:00:00.000000000 -0300
|
||||||
|
+++ orig/components/commons/Audio.jsx 2021-10-15 16:28:48.809523282 -0300
|
||||||
|
@@ -0,0 +1,76 @@
|
||||||
|
+import { forwardRef, useState, useEffect } from 'react';
|
||||||
|
+
|
||||||
|
+// https://formidable.com/blog/2021/stores-no-context-api/
|
||||||
|
+const createEmitter = () => {
|
||||||
|
+ const subscriptions = new Map();
|
||||||
|
+ return {
|
||||||
|
+ emit: (v) => subscriptions.forEach(fn => fn(v)),
|
||||||
|
+ subscribe: (fn) => {
|
||||||
|
+ const key = Symbol();
|
||||||
|
+ subscriptions.set(key, fn);
|
||||||
|
+ return () => subscriptions.delete(key);
|
||||||
|
+ },
|
||||||
|
+ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+const createStore = (init) => {
|
||||||
|
+ // create an emitter
|
||||||
|
+ const emitter = createEmitter();
|
||||||
|
+
|
||||||
|
+ let store = null;
|
||||||
|
+ const get = () => store;
|
||||||
|
+ const set = (op) => (
|
||||||
|
+ store = op(store),
|
||||||
|
+ // notify all subscriptions when the store updates
|
||||||
|
+ emitter.emit(store)
|
||||||
|
+ );
|
||||||
|
+ store = init(get, set);
|
||||||
|
+
|
||||||
|
+ const useStore = () => {
|
||||||
|
+ // intitialize component with latest store
|
||||||
|
+ const [localStore, setLocalStore] = useState(get());
|
||||||
|
+
|
||||||
|
+ // update our local store when the global
|
||||||
|
+ // store updates.
|
||||||
|
+ //
|
||||||
|
+ // emitter.subscribe returns a cleanup
|
||||||
|
+ // function, so react will clean this
|
||||||
|
+ // up on unmount.
|
||||||
|
+ useEffect(() => emitter.subscribe(setLocalStore), []);
|
||||||
|
+ return localStore;
|
||||||
|
+ };
|
||||||
|
+ return useStore;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+const useSpeed = createStore((get, set) => ({
|
||||||
|
+ value: 1,
|
||||||
|
+ set: value => set((state) => ({ ...state, value })),
|
||||||
|
+}));
|
||||||
|
+
|
||||||
|
+export const Audio = forwardRef((props, ref) => {
|
||||||
|
+ const [playing, setPlaying] = useState(false);
|
||||||
|
+ const { value, set } = useSpeed();
|
||||||
|
+
|
||||||
|
+ useEffect(() => {
|
||||||
|
+ ref.current.playbackRate = value
|
||||||
|
+ }, [value])
|
||||||
|
+
|
||||||
|
+ return (
|
||||||
|
+ <div
|
||||||
|
+ style={{
|
||||||
|
+ display: playing ? 'block' : 'none',
|
||||||
|
+ width: '100%',
|
||||||
|
+ }}
|
||||||
|
+ >
|
||||||
|
+ <audio
|
||||||
|
+ onPlay={() => {setPlaying(true)}}
|
||||||
|
+ onEnded={() => {setPlaying(false)}}
|
||||||
|
+ controls
|
||||||
|
+ ref={ref}
|
||||||
|
+ >
|
||||||
|
+ {props.children}
|
||||||
|
+ </audio>
|
||||||
|
+ <input type="range" min="0.25" max="2" step="0.25" onChange={e => { set(e.target.value) }} />
|
||||||
|
+ </div>
|
||||||
|
+ );
|
||||||
|
+});
|
||||||
|
diff -Naur orig.orig/components/Lesson/LessonExercise/LessonExerciseHiddenAudio/LessonExerciseHiddenAudio.jsx orig/components/Lesson/LessonExercise/LessonExerciseHiddenAudio/LessonExerciseHiddenAudio.jsx
|
||||||
|
--- orig.orig/components/Lesson/LessonExercise/LessonExerciseHiddenAudio/LessonExerciseHiddenAudio.jsx 2021-10-15 15:36:57.837243899 -0300
|
||||||
|
+++ orig/components/Lesson/LessonExercise/LessonExerciseHiddenAudio/LessonExerciseHiddenAudio.jsx 2021-10-15 15:47:52.469350865 -0300
|
||||||
|
@@ -1,9 +1,10 @@
|
||||||
|
/* eslint-disable jsx-a11y/media-has-caption */
|
||||||
|
import { forwardRef } from 'react';
|
||||||
|
+import { Audio } from '../../../commons/Audio';
|
||||||
|
|
||||||
|
export const LessonExerciseHiddenAudio = forwardRef(({ src }, ref) => (
|
||||||
|
<div className="exercise-audio-feedback">
|
||||||
|
- <audio
|
||||||
|
+ <Audio
|
||||||
|
className="exercise-audio-file feedback-audio initialized"
|
||||||
|
tabIndex="-1"
|
||||||
|
width="100%"
|
||||||
|
@@ -11,6 +12,6 @@
|
||||||
|
ref={ref}
|
||||||
|
>
|
||||||
|
<source src={src} type="audio/MP3" />
|
||||||
|
- </audio>
|
||||||
|
+ </Audio>
|
||||||
|
</div>
|
||||||
|
));
|
||||||
|
diff -Naur orig.orig/components/Lesson/LessonExercise/LessonExerciseQuestion/QuestionTypes/LessonExerciseQuestionAudio.jsx orig/components/Lesson/LessonExercise/LessonExerciseQuestion/QuestionTypes/LessonExerciseQuestionAudio.jsx
|
||||||
|
--- orig.orig/components/Lesson/LessonExercise/LessonExerciseQuestion/QuestionTypes/LessonExerciseQuestionAudio.jsx 2021-10-15 15:36:57.837243899 -0300
|
||||||
|
+++ orig/components/Lesson/LessonExercise/LessonExerciseQuestion/QuestionTypes/LessonExerciseQuestionAudio.jsx 2021-10-15 15:45:48.129327782 -0300
|
||||||
|
@@ -2,6 +2,7 @@
|
||||||
|
import { useEffect, useRef, useState } from 'react';
|
||||||
|
import { createGlobalStyle } from 'styled-components';
|
||||||
|
import { useAudio } from '../../../../../hooks/useAudio';
|
||||||
|
+import { Audio } from '../../../../commons/Audio';
|
||||||
|
import { useTranslation } from '../../../../../hooks/useTranslation';
|
||||||
|
import { useFrontendConfig } from '../../../../../hooks/useFrontendConfig';
|
||||||
|
|
||||||
|
@@ -62,7 +63,7 @@
|
||||||
|
>
|
||||||
|
<LessonExerciseQuestionAudioGlobalStyles />
|
||||||
|
{/* eslint-disable-next-line jsx-a11y/media-has-caption */}
|
||||||
|
- <audio
|
||||||
|
+ <Audio
|
||||||
|
className={`exercise-audio-file initialized${isPlaying ? ' playing-now' : ''}`}
|
||||||
|
tabIndex="0"
|
||||||
|
width="100%"
|
||||||
|
@@ -73,7 +74,7 @@
|
||||||
|
ref={audioRef}
|
||||||
|
>
|
||||||
|
<source src={audioUrl} type="audio/MP3" />
|
||||||
|
- </audio>
|
||||||
|
+ </Audio>
|
||||||
|
<div className="bubble-text-audio">{audioLabel}</div>
|
||||||
|
<div className="exercise-play-audio" />
|
||||||
|
</a>
|
Loading…
Reference in a new issue