define('application/widgets/asset/asset', [
'application/widgets/pointerfocusableasset',
'application/widgets/asset/progressbar',
'application/widgets/loader',
'application/managers/session',
'application/managers/feature',
'application/utils',
'rofl/widgets/container',
'rofl/widgets/label',
'rofl/lib/utils',
'rofl/lib/l10n',
'antie/runtimecontext',
'application/managers/bookmark'
], function (
Button,
ProgressBar,
Loader,
SessionManager,
FeatureManager,
AppUtils,
Container,
Label,
Utils,
L10N,
RuntimeContext,
BookmarkManager
) {
'use strict';
var device = RuntimeContext.getDevice(),
app = RuntimeContext.getCurrentApplication(),
l10n = L10N.getInstance();
/**
* Base Widget for every asset in the app.
*/
return Button.extend({
/**
* Initialises the widget.
*
* @param {Object} data - The data.
* @param {Object} data.item - Contains the model item.
* @param {string} data.title - The title for this assset.
* @param {string} data.subtitle - The subtitle for this asset.
* @param {string} data.lockedTitle - The title for this asset when locked.
* @param {string} [data.logo] - The logo url.
* @param {string} data.background - The image url.
* @param {string} [data.lockedBackground] - The locked image url.
* @param {number} [data.startTime] - The content's start time.
* @param {number} [data.endTime] - The content's end time.
* @param {string} [data.topRightIcon] - The top right icon classname.
* @param {string} [data.bottomRightIcon] - The bottom right icon classname.
* @param {string} [data.topLeftText] - Top left text to show.
* @param {boolean} [data.gradient] - True if the gradient should show.
* @param {boolean} [data.progressbar] - True if the progressbar should show.
* @param {boolean} [data.setBookmarkProgress] - True if the progressbar should be filled with bookmark time.
* @param {boolean} [data.playOnSelect] - True if the asset should skip details and play after selected.
*/
init: function init (data) {
init.base.call(this);
this._isLocked = false;
this.addClass('asset');
this.setDataItem(data);
this._setListeners(data.listeners);
},
/**
* Sets listeners for the asset.
*
* @param {Array} [listeners] - Array of objects that contains any custom listener.
* @private
*/
_setListeners: function (listeners) {
var boundListener,
listenerEvName,
listenerEvHandler;
this._listeners = [];
Utils.each(listeners, Utils.bind(function (listener) {
listenerEvName = listener.evName;
listenerEvHandler = listener.evHandler;
boundListener = Utils.bind(listenerEvHandler, this, this);
this._listeners.push({
evName: listenerEvName,
evHandler: boundListener
});
app.addEventListener(listener.evName, boundListener);
}, this));
},
/**
* Remove listeners for the asset.
*
* @private
*/
_removeListeners: function () {
Utils.each(this._listeners, function (listener) {
app.removeEventListener(listener.evName, listener.evHandler);
});
},
/**
* Sets the data.
*/
setData: function () {
var data = this.getDataItem(),
showLockedTitles = Utils.getNested(SessionManager.getInstance().getUserPCParams(), 'showLockedTitles'),
title = data.title,
lockedTitle = data.lockedTitle || l10n.get('asset.locked'),
background = data.background;
if (this.isLocked()) {
title = showLockedTitles ? title : lockedTitle;
background = data.lockedBackground;
}
this._setBackground(background);
if (!this._metadata) {
this._buildMetadataContainer();
}
this._setGradient(data.gradient);
this._setTitle(title);
this._setSubTitle(data.subTitle);
this._setSubTitle2(data.subTitle2);
this._setLogo(data.logo);
this._setTopRightIcon(data.topRightIcon);
this._setBottomRightIcon(data.bottomRightIcon);
this._setTopLeftText(data.topLeftText);
this._setProgressBar(data.progressbar);
},
/**
* Sets locked background.
*/
setLockedBackground: function () {
if (!this._lockedContainer) {
this._buildLockedContainer();
this.insertChildWidget(0, this._lockedContainer);
this._lockedContainer.render(device);
}
if (!this._lockedIcon) {
this._buildLockedIcon();
this._lockedContainer.appendChildWidget(this._lockedIcon);
this._lockedIcon.render(device);
}
if (this._placeholder) {
this._placeholder.hide();
}
this._lockedContainer.show();
this._lockedIcon.show();
},
/**
* Sets the title.
*
* @param {string} title - The title.
* @private
*/
_setTitle: function (title) {
if (title) {
if (!this._title) {
this._buildTitle();
}
this._title.render(device);
this._title.setText(title);
this._metadata.appendChildWidget(this._title);
}
},
/**
* Sets the subtitle.
*
* @param {string} subTitle - The subtitle.
* @private
*/
_setSubTitle: function (subTitle) {
if (subTitle) {
if (!this._subTitle) {
this._buildSubTitle();
}
this._subTitle.render(device);
this._subTitle.setText(subTitle);
this._metadata.appendChildWidget(this._subTitle);
}
},
/**
* Sets the second subtitle.
*
* @param {string} subTitle2 - The second subtitle.
* @private
*/
_setSubTitle2: function (subTitle2) {
if (subTitle2) {
if (!this._subTitle2) {
this._buildSubTitle2();
}
this._subTitle2.render(device);
this._subTitle2.setText(subTitle2);
this._metadata.appendChildWidget(this._subTitle2);
}
},
/**
* Sets the top right icon.
*
* @param {string} icon - The icon.
* @private
*/
_setTopRightIcon: function (icon) {
if (icon) {
if (!this._topRightIcon) {
this._buildTopRightIcon();
}
this._topRightIcon.render(device);
this._toprightGradient.render(device);
this._topRightIcon.removeClass(this._previousTopRightIcon);
this._topRightIcon.addClass(icon);
this._previousTopRightIcon = icon;
this.appendChildWidget(this._toprightGradient);
this.appendChildWidget(this._topRightIcon);
} else if (this._topRightIcon) {
this.removeChildWidget(this._toprightGradient);
this.removeChildWidget(this._topRightIcon);
}
},
/**
* Sets the bottom right icon.
*
* @param {Object} icon - The icon.
* @param {string} [icon.textIcon] - The icon as text.
* @param {string} [icon.classIcon] - The icon as classname.
* @private
*/
_setBottomRightIcon: function (icon) {
var hasIcon = icon && (icon.textIcon || icon.classIcon);
if (hasIcon) {
if (!this._bottomRightIcon) {
this._buildBottomRightIcon();
}
this._bottomRightIcon.render(device);
if (icon.textIcon) {
this._bottomRightIcon.setText(icon.textIcon);
} else {
this._bottomRightIcon.addClass(icon.classIcon);
}
this.appendChildWidget(this._bottomRightIcon);
}
},
/**
* Sets the top left text.
*
* @param {string} text - The top left text.
* @private
*/
_setTopLeftText: function (text) {
if (text) {
if (!this._topLefttText) {
this._buildTopLeftText();
}
this._topLefttText.render(device);
this._topLefttText.setText(text);
this.appendChildWidget(this._topLefttText);
}
},
/**
* Sets the background image.
*
* @param {string} url - The image url.
* @private
*/
_setBackground: function (url) {
var self = this,
image;
if (!this._background) {
this._buildBackground();
this.appendChildWidget(this._background);
}
if (this.isLocked() && !url) {
this.setLockedBackground();
} else if (url) {
this._buildPlaceholder();
image = new Image();
image.onload = function () {
self._setImage();
image.onload = null;
delete image.onload;
};
image.onerror = function () {
self._loader.hide();
image.onerror = null;
delete image.onerror;
};
image.src = url;
}
},
/**
* Sets the logo.
*
* @param {string} url - The logo url.
* @private
*/
_setLogo: function (url) {
if (url) {
if (!this._logo) {
this._buildLogo();
this.appendChildWidget(this._logo);
}
this._logo.render(device);
this._logo.setStyleTo('backgroundImage', 'url(' + url + ')');
}
},
/**
* Sets the gradient.
*
* @param {boolean} gradient - True if the gradient should show.
* @private
*/
_setGradient: function (gradient) {
if (gradient) {
if (!this._gradient) {
this._buildGradient();
}
this._gradient.render(device);
this.appendChildWidget(this._gradient);
}
},
/**
* Sets the content's progressbar.
*
* @param {boolean} progressbar - True if progressbar is to be set.
* @private
*/
_setProgressBar: function (progressbar) {
if (progressbar) {
if (!this._progressBar) {
this._buildProgressBar();
this.appendChildWidget(this._progressBar);
this._progressBar.render(device);
}
this._progressBar.setIsLive(true);
this.updateProgressBar();
} else if (this._progressBar) {
this.removeChildWidget(this._progressBar);
delete this._progressBar;
}
},
/**
* Updates the content's progressbar.
*
* @returns {boolean} - Progress complete.
*/
updateProgressBar: function () {
var percentage,
dataItem,
bookmarkTime,
contentItem;
if (!this._progressBar) {
return false;
}
dataItem = this.getDataItem();
contentItem = dataItem.item;
// Set bookmark progress or current time progress.
if (dataItem.setBookmarkProgress) {
bookmarkTime = BookmarkManager.getBookmark(contentItem.getId(), contentItem.getContentType());
percentage = this._getBookmarkPercentage(contentItem.getDuration(), bookmarkTime);
} else {
percentage = this._getPercentage(dataItem.startTime, dataItem.endTime);
}
if (this._progressBar) {
this._progressBar.setProgress(percentage);
}
return true;
},
/**
* 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 = app.getDate(),
percentage,
allTime,
passedTime;
allTime = endTime - startTime;
passedTime = now - startTime;
percentage = Math.round((passedTime * 100) / allTime);
return percentage;
},
/**
* Returns the progressBar percentage.
*
* @param {number} duration - The content's duration.
* @param {number} bookmark - The bookmark time.
* @returns {number} - The percentage.
* @private
*/
_getBookmarkPercentage: function (duration, bookmark) {
return Math.round((bookmark * 100) / duration);
},
/**
* Builds the placeholder.
*
* @private
*/
_buildPlaceholder: function () {
var placeholder = this._placeholder,
loader = this._loader;
if (!placeholder) {
placeholder = this._placeholder = new Container();
loader = this._loader = new Loader();
loader.addClass('small-loader');
placeholder.addClass('asset-placeholder');
placeholder.appendChildWidget(loader);
this.appendChildWidget(placeholder);
}
placeholder.render(device);
loader.show();
placeholder.show();
},
/**
* Sets the background image after loading.
*
* @private
*/
_setImage: function () {
var data = this.getDataItem(),
isLocked = this.isLocked(),
background = data.background;
if (!this._background.rendered) {
this._background.render(device);
this._background.rendered = true;
}
if (isLocked) {
background = data.lockedBackground;
if (!this._lockedIcon) {
this._buildLockedIcon();
this._background.appendChildWidget(this._lockedIcon);
} else if (!this._lockedIcon.parentWidget) {
this._background.appendChildWidget(this._lockedIcon);
}
} else if (this._lockedIcon) {
// Remove locked icon.
this._background.removeChildWidgets();
// Remove locked container.
if (this._lockedContainer) {
this._lockedContainer.hide();
}
}
this._background.setStyleTo('backgroundImage', 'url(' + background + ')');
this._loader.hide({ skipAnim: true });
this._placeholder.hide({ skipAnim: true });
},
/**
* Renders the widget.
*
* @param {Object} d - The device.
* @returns {Object} - The output element.
*/
render: function render (d) {
var outputElement = render.base.call(this, d);
if (!this.rendered) {
this.rendered = true;
this.setData();
}
return outputElement;
},
/**
* Builds the widget.
*
* @private
*/
_build: function () {
this._buildBackground();
this._buildTitle();
this._buildLogo();
this._buildSubTitle();
this._buildSubTitle2();
this._buildBottomRightIcon();
this._buildTopRightIcon();
this._buildTopLeftText();
this._buildGradient();
this._buildProgressBar();
},
/**
* Builds the metadata container (for title, subtitle, subtitle 2, etc..).
*
* @private
*/
_buildMetadataContainer: function () {
var metadata = this._metadata = new Container();
metadata.addClass('metadata-container');
this.appendChildWidget(metadata);
},
/**
* Builds the locked icon.
*
* @private
*/
_buildLockedIcon: function () {
var lockedIcon = this._lockedIcon = new Container();
lockedIcon.addClass(['locked-icon', 'icon-lock']);
},
/**
* Builds the locked icon.
*
* @private
*/
_buildLockedContainer: function () {
var lockedContainer = this._lockedContainer = new Container();
lockedContainer.addClass('locked-container');
},
/**
* Builds the background.
*
* @private
*/
_buildBackground: function () {
var background = this._background = new Container();
background.addClass('background');
},
/**
* Builds the logo.
*
* @private
*/
_buildLogo: function () {
var logo = this._logo = new Container();
logo.addClass('logo');
},
/**
* Builds the title.
*
* @private
*/
_buildTitle: function () {
this._title = new Label({ text: '', classNames: ['title'] });
},
/**
* Builds the subtitle.
*
* @private
*/
_buildSubTitle: function () {
var subTitleClassNames = this.getDataItem().classNames.subTitle,
classNames = ['subtitle'];
if (subTitleClassNames) {
classNames = classNames.concat(subTitleClassNames);
}
this._subTitle = new Label({ text: '', classNames: classNames });
},
/**
* Builds the second subtitle.
*
* @private
*/
_buildSubTitle2: function () {
var subTitle2ClassNames = this.getDataItem().classNames.subTitle2,
classNames = [];
if (subTitle2ClassNames) {
classNames = classNames.concat(subTitle2ClassNames);
}
this._subTitle2 = new Label({ text: '', classNames: classNames });
},
/**
* Builds the bottom right icon.
*
* @private
*/
_buildBottomRightIcon: function () {
var bottomRightIconClassNames = this.getDataItem().classNames.bottomRightIcon,
classNames = ['icon', 'bottomright'];
if (bottomRightIconClassNames) {
classNames = classNames.concat(bottomRightIconClassNames);
}
this._bottomRightIcon = new Label({ text: '', classNames: classNames });
},
/**
* Builds the top right icon.
*
* @private
*/
_buildTopRightIcon: function () {
this._topRightIcon = new Label({ text: '', classNames: ['icon', 'topright'] });
this._toprightGradient = new Container();
this._toprightGradient.addClass('topright-gradient');
},
/**
* Builds the top left text.
*
* @private
*/
_buildTopLeftText: function () {
var topLeftTextClassNames = this.getDataItem().classNames.topLeftText,
classNames = ['topleft'];
if (topLeftTextClassNames) {
classNames = classNames.concat(topLeftTextClassNames);
}
this._topLefttText = new Label({ text: '', classNames: classNames });
},
/**
* Builds the gradient.
*
* @private
*/
_buildGradient: function () {
this._gradient = new Label({ text: '', classNames: ['gradient'] });
},
/**
* Builds the progressBar.
*
* @private
*/
_buildProgressBar: function () {
this._progressBar = new ProgressBar();
},
/**
* Disposes the widget.
*/
dispose: function dispose () {
var self = this,
dataItem = this.getDataItem(),
listeners = dataItem.listeners;
if (listeners) {
this._removeListeners(listeners);
}
Utils.each(self, function (item, key) {
if (item) {
if (typeof item.dispose === 'function') {
item.dispose();
}
}
self[key] = null;
delete self[key];
});
dispose.base.call(this);
},
/**
* Checks whether asset is child protected.
*
* @returns {boolean} - True if is child protected.
*/
isLocked: function () {
var assetItem = Utils.getNested(this.getDataItem(), 'item');
this._isLocked = AppUtils.isBroadcastLocked(assetItem);
return this._isLocked;
},
/**
* For the rendered assets remove the locked container and set background and title.
*/
unlock: function () {
var data = this.getDataItem(),
background = data.background;
if (background) {
// Remove blurred query param from the background url.
data.background = background.replace('?blurred=true', '');
}
if (!this.rendered || !this._isLocked) {
return;
}
this._setBackground(data.background);
this._setTitle(data.title);
},
lock: function () {
var data = this.getDataItem(),
showLockedTitles = Utils.getNested(SessionManager.getInstance().getUserPCParams(), 'showLockedTitles'),
lockedTitle = data.lockedTitle || l10n.get('asset.locked'),
title = showLockedTitles ? data.title : lockedTitle;
if (!this.rendered || !this.isLocked()) {
return;
}
this._locked = true;
this._setBackground(data.lockedBackground);
this._setTitle(title);
},
/**
* Checks if asset should play after select.
*
* @returns {boolean} - Returns true if asset should play after selecting.
*/
playOnSelect: function () {
return this.getDataItem().playOnSelect;
}
});
});