define('application/widgets/detail/header', [
'rofl/widgets/container',
'rofl/widgets/label',
'rofl/widgets/image',
'rofl/widgets/horizontallist',
'application/widgets/detail/iconbutton',
'application/widgets/detail/progress',
'rofl/widgets/verticallist',
'rofl/lib/utils',
'application/utils',
'antie/runtimecontext',
'application/widgets/detail/buttons/play',
'application/widgets/detail/buttons/record',
'application/widgets/detail/buttons/close',
'application/widgets/detail/buttons/restart',
'application/widgets/detail/buttons/delete',
'application/managers/recording',
'application/managers/feature',
'application/models/production/series',
'rofl/lib/l10n',
'application/models/production/recordings/record',
'application/events/recorddeletedevent'
], function (
Container,
Label,
Image,
HorizontalList,
IconButton,
Progress,
VerticalList,
Utils,
AppUtils,
RuntimeContext,
PlayButton,
RecordButton,
CloseButton,
RestartButton,
DeleteButton,
RecordingManager,
FeatureManager,
Series,
L10N,
Record,
RecordDeletedEvent
) {
'use strict';
var VIDEO_RATINGS = {
G: 'icon-kijkwijzer-geweld-v2', // Geweld
A: 'icon-kijkwijzer-eng-v2', // Fear
S: 'icon-kijkwijzer-sex-v2', // Sex
D: 'icon-kijkwijzer-pesten-v2', // Discrimination
H: 'icon-kijkwijzer-drugs-v2', // Drugs or Alcohol use
T: 'icon-kijkwijzer-taal-v2', // Violent language,
'PC-6': 'icon-kijkwijzer-6-v2',
'PC-12': 'icon-kijkwijzer-12-v2',
'PC-16': 'icon-kijkwijzer-16-v2',
'PC-99': 'icon-kijkwijzer-al-v2'
},
application = RuntimeContext.getCurrentApplication(),
recordingManager = RecordingManager.getInstance(),
layoutObject = application.getLayout(),
layout = layoutObject.detailsHeader,
featureManager = FeatureManager.getInstance(),
l10n = L10N.getInstance(),
TYPES = {
LIVE: 'LIVE',
VOD: 'VOD',
RESTART: 'RESTART',
PROGRAM: 'PROGRAM',
RECORDING: 'RECORDING'
};
return Container.extend({
/**
* Initialises the input widget.
*/
init: function init () {
init.base.call(this);
this.addClass('details-page-header');
this._build();
},
/**
* Builds the widget.
*/
_build: function () {
this._buildBackImage();
this._buildGradient();
this._buildRowsList();
this._buildFirstRow();
this._buildChannelLogo();
this._buildSubtitle();
this._buildSecondRow();
this._buildTitle();
this._buildDuration();
this._buildDescription();
this._buildVideoRatings();
this._buildButtonsList();
this._buildProgressBar();
this._buildContentMessage();
},
/**
* Builds the back image.
*
* @private
*/
_buildBackImage: function () {
var backimg = this._backimg = new Image();
backimg.addClass('back-image');
this.appendChildWidget(backimg);
},
/**
* Builds the gradient.
*
* @private
*/
_buildGradient: function () {
var gradient = this._gradient = new Container();
gradient.addClass('gradient');
this.appendChildWidget(gradient);
},
/**
* Builds the list for rows.
*/
_buildRowsList: function () {
var rowsList = this._rowslist = new VerticalList();
rowsList.addClass('rowslist');
this.appendChildWidget(rowsList);
},
/**
* Builds the container for logo and subtitle.
*/
_buildFirstRow: function () {
var firstrow = this._firstrow = new Container();
firstrow.addClass('first-row');
this._rowslist.appendChildWidget(firstrow);
},
/**
* Builds the logo.
*/
_buildChannelLogo: function () {
var logo = this._logo = new Image('');
logo.addClass('channel-logo');
this._firstrow.appendChildWidget(logo);
},
/**
* Builds the subtitle.
*
* @private
*/
_buildSubtitle: function () {
var subtitle = this._subtitle = new Label({ classNames: ['subtitle'] });
this._firstrow.appendChildWidget(subtitle);
},
/**
* Builds the container for title and duration.
*/
_buildSecondRow: function () {
var secondrow = this._secondrow = new Container();
secondrow.addClass('second-row');
this._rowslist.appendChildWidget(secondrow);
},
/**
* Builds the title.
*/
_buildTitle: function () {
var title = this._title = new Label({ text: '', classNames: ['detail-header-title', 'title'] });
title.setWidth(layout.titleWidget);
title.setMaximumLines(2);
title.setTruncationMode(Label.TRUNCATION_MODE_RIGHT_ELLIPSIS);
this._secondrow.appendChildWidget(title);
},
/**
* Builds the duratio.
*/
_buildDuration: function () {
var duration = this._duration = new Label({ classNames: ['duration'] });
this._secondrow.appendChildWidget(duration);
},
/**
* Builds the description.
*/
_buildDescription: function () {
var description = this._description = new Label({ text: '', classNames: ['detail-header-description', 'description'] });
description.setWidth(layout.titleWidget);
description.setMaximumLines(5);
description.setTruncationMode(Label.TRUNCATION_MODE_RIGHT_ELLIPSIS);
this._rowslist.appendChildWidget(description);
},
/**
* Builds the icons list.
*/
_buildVideoRatings: function () {
var videoRatings = this._videoRatings = new Container();
videoRatings.addClass('video-ratings');
this._rowslist.appendChildWidget(videoRatings);
},
/**
* Builds the buttons list.
*/
_buildButtonsList: function () {
var list = this._buttonList = new HorizontalList('');
list.addClass('buttons-list');
list.focus();
this._rowslist.appendChildWidget(list);
},
/**
* Builds the progressbar.
*/
_buildProgressBar: function () {
var progressBar = this._progressBar = new Progress();
progressBar.setIsLive(true);
this.appendChildWidget(progressBar);
},
/**
* Builds the container for forbidden playback message.
*/
_buildContentMessage: function () {
var headerMessages = this._headerMessages = new Container();
headerMessages.addClass('header-messages');
this.appendChildWidget(headerMessages);
},
/**
* Builds the replay state.
*
* @param {Object} data - The data item.
* @private
*/
_buildReplayState: function (data) {
if (data instanceof Series) {
return;
}
if (!featureManager.isReplayEnabled() && data.isReplayItem()) {
this._headerMessages.appendChildWidget(this._createReplayMessage());
} else if (data.isReplayItem() && !data.canCatchup() && !data.isRecording()) {
this._headerMessages.appendChildWidget(this._createUnablePlayIcon());
this._headerMessages.appendChildWidget(this._createForbiddenReplayMessage());
}
},
/**
* Sets data props to elements.
*
* @param {Object} data - Data.
*/
setData: function (data) {
var startTime = new Date(data.getStartTime() * 1000),
endTime = new Date(data.getEndTime() * 1000),
percentage = this._getPercentage(startTime, endTime),
headerLayout = layout.image;
if (Utils.isFunction(data.getImageUrl)) {
this.setBackground(
data.getImageUrl(Math.round(headerLayout.width) + 'x' + Math.round(headerLayout.height)));
} else {
this.setBackground(data.getImage('manual', headerLayout));
}
if (Utils.isFunction(data.getChannelLogo)) {
this.setLogo(data.getChannelLogo());
} else {
this.setLogo(this._getLogo(data));
}
this.setTitle(data.getTitle());
this.setDuration(data.getDuration());
this.setSubtitle(startTime, endTime);
this.setDescription(data);
// Set the age rating and content ratings.
this.setVideoRatings([data.getAgeRating()]);
this.setVideoRatings(data.getVideoRatings());
if (0 > percentage < 100) {
if (this._progressBar.isRendered()) {
this._progressBar.hide();
}
} else {
this.setProgressBar(startTime, endTime);
}
},
/**
* Sets the series data.
*
* @param {Object} data - The data.
* @private
*/
setSeriesData: function (data) {
var startTime = new Date(data.getStartTime() * 1000),
endTime = new Date(data.getEndTime() * 1000),
headerLayout = layout.image,
item = data;
this.setBackground(data.getImageUrl(Math.round(headerLayout.width) + 'x' + Math.round(headerLayout.height)));
this.setLogo(data.getChannelLogo());
this.setTitle(data.getTitle());
this.setDuration(item.getDuration());
this.setVideoRatings([item.getAgeRating()]);
this.setVideoRatings(item.getVideoRatings());
this.setDescription(item);
this.setSubtitle(startTime, endTime);
this._progressBar.hide({skipAnim: true});
},
/**
* Returns the subtitle.
*
* @param {Object} data - The item.
* @returns {string} - The subtitle string.
* @private
*/
_getSubtitle: function (data) {
var duration = data.getDuration(),
subtitle;
subtitle = new Date(data.getStartTime() * 1000).format('H:i')
+ ' | ' + Math.floor(duration / 60) + 'm';
return subtitle;
},
/**
* Returns the logo.
*
* @param {Object} data - The item.
* @returns {string} - The logo url.
* @private
*/
_getLogo: function (data) {
return data.getChannel().getImage('128');
},
/**
* Sets the background image.
*
* @param {string} url - Url.
*/
setBackground: function (url) {
this._backimg.setSrc(url);
},
/**
* Sets the logo.
*
* @param {string} url - The url.
*/
setLogo: function (url) {
this._logo.setSrc(url);
},
/**
* Sets the title.
*
* @param {string} title - The title.
*/
setTitle: function (title) {
this._title.setText(title);
},
/**
* Sets the duration.
*
* @param {number} duration - The duration.
*/
setDuration: function (duration) {
this._duration.setText(Math.floor(duration / 60) + 'm');
},
/**
* Sets the description.
*
* @param {Object} data - The data.
*/
setDescription: function (data) {
var genre = data.getProgramType(),
description = '';
if (genre) {
description = genre + ' - ';
}
description += data.getDescription();
this._description.setText(description);
},
/**
* Sets the subtitle.
*
* @param {Date} startTime - The startTime.
* @param {Date} endTime - The endTime.
*/
setSubtitle: function (startTime, endTime) {
this._subtitle.setText(AppUtils.getStreamDate(startTime, endTime));
},
/**
* Sets the video ratings.
*
* @param {Array} ratings - The video ratings.
*/
setVideoRatings: function (ratings) {
var list = this._videoRatings;
Utils.each(ratings, function (rating) {
list.appendChildWidget(this._createVideoRating(rating));
}, this);
},
/**
* Creates a video rating label.
*
* @param {string} rating - The rating.
* @returns {Object} - The video rating label.
* @private
*/
_createVideoRating: function (rating) {
var videoRating = new Label({ text: '', classNames: [VIDEO_RATINGS[rating]] });
return videoRating;
},
/**
* Returns the progressBar percentage.
*
* @param {Date} startTime - The startTime.
* @param {Date} endTime - The end time.
* @returns {number} - The percentage.
* @private
*/
_getPercentage: function (startTime, endTime) {
var now = application.getDate(),
percentage,
allTime,
passedTime;
allTime = endTime - startTime;
passedTime = now - startTime;
percentage = Math.round((passedTime * 100) / allTime);
return percentage;
},
/**
* Sets the progress.
*
* @param {Date} startTime - The startTime.
* @param {Date} endTime - The end time.
*/
setProgressBar: function (startTime, endTime) {
var percentage = this._getPercentage(startTime, endTime);
this._progressBar.setProgress(percentage);
},
/**
* Sets the data item.
*
* @param {Object} item - The item.
* @param {Object} seriesItem - The series item.
*/
setDataItem: function setDataItem (item, seriesItem) {
setDataItem.base.call(this, item);
this._buttonList.removeChildWidgets();
this._addButtons(seriesItem || item);
this._buildReplayState(item);
},
/**
* Adds the buttons.
*
* @param {Object} item - The item.
* @private
*/
_addButtons: function (item) {
var isRecording,
isFutureBroadcast,
isFutureRecordable,
isScheduledRecording,
assets;
if (!(item instanceof Series || !item.hasChannelRights())) {
isFutureBroadcast = !item.isLive() && item.getStartTime() >= application.getDate() / 1000;
isFutureRecordable = isFutureBroadcast && item.canRecord();
isScheduledRecording = isFutureBroadcast && item.getContentType() === 'RECORDING';
if (item.isLive()) {
if (item instanceof Record || item.getContentType() === 'RECORDING') {
this._addPlayButton();
if (item.getStartTime() <= application.getDate() / 1000) {
this._addDeleteButton();
} else {
this._addRecordButton();
}
} else {
this._addPlayButton();
this._addRestartButton();
if (item.canRecord()) {
this._addRecordButton();
}
}
} else if (item.canPlay() && featureManager.isReplayEnabled() && item.isPlayable() && item.getAssetId() !== undefined) {
this._addPlayButton();
if ((item instanceof Record || item.getContentType() === 'RECORDING')
&& item.getStartTime() <= application.getDate() / 1000) {
this._addDeleteButton();
}
} else {
isRecording = (item instanceof Record || item.getContentType() === 'RECORDING')
&& item.getStartTime() <= application.getDate() / 1000;
if (isRecording) {
this._addDeleteButton();
}
if (isRecording) {
assets = item.getAssets();
if (assets[0] && assets[0].status && assets[0].status === 'RecordSuccess') {
// recording item that cannot be played - show message
this._headerMessages.appendChildWidget(this._createUnablePlayIcon('more-to-right'));
this._headerMessages.appendChildWidget(this._createForbiddenPlaybackMessage());
} else {
this._headerMessages.appendChildWidget(this._createUnablePlayIcon('more-to-right'));
this._headerMessages.appendChildWidget(this._createRecordingFailedMessage());
}
}
}
// Add record button for future assets
if (isFutureRecordable || isScheduledRecording) {
this._addRecordButton();
}
}
},
/**
* Adds a play button.
*
* @private
*/
_addPlayButton: function () {
this._playButton = new PlayButton();
this._playButton.setDataItem(this.getDataItem());
this._buttonList.appendChildWidget(this._playButton);
},
/**
* Adds a record button.
*
* @private
*/
_addRecordButton: function () {
var dataItem = this.getDataItem(),
hasRecording;
if (!application.getUser().canRecord()) {
return;
}
if (dataItem instanceof Series) {
hasRecording = recordingManager.hasRecording(
null, dataItem.getId());
} else {
hasRecording = recordingManager.hasRecording(
dataItem.getId(), dataItem.getSeriesId());
}
this._recordButton = new RecordButton();
this._recordButton.setDataItem(this.getDataItem());
if (hasRecording.episode || hasRecording.series) {
if (dataItem.isFutureItem() && dataItem.getContentType() === TYPES.RECORDING) {
this._recordButton.cancelRecording();
} else {
this._recordButton.recording();
}
}
this._buttonList.appendChildWidget(this._recordButton);
},
/**
* Adds a close button.
*
* @private
*/
_addCloseButton: function () {
this._closeButton = new CloseButton();
this._closeButton.setDataItem(this.getDataItem());
this._buttonList.appendChildWidget(this._closeButton);
},
/**
* Adds a restart button.
*
* @private
*/
_addRestartButton: function () {
this._restartButton = new RestartButton();
this._restartButton.setDataItem(this.getDataItem());
this._buttonList.appendChildWidget(this._restartButton);
},
/**
* Adds a delete button.
*
* @private
*/
_addDeleteButton: function () {
var button = this._deleteButton = new DeleteButton();
button.setDataItem(this.getDataItem());
this._buttonList.appendChildWidget(button);
},
/**
* Creates the replay icon.
*
* @param {Object} [className] - Class name.
* @private
* @returns {string} The label.
*/
_createUnablePlayIcon: function (className) {
var icon = new Label({ text: '', classNames: ['replay-disabled-icon', 'icon-unable-play', 'icon'] });
if (className) {
icon.addClass(className);
}
return icon;
},
/**
* Creates the replay message.
*
* @private
* @returns {string} The label.
*/
_createReplayMessage: function () {
var label = new Label({ text: l10n.get('details.replay_disabled'), classNames: ['replay-disabled'] });
return label;
},
/**
* Creates the forbidden replay message.
*
* @private
* @returns {string} The label.
*/
_createForbiddenReplayMessage: function () {
var label = new Label({ text: l10n.get('details.replay_forbidden'), classNames: ['replay-forbidden'] });
return label;
},
/**
* Creates the recording failed message.
*
* @private
* @returns {string} The label.
*/
_createRecordingFailedMessage: function () {
var label = new Label({ text: l10n.get('details.recording_failed'), classNames: ['recording-failed'] });
return label;
},
/**
* Creates the forbidden replay message.
*
* @param {string} className - The classname.
* @private
*
* @returns {string} The label.
*/
_createForbiddenPlaybackMessage: function (className) {
var label = new Label({ text: l10n.get('details.playback_forbidden'), classNames: ['playback-forbidden'] });
if (className) {
label.addClass(className);
}
return label;
},
/**
* Dispose the widget.
*/
dispose: function dispose () {
dispose.base.call(this);
},
/**
* Updates the recording status.
*
* @private
*/
updateRecordingStatus: function () {
var dataItem = this.getDataItem(),
hasRecording = recordingManager.hasRecording(
dataItem.getId(), dataItem.getSeriesId());
if (this._recordButton) {
if (hasRecording.episode || hasRecording.series) {
if (dataItem.isFutureItem() && dataItem.getContentType() === TYPES.RECORDING) {
this._recordButton.cancelRecording();
} else {
this._recordButton.recording();
}
} else {
this._recordButton.record();
}
}
if ((dataItem instanceof Record || dataItem.getContentType() === 'RECORDING')
&& !hasRecording.episode) {
this.dispose();
this.bubbleEvent(new RecordDeletedEvent(dataItem));
}
},
/**
* Focuses the widget.
*
* @returns {boolean} - True if focus is set.
*/
focus: function () {
if (this._buttonList.getChildWidgetCount()) {
return this._buttonList.focus();
}
},
/**
* Clears the widget.
*/
clear: function () {
this._backimg.setSrc('');
this._title.setText('');
this._subtitle.setText('');
this._buttonList.removeChildWidgets();
this._headerMessages.removeChildWidgets();
this._videoRatings.removeChildWidgets();
this.removeClass('shortheader');
},
/**
* Returns the button list count.
*
* @returns {number} - Number of widgets contained in button list.
*/
getButtonListLength: function () {
return this._buttonList.getChildWidgetCount();
}
});
});