Skip to content

Commit

Permalink
feat(FEC-8038): chromecast sender (#278)
Browse files Browse the repository at this point in the history
Chromecast sender components and adaptions.
  • Loading branch information
Dan Ziv committed Oct 14, 2018
1 parent 674ea09 commit 2e8e162
Show file tree
Hide file tree
Showing 42 changed files with 907 additions and 133 deletions.
6 changes: 6 additions & 0 deletions src/components/ad-learn-more/_ad-learn-more.scss
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
@import '~styles/variables';
@import '~styles/buttons';

.player {
.learn-more {
font-weight: lighter;
}
}
2 changes: 1 addition & 1 deletion src/components/ad-learn-more/ad-learn-more.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class AdLearnMore extends Component {
*/
render(props: any): React$Element<any> {
return (
<a href={props.url} target="_blank" className={[style.btn, style.btnDarkTransparent].join(' ')}>
<a href={props.url} target="_blank" className={[style.btn, style.btnDarkTransparent, style.learnMore].join(' ')}>
<Text id={'ads.learn_more'} />
</a>
);
Expand Down
32 changes: 18 additions & 14 deletions src/components/ad-skip/_ad-skip.scss
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
.btn-skip-ad {
position: absolute;
bottom: 60px;
right: 16px;
}
.player {
.btn-skip-ad {
font-weight: lighter;
position: absolute;
bottom: 60px;
right: 16px;
line-height: 36px;
}

.skip-ad {
color: #fff;
font-size: 20px;
font-weight: bold;
line-height: 24px;
text-shadow: 0 0 6px rgba(0, 0, 0, 0.6);
position: absolute;
bottom: 66px;
right: 16px;
.skip-ad {
color: #fff;
font-size: 20px;
font-weight: lighter;
line-height: 24px;
text-shadow: 0 0 6px rgba(0, 0, 0, 0.6);
position: absolute;
bottom: 66px;
right: 16px;
}
}
39 changes: 14 additions & 25 deletions src/components/ad-skip/ad-skip.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import style from '../../styles/style.scss';
import {h} from 'preact';
import {connect} from 'preact-redux';
import BaseComponent from '../base';
import {Text} from 'preact-i18n';
import {Localizer, Text} from 'preact-i18n';

/**
* mapping state to props
Expand All @@ -26,8 +26,6 @@ const mapStateToProps = state => ({
* @extends {BaseComponent}
*/
class AdSkip extends BaseComponent {
skipSupport: any;

/**
* Creates an instance of AdSkip.
* @param {Object} obj obj
Expand All @@ -37,28 +35,14 @@ class AdSkip extends BaseComponent {
super({name: 'AdSkip', player: obj.player});
}

/**
* componentDidMount
*
* @returns {void}
* @memberof AdSkip
*/
componentDidMount() {
this.skipSupport = this.player.config.plugins.ima.skipSupport;
}

/**
* getting the number value of seconds left to be able to skip ad
*
* @returns {number} - number of seconds left to skip ad
* @memberof AdSkip
*/
getSkipTimeOffset(): number {
if (this.skipSupport) {
return Math.ceil(this.skipSupport.skipTimeOffset - this.props.currentTime);
} else {
return Math.ceil(this.props.adSkipTimeOffset - this.props.currentTime);
}
return Math.ceil(this.props.adSkipTimeOffset - this.props.currentTime);
}

/**
Expand All @@ -68,15 +52,20 @@ class AdSkip extends BaseComponent {
* @memberof AdSkip
*/
render(): React$Element<any> | void {
if (!this.props.adSkippableState && this.skipSupport) {
if (this.props.adSkippableState) {
return this.getSkipTimeOffset() <= 0 ? (
<a className={[style.btn, style.btnBranded, style.btnSkipAd].join(' ')} onClick={() => this.player.ads.skipAd()}>
<Text key={'ads.skip_ad'} />
</a>
<Localizer>
<a className={[style.btn, style.btnBranded, style.btnSkipAd].join(' ')} onClick={() => this.player.ads.skipAd()}>
<Text id="ads.skip_ad" />
</a>
</Localizer>
) : (
<span className={style.skipAd}>
<Text id={'ads.skip_in'} /> {this.getSkipTimeOffset()}
</span>
<Localizer>
<span className={style.skipAd}>
<Text id="ads.skip_in" />
{' ' + this.getSkipTimeOffset()}
</span>
</Localizer>
);
} else {
return undefined;
Expand Down
12 changes: 12 additions & 0 deletions src/components/backdrop/_backdrop.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.player {
.backdrop {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.6);
transition: 100ms opacity;
z-index: 5;
}
}
41 changes: 41 additions & 0 deletions src/components/backdrop/backdrop.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//@flow
import style from '../../styles/style.scss';
import {h} from 'preact';
import {Component} from 'preact';
import {connect} from 'preact-redux';

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

@connect(
mapStateToProps,
null
)
/**
* Backdrop component
*
* @class Backdrop
* @example <Backdrop/>
* @extends {Component}
*/
class Backdrop extends Component {
/**
* render component
*
* @param {*} props - component props
* @returns {?React$Element} - component element
* @memberof Backdrop
*/
render(props: any): ?React$Element<any> {
if (!props.show) return undefined;
return <div className={style.backdrop} />;
}
}

export {Backdrop};
1 change: 1 addition & 0 deletions src/components/backdrop/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {Backdrop} from './backdrop';
7 changes: 7 additions & 0 deletions src/components/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ class BaseComponent extends Component {
logger: any;
eventManager: EventManager;

/**
* Components default props.
* @type {Object}
* @static
*/
static defaultProps: Object = {};

/**
* Creates an instance of BaseComponent.
* @param {Object} [obj={ config: {} }] obj
Expand Down
1 change: 1 addition & 0 deletions src/components/bottom-bar/_bottom-bar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
}
}

.player.casting .bottom-bar,
.player.hover .bottom-bar,
.player.state-paused .bottom-bar,
.player.ad-break .bottom-bar,
Expand Down
69 changes: 69 additions & 0 deletions src/components/cast-on-tv/_cast-on-tv.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
@keyframes castOnTVAnimation {
0% {
opacity: 0;
transform: rotateY(70deg);
}
33% {
opacity: 0.3;
transform: rotateY(50deg);
}
66% {
opacity: 0.6;
transform: rotateY(30deg);
}
100% {
opacity: 1;
transform: rotateY(0);
}
}

.player {
.cast-on-tv-button-container {
margin: auto;
position: absolute;
left: 0;
bottom: 20px;
right: 0;
opacity: 0;

span {
font-family: $font-family;
font-weight: lighter;
color: white;
}

&.show-cast-on-tv {
animation: castOnTVAnimation 300ms linear forwards;
}
}

.btn.cast-on-tv-button {
font-size: 15px;
max-width: 200px;
transition: max-width 200ms;
padding: 0 16px;
white-space: nowrap;

span {
transform: translateX(0px);
opacity: 1;
transition: transform 100ms, opacity 100ms;
display: inline-block;
}
}

.cast-on-tv-icon-container {
width: 32px;
height: 32px;
display: inline-block;
vertical-align: top;
position: relative;
margin-right: 3px;

i {
position: absolute;
top: 0;
left: 0;
}
}
}
105 changes: 105 additions & 0 deletions src/components/cast-on-tv/cast-after-play.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
//@flow
import style from '../../styles/style.scss';
import {h} from 'preact';
import BaseComponent from '../base';
import {connect} from 'preact-redux';
import {IconType} from '../icon/index';
import {Icon} from '../icon/icon';
import {Localizer, Text} from 'preact-i18n';

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

@connect(
mapStateToProps,
null
)
/**
* CastAfterPlay component
*
* @class CastAfterPlay
* @example <CastAfterPlay player={this.player} />
* @extends {BaseComponent}
*/
class CastAfterPlay extends BaseComponent {
/**
* @static
* @type {Object} - Component default props
*/
static defaultProps: Object = {
icon: IconType.CastBrand
};

/**
* Creates an instance of CastOverlay.
* @param {Object} obj obj
* @memberof CastAfterPlay
*/
constructor(obj: Object) {
super({name: 'CastAfterPlay', player: obj.player});
}

/**
* on click call the stop casting API.
*
* @param {Event} e - click event
* @returns {void}
* @memberof CastAfterPlay
*/
onClick(e: Event): void {
e.stopPropagation();
this.player.stopCasting();
}

/**
* after component did mount, show the cast after play button.
*
* @returns {void}
* @memberof CastAfterPlay
*/
componentDidMount(): void {
setTimeout(() => {
this.setState({show: true});
}, 700);
}

/**
* render component
*
* @param {*} props - component props
* @returns {?React$Element} - component element
* @memberof CastAfterPlay
*/
render(props: any): ?React$Element<any> {
if (!props.isCasting || !props.isEnded) return undefined;
const rootStyle = [style.castOnTvButtonContainer];
if (this.state.show) {
rootStyle.push(style.showCastOnTv);
}
return (
<div>
<div className={rootStyle.join(' ')} onClick={e => this.onClick(e)}>
<a className={[style.btn, style.btnDarkTransparent, style.castOnTvButton].join(' ')}>
<div className={style.castOnTvIconContainer}>
<Icon type={props.icon} />
</div>
<Localizer>
<span>
<Text id="cast.disconnect_from_tv" />
</span>
</Localizer>
</a>
</div>
</div>
);
}
}

export {CastAfterPlay};

0 comments on commit 2e8e162

Please sign in to comment.