Skip to content

Commit

Permalink
feat(FEC-10666): add HD/4K indication in quality selector (#621)
Browse files Browse the repository at this point in the history
Currently, the quality selector lists all resolutions that appear in the manifest, taking the height from the resolution and appending a 'P'.
Qualities would look like: 360P, 720P, 1080P, 1440P, etc

However, today's viewers do not know what 720p or 1440p means. They know SD, HD and 4K (and soon - 8K).
We wish to add a simple indication that would allow millennials to know the quality they are watching.

Requirements
For resolutions, where height is between 720 (included) and 2160 (excluded) add an HD indication.
For resolutions, where height is between 2160 (included) and 4320 (excluded) add a 4K indication.
For resolutions, where height is above 4320 (included) add a 8K indication.
  • Loading branch information
JonathanTGold committed Jul 19, 2021
1 parent 2ae29d0 commit a81f08f
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 6 deletions.
15 changes: 15 additions & 0 deletions src/components/badge/_badge.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.badge {
height: 10px;
width: 15px;
background-color: white;
color: black;
border-radius: 1px;
font-size: 9px;
text-transform: uppercase;
margin-left: 3px;
margin-top: 2px;
align-self: flex-start;
display: flex;
justify-content: center;
align-items: center;
}
27 changes: 27 additions & 0 deletions src/components/badge/badge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//@flow
import {h, Component} from 'preact';
import style from '../../styles/style.scss';

const COMPONENT_NAME = 'Badge';

/**
* Badge component
*
* @class Badge
* @example <Badge content={badgeContent} />
* @extends {Component}
*/
class Badge extends Component {
/**
* render component
*
* @returns {React$Element} - component
* @memberof Badge
*/
render(): React$Element<any> {
return <span className={style.badge}>{this.props.content}</span>;
}
}

Badge.displayName = COMPONENT_NAME;
export {Badge};
1 change: 1 addition & 0 deletions src/components/badge/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {Badge} from './badge';
1 change: 1 addition & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export {ErrorOverlay} from './error-overlay';
export * from './event-dispatcher';
export * from './keyboard';
export {Icon, IconType, IconState} from './icon';
export {Badge} from './badge';
export {LiveTag} from './live-tag';
export {Loading} from './loading';
export {Menu} from './menu';
Expand Down
1 change: 1 addition & 0 deletions src/components/menu/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ class MenuItem extends Component {
onClick={this.onClick}
onKeyDown={this.onKeyDown}>
<span>{props.data.label}</span>
{props.data.badge ? props.data.badge : null}
<span className={[style.menuIconContainer, style.active].join(' ')}>
<Icon type={IconType.Check} />
</span>
Expand Down
29 changes: 28 additions & 1 deletion src/components/settings/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ import {actions as overlayIconActions} from 'reducers/overlay-action';
import {Tooltip} from 'components/tooltip';
import {Button} from 'components/button';
import {ButtonControl} from 'components/button-control';
import {Badge} from 'components/badge';

const HeightResolution = {
HD: 720,
UHD_4K: 2160,
UHD_8K: 4320
};

/**
* mapping state to props
Expand Down Expand Up @@ -243,6 +250,25 @@ class Settings extends Component {
return qualities;
}

/**
* Prepares the badge of the quality option according to the height of its resolution.
*
* @param {number} videoTrackHeight - video track quality height.
* @returns {Component<Badge>} - the badge withe the appropriate value.
* @memberof Settings
*/
getBadge(videoTrackHeight: number): Component<Badge> {
let badgeContent = '';
if (videoTrackHeight >= HeightResolution.HD && videoTrackHeight < HeightResolution.UHD_4K) {
badgeContent = 'HD';
} else if (videoTrackHeight >= HeightResolution.UHD_4K && videoTrackHeight < HeightResolution.UHD_8K) {
badgeContent = '4K';
} else if (videoTrackHeight >= HeightResolution.UHD_8K) {
badgeContent = '8K';
}
return badgeContent ? <Badge content={badgeContent} /> : null;
}

/**
* render component
*
Expand Down Expand Up @@ -276,7 +302,8 @@ class Settings extends Component {
.map(t => ({
label: t.label,
active: !player.isAdaptiveBitrateEnabled() && t.active,
value: t
value: t,
badge: this.getBadge(t.height)
}));

// Progressive playback doesn't support auto
Expand Down
1 change: 0 additions & 1 deletion src/components/smart-container/_smart-container.scss
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@
max-width: 100px;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
vertical-align: middle;
}
}
Expand Down
7 changes: 3 additions & 4 deletions src/styles/_dropdown.scss
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@
}

.dropdown-menu-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 2px 10px 2px 16px;
white-space: nowrap;
min-height: 30px;
Expand Down Expand Up @@ -106,10 +109,6 @@
width: 24px;
height: 24px;
}
span {
vertical-align: middle;
line-height: 26px;
}

.menu-icon-container {
opacity: 0;
Expand Down
1 change: 1 addition & 0 deletions src/styles/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,4 @@
@import '../components/interactive-area/_interactive-area';
@import '../components/video-area/video-area';
@import '../components/gui-area/gui-area';
@import '../components/badge/badge';

0 comments on commit a81f08f

Please sign in to comment.