Bug 1479451 - Part 1: Hold custom playback rates till 'new-root' event was called. r=gl

Differential Revision: https://phabricator.services.mozilla.com/D3306
This commit is contained in:
Daisuke Akatsuka 2018-08-14 17:59:26 +09:00
parent 88a85cf5c7
commit f85fbef4a6
5 changed files with 68 additions and 37 deletions

View File

@ -9,6 +9,7 @@ const {
UPDATE_DETAIL_VISIBILITY,
UPDATE_ELEMENT_PICKER_ENABLED,
UPDATE_HIGHLIGHTED_NODE,
UPDATE_PLAYBACK_RATES,
UPDATE_SELECTED_ANIMATION,
UPDATE_SIDEBAR_SIZE
} = require("./index");
@ -54,6 +55,15 @@ module.exports = {
};
},
/**
* Update the playback rates.
*/
updatePlaybackRates() {
return {
type: UPDATE_PLAYBACK_RATES,
};
},
/**
* Update selected animation.
*/

View File

@ -20,6 +20,9 @@ createEnum([
// Update highlighted node.
"UPDATE_HIGHLIGHTED_NODE",
// Update playback rate.
"UPDATE_PLAYBACK_RATES",
// Update selected animation.
"UPDATE_SELECTED_ANIMATION",

View File

@ -18,6 +18,7 @@ const {
updateDetailVisibility,
updateElementPickerEnabled,
updateHighlightedNode,
updatePlaybackRates,
updateSelectedAnimation,
updateSidebarSize
} = require("./actions/animations");
@ -58,6 +59,7 @@ class AnimationInspector {
this.onCurrentTimeTimerUpdated = this.onCurrentTimeTimerUpdated.bind(this);
this.onElementPickerStarted = this.onElementPickerStarted.bind(this);
this.onElementPickerStopped = this.onElementPickerStopped.bind(this);
this.onNavigate = this.onNavigate.bind(this);
this.onSidebarResized = this.onSidebarResized.bind(this);
this.onSidebarSelectionChanged = this.onSidebarSelectionChanged.bind(this);
@ -149,6 +151,7 @@ class AnimationInspector {
destroy() {
this.setAnimationStateChangedListenerEnabled(false);
this.inspector.off("new-root", this.onNavigate);
this.inspector.selection.off("new-node-front", this.update);
this.inspector.sidebar.off("select", this.onSidebarSelectionChanged);
this.inspector.toolbox.off("inspector-sidebar-resized", this.onSidebarResized);
@ -341,6 +344,10 @@ class AnimationInspector {
this.inspector.store.dispatch(updateElementPickerEnabled(false));
}
onNavigate() {
this.inspector.store.dispatch(updatePlaybackRates());
}
async onSidebarSelectionChanged() {
const isPanelVisibled = this.isPanelVisible();
@ -356,11 +363,13 @@ class AnimationInspector {
await this.update();
this.onSidebarResized(null, this.inspector.getSidebarSize());
this.animationsFront.on("mutations", this.onAnimationsMutation);
this.inspector.on("new-root", this.onNavigate);
this.inspector.selection.on("new-node-front", this.update);
this.inspector.toolbox.on("inspector-sidebar-resized", this.onSidebarResized);
} else {
this.stopAnimationsCurrentTimeTimer();
this.animationsFront.off("mutations", this.onAnimationsMutation);
this.inspector.off("new-root", this.onNavigate);
this.inspector.selection.off("new-node-front", this.update);
this.inspector.toolbox.off("inspector-sidebar-resized", this.onSidebarResized);
this.setAnimationStateChangedListenerEnabled(false);

View File

@ -7,6 +7,7 @@
const { PureComponent } = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const { getFormatStr } = require("../utils/l10n");
@ -16,10 +17,33 @@ class PlaybackRateSelector extends PureComponent {
static get propTypes() {
return {
animations: PropTypes.arrayOf(PropTypes.object).isRequired,
playbackRates: PropTypes.arrayOf(PropTypes.number).isRequired,
setAnimationsPlaybackRate: PropTypes.func.isRequired,
};
}
static getDerivedStateFromProps(props, state) {
const { animations, playbackRates } = props;
const currentPlaybackRates = sortAndUnique(animations.map(a => a.state.playbackRate));
const options =
sortAndUnique([...PLAYBACK_RATES, ...playbackRates, ...currentPlaybackRates]);
if (currentPlaybackRates.length === 1) {
return {
options,
selected: currentPlaybackRates[0],
};
}
// When the animations displayed have mixed playback rates, we can't
// select any of the predefined ones.
return {
options: ["", ...options],
selected: "",
};
}
constructor(props) {
super(props);
@ -29,22 +53,6 @@ class PlaybackRateSelector extends PureComponent {
};
}
componentWillMount() {
this.updateState(this.props);
}
componentWillReceiveProps(nextProps) {
this.updateState(nextProps);
}
getPlaybackRates(animations) {
return sortAndUnique(animations.map(a => a.state.playbackRate));
}
getSelectablePlaybackRates(animationsRates) {
return sortAndUnique(PLAYBACK_RATES.concat(animationsRates));
}
onChange(e) {
const { setAnimationsPlaybackRate } = this.props;
@ -55,26 +63,6 @@ class PlaybackRateSelector extends PureComponent {
setAnimationsPlaybackRate(e.target.value);
}
updateState(props) {
const { animations } = props;
let options;
let selected;
const rates = this.getPlaybackRates(animations);
if (rates.length === 1) {
options = this.getSelectablePlaybackRates(rates);
selected = rates[0];
} else {
// When the animations displayed have mixed playback rates, we can't
// select any of the predefined ones.
options = ["", ...PLAYBACK_RATES];
selected = "";
}
this.setState({ options, selected });
}
render() {
const { options, selected } = this.state;
@ -100,4 +88,10 @@ function sortAndUnique(array) {
return [...new Set(array)].sort((a, b) => a > b);
}
module.exports = PlaybackRateSelector;
const mapStateToProps = state => {
return {
playbackRates: state.animations.playbackRates,
};
};
module.exports = connect(mapStateToProps)(PlaybackRateSelector);

View File

@ -9,6 +9,7 @@ const {
UPDATE_DETAIL_VISIBILITY,
UPDATE_ELEMENT_PICKER_ENABLED,
UPDATE_HIGHLIGHTED_NODE,
UPDATE_PLAYBACK_RATES,
UPDATE_SELECTED_ANIMATION,
UPDATE_SIDEBAR_SIZE,
} = require("../actions/index");
@ -20,6 +21,7 @@ const INITIAL_STATE = {
detailVisibility: false,
elementPickerEnabled: false,
highlightedNode: null,
playbackRates: [],
selectedAnimation: null,
sidebarSize: {
height: 0,
@ -39,9 +41,12 @@ const reducers = {
detailVisibility = !!selectedAnimation;
}
const playbackRates = getPlaybackRates(state.playbackRates, animations);
return Object.assign({}, state, {
animations,
detailVisibility,
playbackRates,
selectedAnimation,
timeScale: new TimeScale(animations),
});
@ -69,6 +74,12 @@ const reducers = {
});
},
[UPDATE_PLAYBACK_RATES](state) {
return Object.assign({}, state, {
playbackRates: getPlaybackRates([], state.animations),
});
},
[UPDATE_SELECTED_ANIMATION](state, { selectedAnimation }) {
const detailVisibility = !!selectedAnimation;
@ -85,6 +96,10 @@ const reducers = {
},
};
function getPlaybackRates(basePlaybackRate, animations) {
return [...new Set(animations.map(a => a.state.playbackRate).concat(basePlaybackRate))];
}
module.exports = function(state = INITIAL_STATE, action) {
const reducer = reducers[action.type];
return reducer ? reducer(state, action) : state;