define('application/components/movies', [
'application/components/uibuilder',
'application/managers/api',
'antie/runtimecontext',
'rofl/widgets/label',
'rofl/lib/l10n',
'rofl/widgets/container',
'antie/widgets/verticallist',
'rofl/lib/utils',
'application/managers/genre',
'application/models/uibuilder/filteredResult',
'application/widgets/movies/grid',
'rofl/analytics/web/google',
'rofl/lib/promise',
'application/widgets/infoblock',
'rofl/events/keyevent',
'antie/storageprovider'
], function (
UIBuilder,
ApiManager,
RuntimeContext,
Label,
L10N,
Container,
VerticalList,
Utils,
GenreManager,
FilteredResult,
Grid,
GoogleAnalytics,
Promise,
InfoBlock,
KeyEvent,
StorageProvider
) {
'use strict';
var api = ApiManager.getKPNAPI(),
application = RuntimeContext.getCurrentApplication(),
device = application.getDevice(),
storage = device.getStorage(StorageProvider.STORAGE_TYPE_SESSION, 'storage'),
layout = application.getLayout(),
l10n = L10N.getInstance(),
GA = GoogleAnalytics.getInstance(),
EVENT = {
Movies_HeroClickAction: 'Movies_HeroClickAction',
UserClickedonFilter: 'Movies_UserClickedonFilter',
UserClickedonGenreFilter: 'Movies_UserClickedonGenreFilter',
UserClickedonSortingOptions: 'Movies_UserClickedonSortingOptions',
PlayVideo: 'PlayVideo',
StartVideo: 'StartVideo',
StopVideo: 'StopVideo',
PauseButton: 'PauseButton',
Trickplay: 'Trickplay'
},
GALabels = {
MoreInfo: 'MoreInfo',
WatchNow: 'WatchNow'
},
filterTypes = {
GENRE: 'genre',
SORT: 'sort',
FILTER: 'filter'
},
sortOptions = {
'Nieuwste eerst': {
name: 'Nieuwste eerst',
value: {
orderBy: 'activationDate',
sortOrder: 'desc'
}
},
'Best beoordeeld': {
name: 'Best beoordeeld',
value: {
orderBy: 'extendedMetadata.imdbRating',
sortOrder: 'desc'
}
},
'Naam: A - Z': {
name: 'Naam: A - Z',
value: {
orderBy: 'title',
sortOrder: 'asc'
}
},
'Naam: Z - A': {
name: 'Naam: Z - A',
value: {
orderBy: 'title',
sortOrder: 'desc'
}
}
},
filterOptions = {
'Geen kinderfilms': {
name: 'Geen kinderfilms',
value: 'Kinderen,erotiek'
}
},
infoblockConfig = {
id: 'back-on-top-block',
text: l10n.get('infoblock'),
classname: ['icon', 'icon-back-v2'],
position: 'right'
},
STORAGE_ITEMS = {
parental: 'parental'
},
topPosition = layout.movies.top;
return UIBuilder.extend({
/**
* Initialises the component.
*/
init: function init () {
this.pageId = 'movies';
init.base.call(this);
},
/**
* Builds the component.
*
* @private
*/
_build: function _build () {
_build.base.call(this);
this._buildPageContainer();
this._buildHeader();
this._buildTitle({
label: {text: l10n.get('movies.title'), classNames: ['top-title']}
});
this._buildInfoBlock();
},
/**
* Builds the header.
*
* @private
*/
_buildPageContainer: function () {
var pageContainer = this._pageContainer = new VerticalList();
this.appendChildWidget(pageContainer);
},
/**
* Builds the header.
*
* @private
*/
_buildHeader: function () {
var header = this._header = new Container();
header.addClass('header');
this._pageContainer.appendChildWidget(header);
},
/**
* Builds the no results message.
*
* @private
*/
_showNoResultsMessage: function () {
var noResultsLabel = this._noResultsLabel = new Label({
text: l10n.get('movies.noresults'),
classNames: ['noresults']
});
this.addClass('empty-result');
this._widgetList.removeChildWidgets();
this._widgetList.appendChildWidget(noResultsLabel);
},
/**
* Builds the infoblock.
*
* @private
*/
_buildInfoBlock: function () {
var infoblock = this._infoblock = new InfoBlock(infoblockConfig);
infoblock.addClass('info-block');
this.appendChildWidget(infoblock);
},
/**
* BeforeShow event.
*
* @param {Object} e - The event data.
*/
onBeforeShow: function (e) {
var activeRowIndex,
isParentalActive,
eventArgs = e.args;
application.showLoader();
if (!e.fromBack) {
this._resetPage();
this._infoblock.hide({skipAnim: true});
if (eventArgs && Utils.isFunction(eventArgs.callback)) {
eventArgs.callback();
}
} else {
application.hideLoader();
this.alignCarouselsToLastIndex();
activeRowIndex = this._widgetList && this._widgetList.getActiveChildWidgetIndex();
this._widgetList.focus();
isParentalActive = storage.getItem(STORAGE_ITEMS.parental);
if (activeRowIndex > 0) {
this._infoblock.show();
} else {
this._infoblock.hide({skipAnim: true});
}
if (!this._assetsUnlocked && !isParentalActive) {
this._unlockAssets();
}
}
},
/**
* Loads the data.
*
* @param {Object} params - The parameters.
* @private
*/
_loadData: function loadMoviesData (params) {
var defaultParams = {
page: application.getConfiguration().PAGES.MOVIES
},
customParams = params || {},
allParams = Utils.extend(defaultParams, customParams);
api.read('uibuilder/page', {
params: allParams
}).then(Utils.bind(function (sectionsPage) {
var promises = [];
promises.push(sectionsPage.prepareHero());
promises.push(sectionsPage.prepareCarousels());
Promise.all(promises)
.then(Utils.bind(this._onDataReady, this));
}, this));
},
/**
* Loads the filtered data.
*
* @private
*/
_loadFilteredData: function loadFilteredData () {
var selectedGenre = this._getActiveFilters()[filterTypes.GENRE] ? this._getActiveFilters()[filterTypes.GENRE].name : null,
selectedFilter = this._getActiveFilters()[filterTypes.FILTER] ? this._getActiveFilters()[filterTypes.FILTER].value : null,
selectedSort = this._getActiveFilters()[filterTypes.SORT] ? this._getActiveFilters()[filterTypes.SORT].value : null,
firstLoadTo = application.getConfiguration().movies.firstLoadTo,
genre,
filter,
order,
sort,
options,
pagination;
if (Object.keys(this._getActiveFilters()).length < 1) {
this._resetPage();
return;
}
switch (selectedGenre) {
case l10n.get('genre.overview'):
this._resetPage();
return;
case l10n.get('genre.highlighted'):
genre = '&filter_categoryId=' + this._getActiveFilters()[filterTypes.GENRE].values;
order = '';
sort = '';
break;
case null:
genre = '';
break;
default:
genre = '&filter_genres=' + this._getActiveFilters()[filterTypes.GENRE].values.join();
break;
}
genre += '&filter_contentType=VOD' +
'&filter_contentSubtype=VOD' +
'&filter_quality=hd' +
'&dfilter_packages=matchSubscription' +
'&filter_technicalPackages=10078,10081,10129,10132,10159,10162,10228,10231,10252,10255,10258,10261';
sort = selectedSort ? '&sortOrder=' + selectedSort.sortOrder : '';
order = selectedSort ? '&orderBy=' + selectedSort.orderBy : '';
pagination = '&from=0&to=' + firstLoadTo;
filter = selectedFilter ? '&filter_excludedGenres=' + this._getActiveFilters()[filterTypes.FILTER].value : '&filter_excludedGenres=erotiek';
options = {
title: selectedGenre || l10n.get('genre.all'),
uri: '/TRAY/SEARCH/VOD/?' + order + sort + filter + genre + pagination
};
this._previousActiveRowNumber = null;
this._buildGrid();
this._lastPaginationIndex = firstLoadTo + 1;
this._filteredResult = new FilteredResult(options);
this._filteredResult.prepare().then(Utils.bind(this._onFilteredDataReady, this));
},
/**
* Lazy loading data fetch.
*
* @private
*/
_loadMoreFilteredData: function _loadMoreFilteredData () {
var selectedGenre = this._getActiveFilters()[filterTypes.GENRE] ? this._getActiveFilters()[filterTypes.GENRE].name : null,
selectedFilter = this._getActiveFilters()[filterTypes.FILTER] ? this._getActiveFilters()[filterTypes.FILTER].value : null,
selectedSort = this._getActiveFilters()[filterTypes.SORT] ? this._getActiveFilters()[filterTypes.SORT].value : null,
newPaginationIndex = this._lastPaginationIndex + application.getConfiguration().movies.followingLoads,
genre,
filter,
order,
sort,
options,
pagination,
gridList,
nextRowIndex,
rowsCount,
listWidgetStrip,
nextWidget;
switch (selectedGenre) {
case l10n.get('genre.overview'):
this._resetPage();
return;
case l10n.get('genre.highlighted'):
genre = '&filter_categoryId=' + this._getActiveFilters()[filterTypes.GENRE].values;
order = '';
sort = '';
break;
case null:
genre = '';
break;
default:
genre = '&filter_genres=' + this._getActiveFilters()[filterTypes.GENRE].values.join();
break;
}
genre += '&filter_contentType=VOD' +
'&filter_contentSubtype=VOD' +
'&filter_quality=hd' +
'&dfilter_packages=matchSubscription' +
'&filter_technicalPackages=10078,10081,10129,10132,10159,10162,10228,10231,10252,10255,10258,10261';
sort = selectedSort ? '&sortOrder=' + selectedSort.sortOrder : '';
order = selectedSort ? '&orderBy=' + selectedSort.orderBy : '';
pagination = '&from=' + this._lastPaginationIndex + '&to=' + newPaginationIndex;
this._lastPaginationIndex = newPaginationIndex + 1;
filter = selectedFilter ? '&filter_excludedGenres=' + this._getActiveFilters()[filterTypes.FILTER].value : '&filter_excludedGenres=erotiek';
options = {
title: selectedGenre || l10n.get('genre.all'),
uri: '/TRAY/SEARCH/VOD/?' + order + sort + filter + genre + pagination
};
if (!this._loadInProgress) {
this._loadInProgress = true;
this._filteredResult.setData(options);
this._filteredResult.prepare().then(Utils.bind(function (data) {
gridList = this._grid.getList();
nextRowIndex = gridList.getActiveChildWidgetIndex() + 1;
rowsCount = gridList.getChildWidgetCount();
listWidgetStrip = this._grid.getList().getMask().getWidgetStrip();
if (data._items) {
this._grid.appendData(data._items, false, false);
}
// This conditional block will render & append the last two rows if they're not rendered & visible.
if (nextRowIndex >= rowsCount - 1) {
nextWidget = listWidgetStrip.getChildWidgetByIndex(nextRowIndex);
if (nextWidget && !nextWidget.isRendered()) {
device.appendChildElement(listWidgetStrip.outputElement, nextWidget.render(device));
nextWidget = gridList.getChildWidgetByIndex(nextRowIndex + 1);
if (nextWidget) {
device.appendChildElement(listWidgetStrip.outputElement, nextWidget.render(device));
}
} else {
nextWidget = listWidgetStrip.getChildWidgetByIndex(nextRowIndex + 1);
if (nextWidget && !nextWidget.isRendered()) {
device.appendChildElement(listWidgetStrip.outputElement, nextWidget.render(device));
}
}
}
this._loadInProgress = false;
}, this));
}
},
/**
* Gets executed when the filtered page data has loaded.
*
* @param {Array} pageSections - The grid data to build.
* @private
*/
_onFilteredDataReady: function (pageSections) {
this._settingDataItems = true;
if (pageSections._items.length <= 0) {
this._showNoResultsMessage();
return;
}
this.removeClass('empty-result');
this._widgetList.removeChildWidgets();
// Unset hero found and reset top to the default top position.
this.heroFound = false;
this._widgetList.setStyleTo('top', layout.movies.top + 'px');
this._widgetList.appendChildWidget(this._grid);
this._grid.setDataItem({
items: pageSections._items
}, false, true);
if (!this._grid.isVisible()) {
this._grid.show();
}
this._settingDataItems = false;
this._totalCount = pageSections._totalCount;
application.hideLoader();
},
/**
* Gets executed when the page data has loaded.
*
* @param {Array} pageSections - The sections to build.
* @private
*/
_onDataReady: function (pageSections) {
var sections = this._parseSections(pageSections),
moviesLayout = layout.movies,
firstContentCarousel;
topPosition = moviesLayout.top;
this.buildWidgets(sections);
this.alignCarousels();
firstContentCarousel = this._widgetList.getChildWidgetByIndex(0);
this._addFilterWidget();
this._buildClock();
this._widgetList.focus();
if (!this.heroFound) {
topPosition = moviesLayout.topNoHero;
firstContentCarousel.focus();
}
this._widgetList.setStyleTo('top', topPosition + 'px');
application.hideLoader();
},
/**
* Transforms the sections.
*
* @param {Array} pageSections - The sections to transform.
* @returns {Object} - Returns an object with a collection of hero slider items and carousels.
*/
_parseSections: function (pageSections) {
var hero = pageSections[0],
carousels = pageSections[1];
return {
hero: hero,
carousels: carousels
};
},
/**
* Builds the widgets and appends them to the component.
*
* @param {Object} pageSections - The sections that contains collections of widgets.
* @param {Object} [sectionParams] - Specific params to use for the widgets. i.e. layouts.
*/
buildWidgets: function (pageSections, sectionParams) {
var hero = pageSections.hero,
carousels = pageSections.carousels,
sections = [];
if (hero && hero.getItems().length) {
sections = sections.concat(hero);
}
if (carousels.length) {
sections = sections.concat(carousels);
}
this.heroFound = false;
Utils.each(sections, function (section) {
this.buildWidget(section, sectionParams);
}, this);
if (!this.heroFound) {
this.addClass('no-hero-item');
this._list.getChildWidgetByIndex(0).focus();
} else {
if (this.hasClass('no-hero-item')) {
this.removeClass('no-hero-item');
}
}
},
/**
* Builds the grid.
*
* @private
*/
_buildGrid: function () {
var opts = {
loadmoreCallback: Utils.bind(this._loadMoreFilteredData, this)
};
this._grid = new Grid(opts);
},
/**
* Select event.
*
* @param {Object} e - The event data.
* @private
*/
_onSelect: function (e) {
var eventTarget = e.target,
contentItem,
selectAction = Utils.bind(function () {
contentItem = eventTarget.getDataItem().item;
if (eventTarget.playOnSelect()) {
if (contentItem.canPlay()) {
this._routeToPlayer({
data: contentItem,
type: 'VOD_MOVIE',
callingPage: this.pageId
});
}
} else if (eventTarget.hasClass('asset')) {
this._routeToDetails({
data: contentItem
});
}
}, this),
sliderItem;
switch (eventTarget.id) {
case 'back-on-top-block':
this._onBack();
return;
case 'filter-genre-btn':
this._genreFilterSelected();
return;
case 'filter-filter-btn':
this._commonFilterSelected();
return;
case 'filter-sort-btn':
this._sortFilterSelected();
return;
// no default
}
if (e.target.hasClass('watchall')) {
this.goToWatchAll(e.target.getDataItem());
return;
}
if (eventTarget.hasClass('slider-item') || (eventTarget.hasClass('epg') || eventTarget.hasClass('vod'))) {
sliderItem = e.target.getDataItem();
contentItem = sliderItem.item || sliderItem.getItem();
selectAction = Utils.bind(this._routeToDetails, this, {
data: contentItem
});
if (contentItem.isLocked()) {
application.route('parentalpin', {
successCallback: Utils.bind(function () {
selectAction();
this._unlockAssets();
GA.onEvent('Action', EVENT.Movies_HeroClickAction, {eventLabel: GALabels.MoreInfo});
}, this)
});
} else {
selectAction();
GA.onEvent('Action', EVENT.Movies_HeroClickAction, {eventLabel: GALabels.MoreInfo});
}
} else if (e.target.hasClass('pointer-button-big')) {
if (e.target.hasClass('left-pointer')) {
e.target.parentWidget.getCarousel().alignPrevious();
} else if (e.target.hasClass('right-pointer')) {
e.target.parentWidget.getCarousel().alignNext();
}
} else if (!e.target.isLocked()) {
selectAction();
} else {
application.route('parentalpin', {
successCallback: Utils.bind(function () {
selectAction();
this._unlockAssets();
}, this)
});
}
},
/**
* Attempts to play the video.
*
* @param {Object} dataItem - The data item.
* @private
*/
_onPlay: function (dataItem) {
var data = dataItem || this._data[0];
if (data.canPlay()) {
application.route('vodplayer', {
data: data
});
}
},
/**
* Popup a modal to filter a genre.
*
* @private
*/
_genreFilterSelected: function () {
var genreArray = [],
genreValues = [],
genres = GenreManager.MOVIE_GENRES,
all = l10n.get('genre.overview'),
highlighted = l10n.get('genre.highlighted');
genreArray.push(all);
genreValues.push({
name: all,
values: null
});
genreArray.push(highlighted);
genreValues.push({
name: highlighted,
values: 11393
});
Utils.each(genres, function (genre) {
genreArray.push(genre.name);
genreValues.push(genre);
});
clearTimeout(this._timer);
application.route('dropdown', {
dataOptions: genreArray,
dataValues: genreValues,
prevValue: this._genrefilter.getGenreButton().getText(),
filter: 'genre',
callback: Utils.bind(this._onDropdownCallback, this),
showGoBackButton: true
});
},
/**
* Popup a modal to filter by filtering.
*
* @private
*/
_commonFilterSelected: function () {
var genreArray = [],
genreValues = [],
genres = filterOptions,
all = l10n.get('filter.all_movies');
genreArray.push(all);
genreValues.push({
name: all,
values: null
});
Utils.each(genres, function (value, key) {
genreArray.push(key);
genreValues.push(value);
});
clearTimeout(this._timer);
application.route('dropdown', {
dataOptions: genreArray,
dataValues: genreValues,
prevValue: this._commonfilter.getFilterButton().getText(),
filter: 'filter',
callback: Utils.bind(this._onDropdownCallback, this),
showGoBackButton: true
});
},
/**
* Popup a modal to filter by sorting.
*
* @private
*/
_sortFilterSelected: function () {
var genreArray = [],
genreValues = [],
genres = sortOptions,
all = l10n.get('sort.all');
genreArray.push(all);
genreValues.push({
name: all,
values: null
});
Utils.each(genres, function (value, key) {
genreArray.push(key);
genreValues.push(value);
});
clearTimeout(this._timer);
application.route('dropdown', {
dataOptions: genreArray,
dataValues: genreValues,
prevValue: this._sortfilter.getSortButton().getText(),
filter: 'sort',
callback: Utils.bind(this._onDropdownCallback, this),
showGoBackButton: true
});
},
/**
* Function fires after dropdown item is selected.
*
* @param {Object} event - Selected item.
* @private
*/
_onDropdownCallback: function (event) {
var target,
filterName,
valueObject;
if (!event) {
return;
}
application.showLoader();
target = event.target;
filterName = target._filterName;
valueObject = target._itemValueObject;
this._setFilter(filterName, valueObject);
this._markSelectedFilters();
this._sendFiltersAnalyticsEvents(filterName, valueObject.name);
this._loadFilteredData();
},
/**
* Upload text filter value.
*
* @param {string} filter - Filter name.
* @param {string} value - Value which should be set.
* @private
*/
_setFilter: function (filter, value) {
var buttonName = value.name;
switch (filter) {
case 'genre':
if (buttonName === l10n.get('genre.overview')) {
buttonName = l10n.get('genre.all');
}
this._genrefilter.getGenreButton().setText(buttonName);
break;
case 'filter':
if (buttonName === l10n.get('filter.all')) {
buttonName = l10n.get('filter.filter');
}
this._commonfilter.getFilterButton().setText(buttonName);
break;
case 'sort':
this._sortfilter.getSortButton().setText(buttonName);
break;
}
if (value.values || value.value) {
this._setActiveFilters(filter, value);
} else {
this._removeActiveFilter(filter);
}
},
/**
* Send the appropriate events to google analytics.
*
* @param {string} type - Type of the filter.
* @param {string} value - Value which should be sent to GA.
* @private
*/
_sendFiltersAnalyticsEvents: function (type, value) {
switch (type) {
case 'genre':
GA.onEvent('Action', EVENT.UserClickedonGenreFilter, {eventLabel: value});
break;
case 'filter':
break;
case 'sort':
GA.onEvent('Action', EVENT.UserClickedonSortingOptions, {eventLabel: value});
break;
}
},
/**
* Upload text filter value.
*
* @param {string} filter - Filter name.
* @param {string} value - Value which should be set.
* @private
*/
_setActiveFilters: function (filter, value) {
this._activeFilters = this._activeFilters || {};
this._activeFilters[filter] = value;
},
/**
* Upload text filter value.
*
* @param {string} filter - Filter name.
* @private
*/
_removeActiveFilter: function (filter) {
delete this._activeFilters[filter];
},
/**
* Return the active filter if any.
*
* @returns {Array} List of active filters.
* @private
*/
_getActiveFilters: function () {
return this._activeFilters;
},
/**
* Clear the filters set.
*
* @private
*/
_clearAllFilters: function () {
this._activeFilters = {};
},
/**
* Mark active filtes as selected, if any.
*
* @private
*/
_markSelectedFilters: function () {
var activeFilters = this._getActiveFilters();
if (activeFilters['genre']) {
if (!this._genrefilter.hasClass('selected')) {
this._genrefilter.addClass('selected');
}
} else {
if (this._genrefilter.hasClass('selected')) {
this._genrefilter.removeClass('selected');
}
}
if (activeFilters['filter']) {
if (!this._commonfilter.hasClass('selected')) {
this._commonfilter.addClass('selected');
}
} else {
if (this._commonfilter.hasClass('selected')) {
this._commonfilter.removeClass('selected');
}
}
if (activeFilters['sort']) {
if (!this._sortfilter.hasClass('selected')) {
this._sortfilter.addClass('selected');
}
} else {
if (this._sortfilter.hasClass('selected')) {
this._sortfilter.removeClass('selected');
}
}
},
/**
* Selected item change event.
*
* @param {Object} e - The event data.
* @private
*/
_onSelectedItemChange: function (e) {
var activeRowNumber,
itemsLength,
target = e.target;
if (target === this._widgetList && !this._grid) {
this._scroll(e);
activeRowNumber = e.index + 1;
if (activeRowNumber > 1) {
this._infoblock.show();
} else {
this._infoblock.hide();
}
} else if (this._grid) {
activeRowNumber = this._grid.getActiveChildIndex() + 1;
if (activeRowNumber > 1) {
this._infoblock.show();
} else {
this._infoblock.hide();
}
if (this._grid.getDataItem()) {
itemsLength = this._grid.getDataItem().items.length;
if (!this._previousActiveRowNumber || activeRowNumber > this._previousActiveRowNumber && itemsLength < this._totalCount) {
this._grid.checkLoadMore();
this._previousActiveRowNumber = activeRowNumber;
}
}
}
},
/**
* Back event.
*
* @private
*/
_onBack: function () {
var activeRowNumber,
topCarousel;
if (this._grid) {
activeRowNumber = this._grid.getActiveChildIndex() + 1;
} else {
activeRowNumber = this._widgetList._selectedIndex + 1;
}
if (activeRowNumber !== 1) {
if (this._grid) {
this._grid.alignToFirstItem();
} else {
// Focus on first carousel/hero.
this._widgetList.setActiveChildIndex(0);
topCarousel = this._widgetList.getChildWidgetByIndex(0).getCarousel();
topCarousel.alignToIndex(0);
topCarousel.setActiveChildIndex(0);
}
} else {
application.focusMenu('main');
}
},
/**
* Reset the page to initial view.
*
* @private
*/
_resetPage: function () {
this.removeAll();
this.removeClass('empty-result');
this._loadData();
this._clearAllFilters();
this._markSelectedFilters();
this._genrefilter.getGenreButton().setText(l10n.get('genre.all'));
this._commonfilter.getFilterButton().setText(l10n.get('filter.filter'));
this._sortfilter.getSortButton().setText(l10n.get('sort.all'));
this._grid = null;
},
/**
* Scrolls the page.
*
* @param {Object} e - The selected item change event data.
* @param {boolean} donotAnim - Do not animate.
* @param {boolean} [reset] - True if the alignment should reset.
* @private
*/
_scroll: function (e, donotAnim, reset) {
if (!e.item.outputElement) {
return;
}
// Skip align at last carousel, this way we don't leave a gap at the end of the screen.
if (this._widgetList.getIndexOfChildWidget(e.item) >= 0) {
this._align(e.item, donotAnim, reset, e.index);
}
},
/**
* Aligns the widgetlist to the item.
*
* @param {Object} item - The item.
* @param {boolean} doNotAnim - Prevent animation.
* @param {boolean} [reset] - True if the alignment should reset.
* @private
*/
_align: function (item, doNotAnim, reset, index) {
var listElement = this._widgetList.outputElement,
listTop = listElement.getBoundingClientRect().top,
left = 0,
dimensions,
difference,
newTop,
moviesLayout = layout.movies,
marginTop = moviesLayout.marginTopCarousels;
dimensions = item.outputElement.getBoundingClientRect();
if (index > 1 || (index && !this.heroFound)) {
dimensions = this._widgetList.getChildWidgetByIndex(index - 1).outputElement.getBoundingClientRect();
}
difference = dimensions.top - marginTop;
if (difference > 0) {
newTop = listTop - difference;
} else {
newTop = listTop + -difference;
}
if (newTop > 0 || reset) {
newTop = topPosition;
}
device.moveElementTo({
el: listElement,
duration: 300,
fps: 60,
easing: 'easeInOut',
skipAnim: !!doNotAnim,
to: {
top: newTop,
left: left
}
});
}
});
});