PlaybackRateSelector.js (2707B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 const { 8 PureComponent, 9 } = require("resource://devtools/client/shared/vendor/react.mjs"); 10 const dom = require("resource://devtools/client/shared/vendor/react-dom-factories.js"); 11 const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.mjs"); 12 const { 13 connect, 14 } = require("resource://devtools/client/shared/vendor/react-redux.js"); 15 16 const { 17 getFormatStr, 18 } = require("resource://devtools/client/inspector/animation/utils/l10n.js"); 19 20 const PLAYBACK_RATES = [0.01, 0.1, 0.25, 0.5, 1, 2, 5, 10]; 21 22 class PlaybackRateSelector extends PureComponent { 23 static get propTypes() { 24 return { 25 animations: PropTypes.arrayOf(PropTypes.object).isRequired, 26 playbackRates: PropTypes.arrayOf(PropTypes.number).isRequired, 27 setAnimationsPlaybackRate: PropTypes.func.isRequired, 28 }; 29 } 30 31 static getDerivedStateFromProps(props) { 32 const { animations, playbackRates } = props; 33 34 const currentPlaybackRates = sortAndUnique( 35 animations.map(a => a.state.playbackRate) 36 ); 37 const options = sortAndUnique([ 38 ...PLAYBACK_RATES, 39 ...playbackRates, 40 ...currentPlaybackRates, 41 ]); 42 43 if (currentPlaybackRates.length === 1) { 44 return { 45 options, 46 selected: currentPlaybackRates[0], 47 }; 48 } 49 50 // When the animations displayed have mixed playback rates, we can't 51 // select any of the predefined ones. 52 return { 53 options: ["", ...options], 54 selected: "", 55 }; 56 } 57 58 constructor(props) { 59 super(props); 60 61 this.state = { 62 options: [], 63 selected: 1, 64 }; 65 } 66 67 onChange(e) { 68 const { setAnimationsPlaybackRate } = this.props; 69 70 if (!e.target.value) { 71 return; 72 } 73 74 setAnimationsPlaybackRate(e.target.value); 75 } 76 77 render() { 78 const { options, selected } = this.state; 79 80 return dom.select( 81 { 82 className: "playback-rate-selector devtools-button", 83 onChange: this.onChange.bind(this), 84 }, 85 options.map(rate => { 86 return dom.option( 87 { 88 selected: rate === selected ? "true" : null, 89 value: rate, 90 }, 91 rate ? getFormatStr("player.playbackRateLabel", rate) : "-" 92 ); 93 }) 94 ); 95 } 96 } 97 98 function sortAndUnique(array) { 99 return [...new Set(array)].sort((a, b) => a > b); 100 } 101 102 const mapStateToProps = state => { 103 return { 104 playbackRates: state.animations.playbackRates, 105 }; 106 }; 107 108 module.exports = connect(mapStateToProps)(PlaybackRateSelector);