2018-12-22 03:10:49 +03:00
|
|
|
import React, { Component } from 'react';
|
|
|
|
import { PropTypes } from 'prop-types';
|
|
|
|
import shouldPureComponentUpdate from 'react-pure-render/function';
|
|
|
|
import dateformat from 'dateformat';
|
|
|
|
import debounce from 'lodash.debounce';
|
|
|
|
import RightSlider from './RightSlider';
|
|
|
|
|
|
|
|
const BUTTON_SKIP = 'Skip';
|
|
|
|
const BUTTON_JUMP = 'Jump';
|
|
|
|
|
|
|
|
export default class ActionListRow extends Component {
|
|
|
|
state = { hover: false };
|
|
|
|
|
|
|
|
static propTypes = {
|
|
|
|
styling: PropTypes.func.isRequired,
|
|
|
|
isSelected: PropTypes.bool.isRequired,
|
|
|
|
action: PropTypes.object.isRequired,
|
|
|
|
isInFuture: PropTypes.bool.isRequired,
|
|
|
|
isInitAction: PropTypes.bool.isRequired,
|
|
|
|
onSelect: PropTypes.func.isRequired,
|
|
|
|
timestamps: PropTypes.shape({
|
|
|
|
current: PropTypes.number.isRequired,
|
2020-08-08 23:26:39 +03:00
|
|
|
previous: PropTypes.number.isRequired,
|
2018-12-22 03:10:49 +03:00
|
|
|
}).isRequired,
|
2020-08-08 23:26:39 +03:00
|
|
|
isSkipped: PropTypes.bool.isRequired,
|
2018-12-22 03:10:49 +03:00
|
|
|
};
|
|
|
|
|
2019-01-10 21:51:14 +03:00
|
|
|
shouldComponentUpdate = shouldPureComponentUpdate;
|
2018-12-22 03:10:49 +03:00
|
|
|
|
|
|
|
render() {
|
2019-01-10 21:51:14 +03:00
|
|
|
const {
|
|
|
|
styling,
|
|
|
|
isSelected,
|
|
|
|
action,
|
|
|
|
actionId,
|
|
|
|
isInitAction,
|
|
|
|
onSelect,
|
|
|
|
timestamps,
|
|
|
|
isSkipped,
|
|
|
|
isInFuture,
|
2020-08-08 23:26:39 +03:00
|
|
|
hideActionButtons,
|
2019-01-10 21:51:14 +03:00
|
|
|
} = this.props;
|
2018-12-22 03:10:49 +03:00
|
|
|
const { hover } = this.state;
|
|
|
|
const timeDelta = timestamps.current - timestamps.previous;
|
2019-01-10 21:51:14 +03:00
|
|
|
const showButtons = (hover && !isInitAction) || isSkipped;
|
2018-12-22 03:10:49 +03:00
|
|
|
|
2020-08-08 23:26:39 +03:00
|
|
|
const isButtonSelected = (btn) => btn === BUTTON_SKIP && isSkipped;
|
2018-12-22 03:10:49 +03:00
|
|
|
|
|
|
|
let actionType = action.type;
|
|
|
|
if (typeof actionType === 'undefined') actionType = '<UNDEFINED>';
|
|
|
|
else if (actionType === null) actionType = '<NULL>';
|
|
|
|
else actionType = actionType.toString() || '<EMPTY>';
|
|
|
|
|
|
|
|
return (
|
2019-01-10 21:51:14 +03:00
|
|
|
<div
|
|
|
|
onClick={onSelect}
|
2018-12-22 03:10:49 +03:00
|
|
|
onMouseEnter={!hideActionButtons && this.handleMouseEnter}
|
|
|
|
onMouseLeave={!hideActionButtons && this.handleMouseLeave}
|
|
|
|
onMouseDown={this.handleMouseDown}
|
|
|
|
onMouseUp={this.handleMouseEnter}
|
|
|
|
data-id={actionId}
|
2019-01-10 21:51:14 +03:00
|
|
|
{...styling(
|
|
|
|
[
|
|
|
|
'actionListItem',
|
|
|
|
isSelected && 'actionListItemSelected',
|
|
|
|
isSkipped && 'actionListItemSkipped',
|
2020-08-08 23:26:39 +03:00
|
|
|
isInFuture && 'actionListFromFuture',
|
2019-01-10 21:51:14 +03:00
|
|
|
],
|
|
|
|
isSelected,
|
|
|
|
action
|
|
|
|
)}
|
|
|
|
>
|
|
|
|
<div
|
|
|
|
{...styling([
|
|
|
|
'actionListItemName',
|
2020-08-08 23:26:39 +03:00
|
|
|
isSkipped && 'actionListItemNameSkipped',
|
2019-01-10 21:51:14 +03:00
|
|
|
])}
|
|
|
|
>
|
2018-12-22 03:10:49 +03:00
|
|
|
{actionType}
|
|
|
|
</div>
|
2019-01-10 21:51:14 +03:00
|
|
|
{hideActionButtons ? (
|
2018-12-22 03:10:49 +03:00
|
|
|
<RightSlider styling={styling} shown>
|
|
|
|
<div {...styling('actionListItemTime')}>
|
2019-01-10 21:51:14 +03:00
|
|
|
{timeDelta === 0
|
|
|
|
? '+00:00:00'
|
|
|
|
: dateformat(
|
|
|
|
timeDelta,
|
|
|
|
timestamps.previous ? '+MM:ss.L' : 'h:MM:ss.L'
|
|
|
|
)}
|
2018-12-22 03:10:49 +03:00
|
|
|
</div>
|
|
|
|
</RightSlider>
|
2019-01-10 21:51:14 +03:00
|
|
|
) : (
|
2018-12-22 03:10:49 +03:00
|
|
|
<div {...styling('actionListItemButtons')}>
|
|
|
|
<RightSlider styling={styling} shown={!showButtons} rotate>
|
|
|
|
<div {...styling('actionListItemTime')}>
|
2019-01-10 21:51:14 +03:00
|
|
|
{timeDelta === 0
|
|
|
|
? '+00:00:00'
|
|
|
|
: dateformat(
|
|
|
|
timeDelta,
|
|
|
|
timestamps.previous ? '+MM:ss.L' : 'h:MM:ss.L'
|
|
|
|
)}
|
2018-12-22 03:10:49 +03:00
|
|
|
</div>
|
|
|
|
</RightSlider>
|
|
|
|
<RightSlider styling={styling} shown={showButtons} rotate>
|
|
|
|
<div {...styling('actionListItemSelector')}>
|
2019-01-10 21:51:14 +03:00
|
|
|
{[BUTTON_JUMP, BUTTON_SKIP].map(
|
2020-08-08 23:26:39 +03:00
|
|
|
(btn) =>
|
2019-01-10 21:51:14 +03:00
|
|
|
(!isInitAction || btn !== BUTTON_SKIP) && (
|
|
|
|
<div
|
|
|
|
key={btn}
|
|
|
|
onClick={this.handleButtonClick.bind(this, btn)}
|
|
|
|
{...styling(
|
|
|
|
[
|
|
|
|
'selectorButton',
|
|
|
|
isButtonSelected(btn) && 'selectorButtonSelected',
|
2020-08-08 23:26:39 +03:00
|
|
|
'selectorButtonSmall',
|
2019-01-10 21:51:14 +03:00
|
|
|
],
|
|
|
|
isButtonSelected(btn),
|
|
|
|
true
|
|
|
|
)}
|
|
|
|
>
|
|
|
|
{btn}
|
|
|
|
</div>
|
|
|
|
)
|
2018-12-22 03:10:49 +03:00
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</RightSlider>
|
|
|
|
</div>
|
2019-01-10 21:51:14 +03:00
|
|
|
)}
|
2018-12-22 03:10:49 +03:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
handleButtonClick(btn, e) {
|
|
|
|
e.stopPropagation();
|
|
|
|
|
2019-01-10 21:51:14 +03:00
|
|
|
switch (btn) {
|
|
|
|
case BUTTON_SKIP:
|
|
|
|
this.props.onToggleClick();
|
|
|
|
break;
|
|
|
|
case BUTTON_JUMP:
|
|
|
|
this.props.onJumpClick();
|
|
|
|
break;
|
2018-12-22 03:10:49 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-08 23:26:39 +03:00
|
|
|
handleMouseEnter = (e) => {
|
2018-12-22 03:10:49 +03:00
|
|
|
if (this.hover) return;
|
|
|
|
this.handleMouseLeave.cancel();
|
|
|
|
this.handleMouseEnterDebounced(e.buttons);
|
2019-01-10 21:51:14 +03:00
|
|
|
};
|
2018-12-22 03:10:49 +03:00
|
|
|
|
2020-08-08 23:26:39 +03:00
|
|
|
handleMouseEnterDebounced = debounce((buttons) => {
|
2018-12-22 03:10:49 +03:00
|
|
|
if (buttons) return;
|
|
|
|
this.setState({ hover: true });
|
2019-01-10 21:51:14 +03:00
|
|
|
}, 150);
|
2018-12-22 03:10:49 +03:00
|
|
|
|
|
|
|
handleMouseLeave = debounce(() => {
|
|
|
|
this.handleMouseEnterDebounced.cancel();
|
|
|
|
if (this.state.hover) this.setState({ hover: false });
|
2019-01-10 21:51:14 +03:00
|
|
|
}, 100);
|
2018-12-22 03:10:49 +03:00
|
|
|
|
2020-08-08 23:26:39 +03:00
|
|
|
handleMouseDown = (e) => {
|
2018-12-22 03:10:49 +03:00
|
|
|
if (e.target.className.indexOf('selectorButton') === 0) return;
|
|
|
|
this.handleMouseLeave();
|
2019-01-10 21:51:14 +03:00
|
|
|
};
|
2018-12-22 03:10:49 +03:00
|
|
|
}
|