Repository: streamich/react-use
Pull request #2075 (2021-08-27 10:31:33)

feat: useAudio add playing state
# Description

<!-- Please include a summary of the change along with relevant motivation and context. -->
At present, useAudio cannot get whether it is playing in a weak network environment

## Type of change

<!-- Check all relevant options. -->
- [ ] Bug fix _(non-breaking change which fixes an issue)_
- [ ] New feature _(non-breaking change which adds functionality)_
- [ ] **Breaking change** _(fix or feature that would cause existing functionality to not work as before)_

# Checklist
- [x] Read the [Contributing Guide](https://github.com/streamich/react-use/blob/master/CONTRIBUTING.md)
- [x] Perform a code self-review
- [ ] Comment the code, particularly in hard-to-understand areas
- [x] Add documentation
- [ ] Add hook's story at Storybook
- [ ] Cover changes with tests
  Difficult to test in a weak network environment
- [x] Ensure the test suite passes (`yarn test`)
- [ ] Provide 100% tests coverage
- [x] Make sure code lints (`yarn lint`). Fix it with `yarn lint:fix` in case of failure.
- [x] Make sure types are fine (`yarn lint:types`).

<!-- If you can't check all the checkboxes right now - check what you can, create a Draft PR, make some changes if needed and get back to it when you will be able to put some marks in list. -->



Patch:
diff --git a/docs/useAudio.md b/docs/useAudio.md
index 84184037..89390604 100644
--- a/docs/useAudio.md
+++ b/docs/useAudio.md
@@ -64,10 +64,13 @@ render tree, for example:
   "duration": 425.952625,
   "paused": false,
   "muted": false,
-  "volume": 1
+  "volume": 1,
+  "playing": true
 }
 ```
 
+`playing`: The audio is being played and is affected by the network. If it starts to buffer audio, it will be false
+
 `controls` is a list collection of methods that allow you to control the
 playback of the audio, it has the following interface:
 
@@ -85,4 +88,4 @@ interface AudioControls {
 `ref` is a React reference to HTML `<audio>` element, you can access the element by
 `ref.current`, note that it may be `null`.
 
-And finally, `props` &mdash; all props that `<audio>` accepts.
\ No newline at end of file
+And finally, `props` &mdash; all props that `<audio>` accepts.
diff --git a/src/factory/createHTMLMediaHook.ts b/src/factory/createHTMLMediaHook.ts
index 2bdae110..954a5bb8 100644
--- a/src/factory/createHTMLMediaHook.ts
+++ b/src/factory/createHTMLMediaHook.ts
@@ -16,6 +16,7 @@ export interface HTMLMediaState {
   muted: boolean;
   time: number;
   volume: number;
+  playing: boolean;
 }
 
 export interface HTMLMediaControls {
@@ -50,6 +51,7 @@ export default function createHTMLMediaHook<T extends HTMLAudioElement | HTMLVid
       paused: true,
       muted: false,
       volume: 1,
+      playing: false
     });
     const ref = useRef<T | null>(null);
 
@@ -64,7 +66,9 @@ export default function createHTMLMediaHook<T extends HTMLAudioElement | HTMLVid
     };
 
     const onPlay = () => setState({ paused: false });
-    const onPause = () => setState({ paused: true });
+    const onPlaying = () => setState({ playing: true });
+    const onWaiting = () => setState({ playing: false });
+    const onPause = () => setState({ paused: true, playing: false });
     const onVolumeChange = () => {
       const el = ref.current;
       if (!el) {
@@ -107,6 +111,8 @@ export default function createHTMLMediaHook<T extends HTMLAudioElement | HTMLVid
         ...props,
         ref,
         onPlay: wrapEvent(props.onPlay, onPlay),
+        onPlaying: wrapEvent(props.onPlaying, onPlaying),
+        onWaiting: wrapEvent(props.onWaiting, onWaiting),
         onPause: wrapEvent(props.onPause, onPause),
         onVolumeChange: wrapEvent(props.onVolumeChange, onVolumeChange),
         onDurationChange: wrapEvent(props.onDurationChange, onDurationChange),
@@ -119,6 +125,8 @@ export default function createHTMLMediaHook<T extends HTMLAudioElement | HTMLVid
         ...props,
         ref,
         onPlay: wrapEvent(props.onPlay, onPlay),
+        onPlaying: wrapEvent(props.onPlaying, onPlaying),
+        onWaiting: wrapEvent(props.onWaiting, onWaiting),
         onPause: wrapEvent(props.onPause, onPause),
         onVolumeChange: wrapEvent(props.onVolumeChange, onVolumeChange),
         onDurationChange: wrapEvent(props.onDurationChange, onDurationChange),


Test patch:
diff --git a/tests/useAudio.test.ts b/tests/useAudio.test.ts
index 691078d8..fac5df47 100644
--- a/tests/useAudio.test.ts
+++ b/tests/useAudio.test.ts
@@ -23,6 +23,7 @@ it('should init audio and utils', () => {
   // Test state value
   expect(state.time).toBe(0);
   expect(state.paused).toBe(true);
+  expect(state.playing).toBe(false);
   expect(state.muted).toBe(false);
   expect(state.volume).toBe(1);