Bug 1511567 - Add UI transitions. r=bhackett

Tags:

Bug #: 1511567

Differential Revision: https://phabricator.services.mozilla.com/D13605
This commit is contained in:
Jason Laster 2018-11-30 19:39:31 -05:00
Родитель 2b70c3a5fb
Коммит 8280608066
4 изменённых файлов: 68 добавлений и 25 удалений

Просмотреть файл

@ -464,6 +464,8 @@
--progress-recording-background: hsl(0, 100%, 97%);
--progress-playing-background: hsl(207, 100%, 97%);
--progress-bar-transition: 200ms;
--recording-marker-background: hsl(14.9, 100%, 67%);
--recording-marker-background-hover: hsl(14.9, 100%, 47%);
--command-button-size: 14px;
@ -488,8 +490,7 @@
width: 100%;
height: 100%;
background: var(--progress-playing-background);
transition-duration: 200ms;
transition-duration: var(--progress-bar-transition);
}
.webreplay-player #overlay:not(.recording) .progress::after {
@ -505,7 +506,7 @@
.webreplay-player .recording .progress {
background: var(--progress-recording-background);
transition-duration: 200ms;
transition-duration: var(--progress-bar-transition);
}
.webreplay-player .message {
@ -531,6 +532,7 @@
.webreplay-player .message.highlighted {
background-color: var(--blue-60);
transform: scale(1.25);
transition-duration: 100ms;
}
.webreplay-player .recording .message.highlighted {
@ -615,9 +617,8 @@
background: var(--blue-40);
position: absolute;
left: 0;
right: 10px;
top: 50%;
transition-duration: 200ms;
transition-duration: var(--progress-bar-transition);
}
.webreplay-player .progress-line.end {

Просмотреть файл

@ -8,6 +8,7 @@ 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/redux/visibility-handler-connect");
const {initialize} = require("devtools/client/webconsole/actions/ui");
const {sortBy} = require("devtools/client/shared/vendor/lodash");
const {
getAllMessagesById,
@ -26,24 +27,18 @@ const {
getInitialMessageCountForViewport,
} = require("devtools/client/webconsole/utils/messages.js");
// Finds the message that comes right after the current paused execution point.
// NOTE: visibleMessages are not guaranteed to be ordered.
function getPausedMessage(visibleMessages, messages, executionPoint) {
function getClosestMessage(visibleMessages, messages, executionPoint) {
if (!executionPoint || !visibleMessages) {
return null;
}
let pausedMessage = messages.get(visibleMessages[0]);
for (const messageId of visibleMessages) {
const message = messages.get(messageId);
if (message.executionPoint &&
executionPoint.progress >= message.executionPoint.progress &&
message.executionPoint.progress > pausedMessage.executionPoint.progress) {
pausedMessage = message;
}
}
const { progress } = executionPoint;
const getProgress = m => m && m.executionPoint && m.executionPoint.progress;
return pausedMessage;
return sortBy(
visibleMessages.map(id => messages.get(id)),
m => Math.abs(progress - getProgress(m))
)[0];
}
class ConsoleOutput extends Component {
@ -165,7 +160,7 @@ class ConsoleOutput extends Component {
}
}
const pausedMessage = getPausedMessage(
const pausedMessage = getClosestMessage(
visibleMessages, messages, pausedExecutionPoint);
const messageNodes = visibleMessages.map((messageId) => MessageContainer({

Просмотреть файл

@ -166,6 +166,7 @@ class Message extends Component {
timestampsVisible,
executionPoint,
pausedExecutionPoint,
messageId,
notes,
} = this.props;
@ -298,6 +299,7 @@ class Message extends Component {
ref: node => {
this.messageNode = node;
},
"data-message-id": messageId,
"aria-live": type === MESSAGE_TYPE.COMMAND ? "off" : "polite",
},
timestampEl,

Просмотреть файл

@ -7,6 +7,7 @@ const { Component } = require("devtools/client/shared/vendor/react");
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const {sortBy} = require("devtools/client/shared/vendor/lodash");
const { LocalizationHelper } = require("devtools/shared/l10n");
const L10N = new LocalizationHelper(
@ -60,6 +61,23 @@ function CommandButton({ img, className, onClick }) {
);
}
function getMessageProgress(message) {
return getProgress(message.executionPoint);
}
function getProgress(executionPoint) {
return executionPoint && executionPoint.progress;
}
function getClosestMessage(messages, executionPoint) {
const progress = getProgress(executionPoint);
return sortBy(
messages,
message => Math.abs(progress - getMessageProgress(message))
)[0];
}
/*
*
* The player has 4 valid states
@ -105,20 +123,24 @@ class WebReplayPlayer extends Component {
});
}
componentDidUpdate() {
componentDidUpdate(prevProps, prevState) {
this.overlayWidth = this.updateOverlayWidth();
if (prevState.closestMessage != this.state.closestMessage) {
this.scrollToMessage();
}
}
get toolbox() {
return this.props.toolbox;
}
get threadClient() {
return this.toolbox.threadClient;
get console() {
return this.toolbox.getPanel("webconsole");
}
get activeConsole() {
return this.toolbox.target.activeConsole;
get threadClient() {
return this.toolbox.threadClient;
}
isRecording() {
@ -140,18 +162,21 @@ class WebReplayPlayer extends Component {
onPaused(_, packet) {
if (packet && packet.recordingEndpoint) {
const { executionPoint, recordingEndpoint } = packet;
const closestMessage = getClosestMessage(this.state.messages, executionPoint);
this.setState({
executionPoint,
recordingEndpoint,
paused: true,
seeking: false,
recording: false,
closestMessage,
});
}
}
onResumed(_, packet) {
this.setState({ paused: false });
this.setState({ paused: false, closestMessage: null });
}
onProgress(_, packet) {
@ -198,6 +223,26 @@ class WebReplayPlayer extends Component {
return null;
}
scrollToMessage() {
const {closestMessage} = this.state;
if (!closestMessage) {
return;
}
const consoleOutput = this.console.hud.ui.outputNode;
const element = consoleOutput
.querySelector(`.message[data-message-id="${closestMessage.id}"]`);
if (element) {
const consoleHeight = consoleOutput.getBoundingClientRect().height;
const elementTop = element.getBoundingClientRect().top;
if (elementTop < 30 || elementTop + 50 > consoleHeight) {
element.scrollIntoView({block: "center", behavior: "smooth"});
}
}
}
seek(executionPoint) {
if (!executionPoint) {
return null;