Skip to content

Commit

Permalink
feat(FEC-8623): playlist UI (#285)
Browse files Browse the repository at this point in the history
* next/prev hovering poster
* mobile controls (play/pause and playlist controls)
* countdown
  • Loading branch information
yairans committed Nov 5, 2018
1 parent 74eed0e commit 8124b59
Show file tree
Hide file tree
Showing 19 changed files with 541 additions and 39 deletions.
5 changes: 5 additions & 0 deletions src/components/engine-connector/engine-connector.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class EngineConnector extends BaseComponent {
this.props.updateAdIsPlaying(false);
this.props.updateIsPlaying(false);
this.props.updateIsEnded(false);
this.props.updateLastSeekPoint(0);
if (this.props.engine.isCasting) {
this.props.updateLoadingSpinnerState(true);
}
Expand Down Expand Up @@ -114,6 +115,10 @@ class EngineConnector extends BaseComponent {
this.props.updateIsPaused(true);
});

this.eventManager.listen(this.player, this.player.Event.SEEKED, () => {
this.props.updateLastSeekPoint(this.player.currentTime);
});

this.eventManager.listen(this.player, this.player.Event.ENDED, () => {
this.props.updateIsEnded(true);
this.props.updateIsPlaying(false);
Expand Down
10 changes: 6 additions & 4 deletions src/components/overlay-action/_overlay-action.scss
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,6 @@
width: 100%;
height: 100%;

&.in .icon {
animation: overlayActionIconIn 300ms linear forwards;
}

.icon {
width: 144px;
height: 144px;
Expand All @@ -86,3 +82,9 @@
opacity: 0;
}
}

.player:not(.touch, .size-sm) {
.overlay-action.in .icon {
animation: overlayActionIconIn 300ms linear forwards;
}
}
12 changes: 0 additions & 12 deletions src/components/play-pause/_play-pause.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,3 @@
}
}
}

.touch {
.control-button-container.control-play-pause {
display: none;
}
}

.player.size-sm {
.control-button-container.control-play-pause {
display: none;
}
}
46 changes: 46 additions & 0 deletions src/components/playback-controls/_playback-controls.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
.player-gui > .playback-controls {
display: none;

position: absolute;
top: 50%;
left: 50%;
margin-top: -32px;
margin-left: -48px;
}

.player.playlist {
.player-gui > .playback-controls {
margin-left: -144px;
}
}

.bottom-bar .playback-controls {
display: inline;
}

.player.size-sm, .player.touch {

.bottom-bar .playback-controls {
display: none;
}

&.hover {
.player-gui > .playback-controls {
display: block;

.control-button {
width: auto;
height: auto;
padding: 0 16px;
}
.icon {
width: 64px;
height: 64px;
}

.poster-preview {
opacity: 0;
}
}
}
}
1 change: 1 addition & 0 deletions src/components/playback-controls/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {PlaybackControls} from './playback-controls';
44 changes: 44 additions & 0 deletions src/components/playback-controls/playback-controls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//@flow
import style from '../../styles/style.scss';
import {h, Component} from 'preact';
import {connect} from 'preact-redux';
import {PlaylistButton} from '../playlist-button';
import {PlayPauseControl} from '../play-pause';

/**
* mapping state to props
* @param {*} state - redux store state
* @returns {Object} - mapped state to this component
*/
const mapStateToProps = state => ({
playlist: state.engine.playlist
});

@connect(mapStateToProps)
/**
* PlaybackControls component
*
* @class PlaybackControls
* @example <PlaybackControls>...</PlaybackControls>
* @extends {Component}
*/
class PlaybackControls extends Component {
/**
* render component
*
* @param {*} props - component props
* @returns {React$Element} - component element
* @memberof PlaybackControls
*/
render(props: any): React$Element<any> {
return (
<div className={[style.playbackControls]}>
{props.playlist ? <PlaylistButton player={props.player} type="prev" /> : undefined}
<PlayPauseControl player={props.player} />
{props.playlist ? <PlaylistButton player={props.player} type="next" /> : undefined}
</div>
);
}
}

export {PlaybackControls};
64 changes: 57 additions & 7 deletions src/components/playlist-button/_playlist-button.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,61 @@
.control-button-container.control-playlist-button {

.poster-preview {
position: absolute;
bottom: 35px;
width: 160px;
height: 90px;
border: 2px solid rgba(255, 255, 255, 0.2);
border-radius: 4px;
opacity: 0;
transition: 400ms opacity;
pointer-events: none;

&:hover {
opacity: 0 !important;
}

.poster-preview-text {
position: absolute;
padding: 8px;
width: 100%;

.poster-preview-text-title {
font-size: 14px;
font-weight: 400;
margin-bottom: 3px;
opacity: 0.7;
}

.poster-preview-text-name {
font-size: 15px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-weight: 400;
}
}

.poster-preview-img {
height: 100%;
background-size: contain;
background-repeat: round;

&:after {
display: block;
background-image: linear-gradient(rgba(black, 0.8), transparent);
height: 60%;
content: '';
}
}
}

&:hover {
.poster-preview {
opacity: 1;
}
}

.control-button {

.icon-prev {
Expand All @@ -16,6 +72,7 @@
}

&:disabled {
opacity: 1;

.icon-prev {
display: none;
Expand All @@ -32,10 +89,3 @@
}
}
}

.touch {
.control-button-container.control-playlist-button {
display: none;
}
}

15 changes: 15 additions & 0 deletions src/components/playlist-button/playlist-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,21 @@ class PlaylistButton extends BaseComponent {
render(props: any): React$Element<any> | void {
return (
<div className={[style.controlButtonContainer, style.controlPlaylistButton].join(' ')}>
{props.playlist[props.type] ? (
<div className={style.posterPreview}>
<div className={style.posterPreviewText}>
<Localizer>
<div className={style.posterPreviewTextTitle}>
<Text id={props.type === 'prev' ? 'playlist.prev' : 'playlist.next'} />
</div>
</Localizer>
<div className={style.posterPreviewTextName}>{`${props.playlist[props.type].sources.metadata.name}`}</div>
</div>
<div className={style.posterPreviewImg} style={`background-image: url(${props.playlist[props.type].sources.poster});`} />
</div>
) : (
undefined
)}
<Localizer>
<button
disabled={!props.playlist[props.type]}
Expand Down

0 comments on commit 8124b59

Please sign in to comment.