Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Commit

Permalink
Merge pull request #163 from WordPress/error_handling
Browse files Browse the repository at this point in the history
  • Loading branch information
dhruvkb authored Aug 27, 2021
2 parents 79db5ec + c705d2a commit 0ae2ac9
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 21 deletions.
29 changes: 26 additions & 3 deletions src/components/AudioTrack/AudioTrack.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@
@toggle="setPlayerState"
/>
<div
class="flex-grow"
@keypress.enter="setPlayerState(!isPlaying)"
@keypress.space="setPlayerState(!isPlaying)"
>
<Waveform
:class="isCompact ? 'h-20' : 'h-30'"
:is-ready="isReady"
:message="message ? $t(`audio-track.messages.${message}`) : null"
:current-time="currentTime"
:duration="duration"
:peaks="audio.peaks"
Expand Down Expand Up @@ -83,6 +84,7 @@
"
@play="setIsPlaying(true)"
@pause="setIsPlaying(false)"
@error="handleError"
/>
<!-- eslint-enable vuejs-accessibility/media-has-caption -->
</div>
Expand Down Expand Up @@ -120,7 +122,7 @@ export default {
player: null, // HTMLAudioElement
currentTime: 0,
duration: 0,
isReady: false,
message: 'loading',
isPlaying: false,
}),
computed: {
Expand All @@ -135,6 +137,10 @@ export default {
date.setSeconds(seconds)
return date.toISOString().substr(11, 8).replace(/^00:/, '')
},
isReady() {
return this.message === null
},
},
mounted() {
this.player = this.$refs.audio
Expand Down Expand Up @@ -172,11 +178,28 @@ export default {
// HTMLAudioElement events
setIsReady() {
this.isReady = true
this.message = null
},
setIsPlaying(isPlaying) {
this.isPlaying = isPlaying
},
handleError(event) {
const error = event.target.error
switch (error.code) {
case error.MEDIA_ERR_ABORTED:
this.message = 'err_aborted'
break
case error.MEDIA_ERR_NETWORK:
this.message = 'err_network'
break
case error.MEDIA_ERR_DECODE:
this.message = 'err_decode'
break
case error.MEDIA_ERR_SRC_NOT_SUPPORTED:
this.message = 'err_unsupported'
break
}
},
},
}
</script>
24 changes: 15 additions & 9 deletions src/components/AudioTrack/Waveform.vue
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,12 @@
</div>
</template>

<!-- Loading overlay -->
<!-- Message overlay -->
<div
v-else
class="absolute inset-x-0 inset-y-0 flex items-center justify-center loading font-bold text-sm"
>
{{ $t('waveform.loading') }}
{{ message }}
</div>
</div>
</template>
Expand Down Expand Up @@ -116,11 +116,11 @@ export default {
validator: (val) => val.every((item) => item >= 0 && item <= 1),
},
/**
* whether the audio metadata has been loaded and is ready to display
* the message to display instead of the waveform; This is useful when
* displaying a loading or error state.
*/
isReady: {
type: Boolean,
default: false,
message: {
type: String,
},
/**
* the current play time of the audio track
Expand Down Expand Up @@ -193,6 +193,10 @@ export default {
observer.disconnect()
})
/* State */
const isReady = computed(() => !props.message)
/* Resampling */
const barWidth = 2
Expand Down Expand Up @@ -229,7 +233,7 @@ export default {
/* Progress bar */
const currentFrac = computed(() =>
props.isReady ? props.currentTime / props.duration : 0
isReady.value ? props.currentTime / props.duration : 0
)
const progressBarWidth = computed(() => {
const frac = isDragging.value ? seekFrac.value : currentFrac.value
Expand Down Expand Up @@ -276,10 +280,10 @@ export default {
* the seek jump length as a % of the track
*/
const seekDeltaFrac = computed(() => {
return props.isReady ? seekDelta / props.duration : 0
return isReady.value ? seekDelta / props.duration : 0
})
const modSeekDeltaFrac = computed(() =>
props.isReady ? modSeekDelta / props.duration : 0
isReady.value ? modSeekDelta / props.duration : 0
)
const setSeekProgress = (event) => {
seekFrac.value = getPositionFrac(event)
Expand Down Expand Up @@ -335,6 +339,8 @@ export default {
el, // template ref
isReady,
barWidth,
normalizedPeaks,
Expand Down
12 changes: 5 additions & 7 deletions src/components/AudioTrack/meta/Waveform.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ Here 9 points are upsampled to as many as required to fill the viewport.
name="Upsampling"
args={{
peaks: [0.5, 1, 0.5, 0, 0.5, 1, 0.5, 0, 0.5], // triangular wave with 9 points
isReady: true,
currentTime: 2,
duration: 10,
showDuration: true,
Expand All @@ -67,7 +66,6 @@ Here 1000 points are downsampled to as many as required to fill the viewport.
{ length: 1000 },
(_, k) => 0.5 * Math.sin((k * 2 * Math.PI) / 500) + 0.5
), // sine wave with 1000 points
isReady: true,
currentTime: 2,
duration: 10,
showDuration: true,
Expand All @@ -87,16 +85,16 @@ The waveform always takes the height and width of its container.
Thus the `barWidth` and `barGap` will be maintained even in the case of
horizontal scaling.

## Loading state
## Message state

The waveform bars are set to zero height when loading. They will animate up to
their actual height when the `isReady` prop is set to `true`.
The waveform bars are set to zero height when the `message` prop is passed. They
will animate up to their actual height when the prop is unset.

<Canvas>
<Story
name="Loading"
name="Message"
args={{
isReady: false,
message: 'Hello, World!',
}}
>
{Template.bind({})}
Expand Down
10 changes: 8 additions & 2 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -571,12 +571,18 @@
},
"waveform": {
"label": "Audio seek bar",
"loading": "Loading...",
"current-time": "{time} seconds"
},
"audio-track": {
"title": "{title} by {creator}",
"aria-label": "Audio Player"
"aria-label": "Audio Player",
"messages": {
"err_aborted": "You aborted playback.",
"err_network": "A network error occurred.",
"err_decode": "Could not decode audio.",
"err_unsupported": "This audio format is not supported by your browser.",
"loading": "Loading..."
}
},
"play-pause": {
"play": "Play",
Expand Down

0 comments on commit 0ae2ac9

Please sign in to comment.