1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

use shared headroom

This commit is contained in:
Luke Pulverenti 2016-08-15 22:40:29 -04:00
parent e5b6336256
commit a11c82ac9d
12 changed files with 177 additions and 156 deletions

View file

@ -130,11 +130,11 @@
* @param {DOMElement} elem the header element * @param {DOMElement} elem the header element
* @param {Object} options options for the widget * @param {Object} options options for the widget
*/ */
function Headroom(elem, options) { function Headroom(elems, options) {
options = extend(options, Headroom.options); options = extend(options, Headroom.options);
this.lastKnownScrollY = 0; this.lastKnownScrollY = 0;
this.elem = elem; this.elems = elems;
this.debouncer = new Debouncer(this.update.bind(this)); this.debouncer = new Debouncer(this.update.bind(this));
this.tolerance = normalizeTolerance(options.tolerance); this.tolerance = normalizeTolerance(options.tolerance);
this.classes = options.classes; this.classes = options.classes;
@ -143,8 +143,6 @@
this.initialised = false; this.initialised = false;
this.onPin = options.onPin; this.onPin = options.onPin;
this.onUnpin = options.onUnpin; this.onUnpin = options.onUnpin;
this.onTop = options.onTop;
this.onNotTop = options.onNotTop;
} }
Headroom.prototype = { Headroom.prototype = {
constructor: Headroom, constructor: Headroom,
@ -154,13 +152,30 @@
*/ */
init: function () { init: function () {
this.elem.classList.add(this.classes.initial); for (var i = 0, length = this.elems.length; i < length; i++) {
this.elems[i].classList.add(this.classes.initial);
}
this.attachEvent(); this.attachEvent();
return this; return this;
}, },
add: function (elem) {
elem.classList.add(this.classes.initial);
this.elems.push(elem);
},
remove: function (elem) {
var classes = this.classes;
elem.classList.remove(classes.unpinned, classes.pinned, classes.initial);
var i = this.elems.indexOf(elem);
if (i != -1) {
this.elems.splice(i, 1);
}
},
/** /**
* Unattaches events and removes any classes that were added * Unattaches events and removes any classes that were added
*/ */
@ -168,7 +183,11 @@
var classes = this.classes; var classes = this.classes;
this.initialised = false; this.initialised = false;
this.elem.classList.remove(classes.unpinned, classes.pinned, classes.top, classes.initial);
for (var i = 0, length = this.elems.length; i < length; i++) {
this.elems[i].classList.remove(classes.unpinned, classes.pinned, classes.initial);
}
removeEventListenerWithOptions(this.scroller, 'scroll', this.debouncer, { removeEventListenerWithOptions(this.scroller, 'scroll', this.debouncer, {
capture: false, capture: false,
passive: true passive: true
@ -196,13 +215,17 @@
* Unpins the header if it's currently pinned * Unpins the header if it's currently pinned
*/ */
unpin: function () { unpin: function () {
var classList = this.elem.classList,
classes = this.classes;
if (classList.contains(classes.pinned) || !classList.contains(classes.unpinned)) { var classes = this.classes;
classList.add(classes.unpinned);
classList.remove(classes.pinned); for (var i = 0, length = this.elems.length; i < length; i++) {
this.onUnpin && this.onUnpin.call(this); var classList = this.elems[i].classList;
if (classList.contains(classes.pinned) || !classList.contains(classes.unpinned)) {
classList.add(classes.unpinned);
classList.remove(classes.pinned);
this.onUnpin && this.onUnpin.call(this);
}
} }
}, },
@ -210,42 +233,19 @@
* Pins the header if it's currently unpinned * Pins the header if it's currently unpinned
*/ */
pin: function () { pin: function () {
var classList = this.elem.classList,
classes = this.classes;
if (classList.contains(classes.unpinned)) { var classes = this.classes;
classList.remove(classes.unpinned);
classList.add(classes.pinned); for (var i = 0, length = this.elems.length; i < length; i++) {
this.onPin && this.onPin.call(this); var classList = this.elems[i].classList;
if (classList.contains(classes.unpinned)) {
classList.remove(classes.unpinned);
classList.add(classes.pinned);
this.onPin && this.onPin.call(this);
}
} }
},
/**
* Handles the top states
*/
top: function () {
var classList = this.elem.classList,
classes = this.classes;
if (!classList.contains(classes.top)) {
classList.add(classes.top);
classList.remove(classes.notTop);
this.onTop && this.onTop.call(this);
}
},
/**
* Handles the not top state
*/
notTop: function () {
var classList = this.elem.classList,
classes = this.classes;
if (!classList.contains(classes.notTop)) {
classList.add(classes.notTop);
classList.remove(classes.top);
this.onNotTop && this.onNotTop.call(this);
}
}, },
/** /**
@ -315,14 +315,6 @@
return; return;
} }
if (this.enableTopClasses) {
if (currentScrollY <= this.offset) {
this.top();
} else {
this.notTop();
}
}
if (this.shouldUnpin(currentScrollY, toleranceExceeded)) { if (this.shouldUnpin(currentScrollY, toleranceExceeded)) {
this.unpin(); this.unpin();
} }
@ -347,8 +339,6 @@
classes: { classes: {
pinned: 'headroom--pinned', pinned: 'headroom--pinned',
unpinned: 'headroom--unpinned', unpinned: 'headroom--unpinned',
top: 'headroom--top',
notTop: 'headroom--not-top',
initial: 'headroom' initial: 'headroom'
} }
}; };

View file

@ -1,4 +1,4 @@
<div id="channelsPage" data-role="page" data-dom-cache="true" class="page libraryPage channelsPage pageWithAbsoluteTabs" data-contextname="${HeaderChannels}" data-require="scripts/channels,scripts/channelslatest,scripts/sections"> <div id="channelsPage" data-role="page" data-dom-cache="true" class="page libraryPage channelsPage pageWithAbsoluteTabs" data-contextname="${HeaderChannels}">
<div is="emby-tabs" class="libraryViewNav"> <div is="emby-tabs" class="libraryViewNav">
<div class="emby-tabs-slider"> <div class="emby-tabs-slider">

View file

@ -5,16 +5,9 @@
right: 0; right: 0;
z-index: 1; z-index: 1;
bottom: 0; bottom: 0;
}
.appfooter-headroom {
transition: transform 180ms linear; transition: transform 180ms linear;
} }
.appfooter--pinned { .appfooter.headroom--unpinned {
transform: none;
}
.appfooter--unpinned {
transform: translateY(100%); transform: translateY(100%);
} }

View file

@ -13,27 +13,10 @@
function initHeadRoom(instance, elem) { function initHeadRoom(instance, elem) {
require(["headroom"], function () { require(["headroom-window"], function (headroom) {
// construct an instance of Headroom, passing the element self.headroom = headroom;
var headroom = new Headroom(elem, { headroom.add(elem);
// or scroll tolerance per direction
tolerance: {
down: 20,
up: 0
},
classes: {
pinned: 'appfooter--pinned',
unpinned: 'appfooter--unpinned',
top: 'appfooter--top',
notTop: 'appfooter--not-top',
initial: 'appfooter-headroom'
}
});
// initialise
headroom.init();
instance.headroom = headroom;
}); });
} }
@ -62,10 +45,11 @@
var self = this; var self = this;
if (self.headroom) { if (self.headroom) {
self.headroom.destroy(); self.headroom.remove(self.element);
self.headroom = null;
} }
self.Element = null; self.element = null;
}; };
return dockedTabs; return dockedTabs;

View file

@ -1,4 +1,4 @@
define(['libraryBrowser', 'cardBuilder', 'emby-itemscontainer', 'emby-tabs', 'emby-button'], function (libraryBrowser, cardBuilder) { define(['libraryBrowser', 'cardBuilder', 'emby-itemscontainer', 'emby-tabs', 'emby-button', 'scripts/channelslatest', 'scripts/sections'], function (libraryBrowser, cardBuilder) {
// The base query options // The base query options
var query = { var query = {
@ -70,18 +70,29 @@
} }
} }
pageIdOn('pageinit', "channelsPage", function () { return function (view, params) {
var page = this; var self = this;
var viewTabs = view.querySelector('.libraryViewNav');
var mdlTabs = page.querySelector('.libraryViewNav'); libraryBrowser.configurePaperLibraryTabs(view, viewTabs, view.querySelectorAll('.pageTabContent'), [0, 1]);
libraryBrowser.configurePaperLibraryTabs(page, mdlTabs, page.querySelectorAll('.pageTabContent'), [0, 1]); viewTabs.addEventListener('tabchange', function (e) {
loadTab(view, parseInt(e.detail.selectedTabIndex));
mdlTabs.addEventListener('tabchange', function (e) {
loadTab(page, parseInt(e.detail.selectedTabIndex));
}); });
}); if (AppInfo.enableHeadRoom) {
require(["headroom-window"], function (headroom) {
headroom.add(viewTabs);
self.headroom = headroom;
});
}
view.addEventListener('viewdestroy', function (e) {
if (self.headroom) {
self.headroom.remove(viewTabs);
}
});
};
}); });

View file

@ -248,9 +248,9 @@
loadHomeTab(view, tabContent); loadHomeTab(view, tabContent);
}; };
var mdlTabs = view.querySelector('.libraryViewNav'); var viewTabs = view.querySelector('.libraryViewNav');
libraryBrowser.configurePaperLibraryTabs(view, mdlTabs, view.querySelectorAll('.pageTabContent'), [0, 1, 2, 3]); libraryBrowser.configurePaperLibraryTabs(view, viewTabs, view.querySelectorAll('.pageTabContent'), [0, 1, 2, 3]);
var tabControllers = []; var tabControllers = [];
var renderedTabs = []; var renderedTabs = [];
@ -319,11 +319,11 @@
}); });
} }
mdlTabs.addEventListener('beforetabchange', function (e) { viewTabs.addEventListener('beforetabchange', function (e) {
preLoadTab(view, parseInt(e.detail.selectedTabIndex)); preLoadTab(view, parseInt(e.detail.selectedTabIndex));
}); });
mdlTabs.addEventListener('tabchange', function (e) { viewTabs.addEventListener('tabchange', function (e) {
loadTab(view, parseInt(e.detail.selectedTabIndex)); loadTab(view, parseInt(e.detail.selectedTabIndex));
}); });
@ -343,7 +343,7 @@
if (state.NowPlayingItem && state.NowPlayingItem.MediaType == 'Video') { if (state.NowPlayingItem && state.NowPlayingItem.MediaType == 'Video') {
mdlTabs.triggerTabChange(); viewTabs.triggerTabChange();
} }
} }
@ -370,5 +370,18 @@
Events.off(MediaController, 'playbackstop', onPlaybackStop); Events.off(MediaController, 'playbackstop', onPlaybackStop);
Events.off(ApiClient, "websocketmessage", onWebSocketMessage); Events.off(ApiClient, "websocketmessage", onWebSocketMessage);
}); });
if (AppInfo.enableHeadRoom) {
require(["headroom-window"], function (headroom) {
headroom.add(viewTabs);
self.headroom = headroom;
});
}
view.addEventListener('viewdestroy', function (e) {
if (self.headroom) {
self.headroom.remove(viewTabs);
}
});
}; };
}); });

View file

@ -879,21 +879,6 @@
} }
} }
pageClassOn('pageinit', 'page', function () {
var page = this;
var isLibraryPage = page.classList.contains('libraryPage');
if (isLibraryPage) {
var navs = page.querySelectorAll('.libraryViewNav');
for (var i = 0, length = navs.length; i < length; i++) {
initHeadRoom(navs[i]);
}
}
});
pageClassOn('pagebeforeshow', 'page', function (e) { pageClassOn('pagebeforeshow', 'page', function (e) {
var page = this; var page = this;
@ -999,18 +984,9 @@
return; return;
} }
require(["headroom"], function () { require(["headroom-window"], function (headroom) {
// construct an instance of Headroom, passing the element headroom.add(elem);
var headroom = new Headroom(elem, {
// or scroll tolerance per direction
tolerance: {
down: 40,
up: 0
}
});
// initialise
headroom.init();
}); });
} }

View file

@ -198,11 +198,11 @@
}); });
} }
var mdlTabs = view.querySelector('.libraryViewNav'); var viewTabs = view.querySelector('.libraryViewNav');
libraryBrowser.configurePaperLibraryTabs(view, mdlTabs, view.querySelectorAll('.pageTabContent'), [0, 2, 3, 4]); libraryBrowser.configurePaperLibraryTabs(view, viewTabs, view.querySelectorAll('.pageTabContent'), [0, 2, 3, 4]);
mdlTabs.addEventListener('tabchange', function (e) { viewTabs.addEventListener('tabchange', function (e) {
loadTab(view, parseInt(e.detail.selectedTabIndex)); loadTab(view, parseInt(e.detail.selectedTabIndex));
}); });
@ -211,8 +211,18 @@
document.body.classList.remove('autoScrollY'); document.body.classList.remove('autoScrollY');
}); });
if (AppInfo.enableHeadRoom) {
require(["headroom-window"], function (headroom) {
headroom.add(viewTabs);
self.headroom = headroom;
});
}
view.addEventListener('viewdestroy', function (e) { view.addEventListener('viewdestroy', function (e) {
if (self.headroom) {
self.headroom.remove(viewTabs);
}
tabControllers.forEach(function (t) { tabControllers.forEach(function (t) {
if (t.destroy) { if (t.destroy) {
t.destroy(); t.destroy();

View file

@ -208,15 +208,9 @@
loadSuggestionsTab(view, params, tabContent); loadSuggestionsTab(view, params, tabContent);
}; };
var mdlTabs = view.querySelector('.libraryViewNav'); var viewTabs = view.querySelector('.libraryViewNav');
var baseUrl = 'movies.html'; libraryBrowser.configurePaperLibraryTabs(view, viewTabs, view.querySelectorAll('.pageTabContent'), [0, 3, 4, 5]);
var topParentId = params.topParentId;
if (topParentId) {
baseUrl += '?topParentId=' + topParentId;
}
libraryBrowser.configurePaperLibraryTabs(view, mdlTabs, view.querySelectorAll('.pageTabContent'), [0, 3, 4, 5]);
var tabControllers = []; var tabControllers = [];
var renderedTabs = []; var renderedTabs = [];
@ -290,14 +284,15 @@
}); });
} }
mdlTabs.addEventListener('beforetabchange', function (e) { viewTabs.addEventListener('beforetabchange', function (e) {
preLoadTab(view, parseInt(e.detail.selectedTabIndex)); preLoadTab(view, parseInt(e.detail.selectedTabIndex));
}); });
mdlTabs.addEventListener('tabchange', function (e) { viewTabs.addEventListener('tabchange', function (e) {
loadTab(view, parseInt(e.detail.selectedTabIndex)); loadTab(view, parseInt(e.detail.selectedTabIndex));
}); });
view.addEventListener('viewbeforeshow', function (e) { view.addEventListener('viewbeforeshow', function (e) {
if (!view.getAttribute('data-title')) { if (!view.getAttribute('data-title')) {
var parentId = params.topParentId; var parentId = params.topParentId;
@ -323,7 +318,7 @@
if (state.NowPlayingItem && state.NowPlayingItem.MediaType == 'Video') { if (state.NowPlayingItem && state.NowPlayingItem.MediaType == 'Video') {
renderedTabs = []; renderedTabs = [];
mdlTabs.triggerTabChange(); viewTabs.triggerTabChange();
} }
} }
@ -334,6 +329,19 @@
view.addEventListener('viewbeforehide', function (e) { view.addEventListener('viewbeforehide', function (e) {
Events.off(MediaController, 'playbackstop', onPlaybackStop); Events.off(MediaController, 'playbackstop', onPlaybackStop);
}); });
if (AppInfo.enableHeadRoom) {
require(["headroom-window"], function (headroom) {
headroom.add(viewTabs);
self.headroom = headroom;
});
}
view.addEventListener('viewdestroy', function (e) {
if (self.headroom) {
self.headroom.remove(viewTabs);
}
});
}; };
}); });

View file

@ -349,19 +349,29 @@
}); });
} }
var mdlTabs = view.querySelector('.libraryViewNav'); var viewTabs = view.querySelector('.libraryViewNav');
libraryBrowser.configurePaperLibraryTabs(view, mdlTabs, view.querySelectorAll('.pageTabContent'), [0, 4, 5, 6]); libraryBrowser.configurePaperLibraryTabs(view, viewTabs, view.querySelectorAll('.pageTabContent'), [0, 4, 5, 6]);
mdlTabs.addEventListener('beforetabchange', function (e) { viewTabs.addEventListener('beforetabchange', function (e) {
preLoadTab(view, parseInt(e.detail.selectedTabIndex)); preLoadTab(view, parseInt(e.detail.selectedTabIndex));
}); });
mdlTabs.addEventListener('tabchange', function (e) { viewTabs.addEventListener('tabchange', function (e) {
loadTab(view, parseInt(e.detail.selectedTabIndex)); loadTab(view, parseInt(e.detail.selectedTabIndex));
}); });
if (AppInfo.enableHeadRoom) {
require(["headroom-window"], function (headroom) {
headroom.add(viewTabs);
self.headroom = headroom;
});
}
view.addEventListener('viewdestroy', function (e) { view.addEventListener('viewdestroy', function (e) {
if (self.headroom) {
self.headroom.remove(viewTabs);
}
tabControllers.forEach(function (t) { tabControllers.forEach(function (t) {
if (t.destroy) { if (t.destroy) {
t.destroy(); t.destroy();

View file

@ -1185,6 +1185,25 @@ var AppInfo = {};
} }
} }
function createWindowHeadroom() {
// construct an instance of Headroom, passing the element
var headroom = new Headroom([], {
// or scroll tolerance per direction
tolerance: {
down: 20,
up: 0
},
classes: {
//pinned: 'appfooter--pinned',
//unpinned: 'appfooter--unpinned',
//initial: 'appfooter-headroom'
}
});
// initialise
headroom.init();
return headroom;
}
function initRequire() { function initRequire() {
var urlArgs = "v=" + (window.dashboardVersion || new Date().getDate()); var urlArgs = "v=" + (window.dashboardVersion || new Date().getDate());
@ -1491,6 +1510,8 @@ var AppInfo = {};
return Emby.Page; return Emby.Page;
}); });
define("headroom-window", ['headroom'], createWindowHeadroom);
// mock this for now. not used in this app // mock this for now. not used in this app
define("playbackManager", [], function () { define("playbackManager", [], function () {
return { return {
@ -1892,7 +1913,8 @@ var AppInfo = {};
path: '/channels.html', path: '/channels.html',
dependencies: [], dependencies: [],
autoFocus: false, autoFocus: false,
transition: 'fade' transition: 'fade',
controller: 'scripts/channels'
}); });
defineRoute({ defineRoute({

View file

@ -202,34 +202,28 @@
}); });
} }
var mdlTabs = view.querySelector('.libraryViewNav'); var viewTabs = view.querySelector('.libraryViewNav');
function onPlaybackStop(e, state) { function onPlaybackStop(e, state) {
if (state.NowPlayingItem && state.NowPlayingItem.MediaType == 'Video') { if (state.NowPlayingItem && state.NowPlayingItem.MediaType == 'Video') {
renderedTabs = []; renderedTabs = [];
mdlTabs.triggerTabChange(); viewTabs.triggerTabChange();
} }
} }
var baseUrl = 'tv.html';
var topParentId = params.topParentId;
if (topParentId) {
baseUrl += '?topParentId=' + topParentId;
}
if (enableScrollX()) { if (enableScrollX()) {
view.querySelector('#resumableItems').classList.add('hiddenScrollX'); view.querySelector('#resumableItems').classList.add('hiddenScrollX');
} else { } else {
view.querySelector('#resumableItems').classList.remove('hiddenScrollX'); view.querySelector('#resumableItems').classList.remove('hiddenScrollX');
} }
libraryBrowser.configurePaperLibraryTabs(view, mdlTabs, view.querySelectorAll('.pageTabContent'), [0, 1, 2, 4, 5, 6]); libraryBrowser.configurePaperLibraryTabs(view, viewTabs, view.querySelectorAll('.pageTabContent'), [0, 1, 2, 4, 5, 6]);
mdlTabs.addEventListener('beforetabchange', function (e) { viewTabs.addEventListener('beforetabchange', function (e) {
preLoadTab(view, parseInt(e.detail.selectedTabIndex)); preLoadTab(view, parseInt(e.detail.selectedTabIndex));
}); });
mdlTabs.addEventListener('tabchange', function (e) { viewTabs.addEventListener('tabchange', function (e) {
loadTab(view, parseInt(e.detail.selectedTabIndex)); loadTab(view, parseInt(e.detail.selectedTabIndex));
}); });
@ -278,8 +272,18 @@
Events.off(ApiClient, "websocketmessage", onWebSocketMessage); Events.off(ApiClient, "websocketmessage", onWebSocketMessage);
}); });
if (AppInfo.enableHeadRoom) {
require(["headroom-window"], function (headroom) {
headroom.add(viewTabs);
self.headroom = headroom;
});
}
view.addEventListener('viewdestroy', function (e) { view.addEventListener('viewdestroy', function (e) {
if (self.headroom) {
self.headroom.remove(viewTabs);
}
tabControllers.forEach(function (t) { tabControllers.forEach(function (t) {
if (t.destroy) { if (t.destroy) {
t.destroy(); t.destroy();