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 ( +
+ + { set(e.target.value) }} /> +
+ ); +}); 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) => (
- +
)); 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 @@ > {/* eslint-disable-next-line jsx-a11y/media-has-caption */} - +
{audioLabel}