mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
update docked tabs
This commit is contained in:
parent
818ee2bcc3
commit
16e66718f9
9 changed files with 147 additions and 80 deletions
20
dashboard-ui/components/appfooter/appfooter.css
Normal file
20
dashboard-ui/components/appfooter/appfooter.css
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
.appfooter {
|
||||||
|
background: #1c1c1c;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.appfooter-headroom {
|
||||||
|
transition: transform 180ms linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.appfooter--pinned {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.appfooter--unpinned {
|
||||||
|
transform: translateY(100%);
|
||||||
|
}
|
72
dashboard-ui/components/appfooter/appfooter.js
Normal file
72
dashboard-ui/components/appfooter/appfooter.js
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
define(['css!./appfooter'], function () {
|
||||||
|
|
||||||
|
function render(options) {
|
||||||
|
|
||||||
|
var elem = document.createElement('div');
|
||||||
|
|
||||||
|
elem.classList.add('appfooter');
|
||||||
|
|
||||||
|
document.body.appendChild(elem);
|
||||||
|
|
||||||
|
return elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
function initHeadRoom(instance, elem) {
|
||||||
|
|
||||||
|
require(["headroom"], function () {
|
||||||
|
|
||||||
|
// construct an instance of Headroom, passing the element
|
||||||
|
var headroom = new Headroom(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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function dockedTabs(options) {
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.element = render(options);
|
||||||
|
|
||||||
|
self.add = function (elem) {
|
||||||
|
self.element.appendChild(elem);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.insert = function (elem) {
|
||||||
|
if (typeof elem === 'string') {
|
||||||
|
self.element.insertAdjacentHTML('afterbegin', elem);
|
||||||
|
} else {
|
||||||
|
self.element.insertBefore(elem, self.element.firstChild);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
initHeadRoom(self, self.element);
|
||||||
|
}
|
||||||
|
|
||||||
|
dockedTabs.prototype.destroy = function () {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (self.headroom) {
|
||||||
|
self.headroom.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.Element = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
return dockedTabs;
|
||||||
|
});
|
|
@ -1,32 +1,7 @@
|
||||||
.dockedtabs {
|
.dockedtabs-tabs {
|
||||||
height: 54px;
|
|
||||||
background: #212121;
|
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 1;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dockedtabs-bottom {
|
|
||||||
bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dockedtabs-headroom {
|
|
||||||
transition: transform 180ms linear;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dockedtabs--pinned {
|
|
||||||
transform: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dockedtabs--unpinned {
|
|
||||||
transform: translateY(100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dockedtabs-tabs {
|
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
padding: .5em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dockedtabs-tab-button {
|
.dockedtabs-tab-button {
|
||||||
|
|
|
@ -36,53 +36,21 @@
|
||||||
|
|
||||||
elem.innerHTML = html;
|
elem.innerHTML = html;
|
||||||
|
|
||||||
document.body.appendChild(elem);
|
options.appFooter.add(elem);
|
||||||
|
|
||||||
return elem;
|
return elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
function initHeadRoom(instance, elem) {
|
|
||||||
|
|
||||||
require(["headroom"], function () {
|
|
||||||
|
|
||||||
// construct an instance of Headroom, passing the element
|
|
||||||
var headroom = new Headroom(elem, {
|
|
||||||
// or scroll tolerance per direction
|
|
||||||
tolerance: {
|
|
||||||
down: 20,
|
|
||||||
up: 0
|
|
||||||
},
|
|
||||||
classes: {
|
|
||||||
pinned: 'dockedtabs--pinned',
|
|
||||||
unpinned: 'dockedtabs--unpinned',
|
|
||||||
top: 'dockedtabs--top',
|
|
||||||
notTop: 'dockedtabs--not-top',
|
|
||||||
initial: 'dockedtabs-headroom'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// initialise
|
|
||||||
headroom.init();
|
|
||||||
|
|
||||||
instance.headroom = headroom;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function dockedTabs(options) {
|
function dockedTabs(options) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.element = render(options);
|
self.element = render(options);
|
||||||
|
|
||||||
initHeadRoom(self, self.element);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dockedTabs.prototype.destroy = function() {
|
dockedTabs.prototype.destroy = function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (self.headroom) {
|
|
||||||
self.headroom.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
self.Element = null;
|
self.Element = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -33,9 +33,14 @@
|
||||||
<button is="emby-button" type="button" class="raised subdued hide btnCancelRecording"><i class="md-icon">delete</i><span>${ButtonCancelRecording}</span></button>
|
<button is="emby-button" type="button" class="raised subdued hide btnCancelRecording"><i class="md-icon">delete</i><span>${ButtonCancelRecording}</span></button>
|
||||||
<button is="emby-button" type="button" class="raised subdued btnSync hide"><i class="md-icon">sync</i><span>${ButtonSync}</span></button>
|
<button is="emby-button" type="button" class="raised subdued btnSync hide"><i class="md-icon">sync</i><span>${ButtonSync}</span></button>
|
||||||
<button is="emby-button" type="button" class="raised subdued btnMoreCommands hide notext"><i class="md-icon">more_vert</i></button>
|
<button is="emby-button" type="button" class="raised subdued btnMoreCommands hide notext"><i class="md-icon">more_vert</i></button>
|
||||||
<button is="emby-button" type="button" class="fab mini subdued btnSyncLocal hide"><i class="md-icon">file_download</i></button>
|
|
||||||
<div class="detailUserDataIcons userDataIcons"></div>
|
<div class="detailUserDataIcons userDataIcons"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="syncLocalContainer hide" style="margin-top:1em; display: inline-flex; padding: 0 .5em;">
|
||||||
|
<label class="checkboxContainer" style="margin:0;">
|
||||||
|
<input type="checkbox" is="emby-checkbox" class="chkOffline" />
|
||||||
|
<span>Make Available Offline</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -52,9 +57,14 @@
|
||||||
<button is="emby-button" type="button" class="raised subdued hide btnCancelRecording"><i class="md-icon">delete</i><span>${ButtonCancelRecording}</span></button>
|
<button is="emby-button" type="button" class="raised subdued hide btnCancelRecording"><i class="md-icon">delete</i><span>${ButtonCancelRecording}</span></button>
|
||||||
<button is="emby-button" type="button" class="raised subdued btnSync hide"><i class="md-icon">sync</i><span>${ButtonSync}</span></button>
|
<button is="emby-button" type="button" class="raised subdued btnSync hide"><i class="md-icon">sync</i><span>${ButtonSync}</span></button>
|
||||||
<button is="emby-button" type="button" class="raised subdued btnMoreCommands hide notext"><i class="md-icon">more_vert</i></button>
|
<button is="emby-button" type="button" class="raised subdued btnMoreCommands hide notext"><i class="md-icon">more_vert</i></button>
|
||||||
<button is="emby-button" type="button" class="fab mini subdued btnSyncLocal hide"><i class="md-icon">file_download</i></button>
|
|
||||||
<div class="detailUserDataIcons userDataIcons"></div>
|
<div class="detailUserDataIcons userDataIcons"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="syncLocalContainer hide" style="margin-top:1em; display: inline-flex; padding: 0 .5em;">
|
||||||
|
<label class="checkboxContainer" style="margin:0;">
|
||||||
|
<input type="checkbox" is="emby-checkbox" class="chkOffline" />
|
||||||
|
<span>Make Available Offline</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div data-role="content" style="padding-top:0;clear:both;">
|
<div data-role="content" style="padding-top:0;clear:both;">
|
||||||
<div class="detailPageContent">
|
<div class="detailPageContent">
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
define(['layoutManager', 'cardBuilder', 'datetime', 'mediaInfo', 'backdrop', 'listView', 'itemContextMenu', 'itemHelper', 'userdataButtons', 'dom', 'indicators', 'apphost', 'scrollStyles', 'emby-itemscontainer'], function (layoutManager, cardBuilder, datetime, mediaInfo, backdrop, listView, itemContextMenu, itemHelper, userdataButtons, dom, indicators, appHost) {
|
define(['layoutManager', 'cardBuilder', 'datetime', 'mediaInfo', 'backdrop', 'listView', 'itemContextMenu', 'itemHelper', 'userdataButtons', 'dom', 'indicators', 'apphost', 'scrollStyles', 'emby-itemscontainer', 'emby-checkbox'], function (layoutManager, cardBuilder, datetime, mediaInfo, backdrop, listView, itemContextMenu, itemHelper, userdataButtons, dom, indicators, appHost) {
|
||||||
|
|
||||||
var currentItem;
|
var currentItem;
|
||||||
|
|
||||||
|
@ -87,16 +87,10 @@
|
||||||
function updateSyncStatus(page, item) {
|
function updateSyncStatus(page, item) {
|
||||||
|
|
||||||
var i, length;
|
var i, length;
|
||||||
var elems = page.querySelectorAll('.btnSyncLocal');
|
var elems = page.querySelectorAll('.chkOffline');
|
||||||
for (i = 0, length = elems.length; i < length; i++) {
|
for (i = 0, length = elems.length; i < length; i++) {
|
||||||
|
|
||||||
if (item.SyncPercent == 100) {
|
elems[i].checked = item.SyncPercent == 100;
|
||||||
elems[i].querySelector('i').innerHTML = 'offline_pin';
|
|
||||||
elems[i].classList.add('btnSyncComplete');
|
|
||||||
} else {
|
|
||||||
elems[i].querySelector('i').innerHTML = 'file_download';
|
|
||||||
elems[i].classList.remove('btnSyncComplete');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,16 +163,16 @@
|
||||||
|
|
||||||
if (itemHelper.canSync(user, item)) {
|
if (itemHelper.canSync(user, item)) {
|
||||||
if (appHost.supports('sync')) {
|
if (appHost.supports('sync')) {
|
||||||
hideAll(page, 'btnSyncLocal', true);
|
hideAll(page, 'syncLocalContainer', true);
|
||||||
hideAll(page, 'btnSync');
|
hideAll(page, 'btnSync');
|
||||||
} else {
|
} else {
|
||||||
hideAll(page, 'btnSyncLocal');
|
hideAll(page, 'syncLocalContainer');
|
||||||
hideAll(page, 'btnSync', true);
|
hideAll(page, 'btnSync', true);
|
||||||
}
|
}
|
||||||
updateSyncStatus(page, item);
|
updateSyncStatus(page, item);
|
||||||
} else {
|
} else {
|
||||||
hideAll(page, 'btnSync');
|
hideAll(page, 'btnSync');
|
||||||
hideAll(page, 'btnSyncLocal');
|
hideAll(page, 'syncLocalContainer');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.Type == 'Program' && item.TimerId) {
|
if (item.Type == 'Program' && item.TimerId) {
|
||||||
|
@ -2060,6 +2054,19 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onSyncLocalClick() {
|
||||||
|
|
||||||
|
if (this.checked) {
|
||||||
|
require(['syncDialog'], function (syncDialog) {
|
||||||
|
syncDialog.showMenu({
|
||||||
|
items: [currentItem]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return function (view, params) {
|
return function (view, params) {
|
||||||
|
|
||||||
function onPlayTrailerClick() {
|
function onPlayTrailerClick() {
|
||||||
|
@ -2116,9 +2123,9 @@
|
||||||
elems[i].addEventListener('click', onSyncClick);
|
elems[i].addEventListener('click', onSyncClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
elems = view.querySelectorAll('.btnSyncLocal');
|
elems = view.querySelectorAll('.chkOffline');
|
||||||
for (i = 0, length = elems.length; i < length; i++) {
|
for (i = 0, length = elems.length; i < length; i++) {
|
||||||
elems[i].addEventListener('click', onSyncClick);
|
elems[i].addEventListener('change', onSyncLocalClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
elems = view.querySelectorAll('.btnRecord,.btnFloatingRecord');
|
elems = view.querySelectorAll('.btnRecord,.btnFloatingRecord');
|
||||||
|
|
|
@ -1105,7 +1105,12 @@
|
||||||
|
|
||||||
setDrawerClass();
|
setDrawerClass();
|
||||||
|
|
||||||
//require(['dockedtabs'], function (dockedtabs) {
|
//require(['appfooter'], function (appfooter) {
|
||||||
// new dockedtabs({});
|
// var footer = new appfooter({});
|
||||||
|
// require(['dockedtabs'], function (dockedtabs) {
|
||||||
|
// new dockedtabs({
|
||||||
|
// appFooter: footer
|
||||||
|
// });
|
||||||
|
// });
|
||||||
//});
|
//});
|
||||||
});
|
});
|
|
@ -1260,6 +1260,7 @@ var AppInfo = {};
|
||||||
|
|
||||||
define("libjass", [bowerPath + "/libjass/libjass.min", "css!" + bowerPath + "/libjass/libjass"], returnFirstDependency);
|
define("libjass", [bowerPath + "/libjass/libjass.min", "css!" + bowerPath + "/libjass/libjass"], returnFirstDependency);
|
||||||
|
|
||||||
|
define("appfooter", ["components/appfooter/appfooter"], returnFirstDependency);
|
||||||
define("dockedtabs", ["components/dockedtabs/dockedtabs"], returnFirstDependency);
|
define("dockedtabs", ["components/dockedtabs/dockedtabs"], returnFirstDependency);
|
||||||
define("directorybrowser", ["components/directorybrowser/directorybrowser"], returnFirstDependency);
|
define("directorybrowser", ["components/directorybrowser/directorybrowser"], returnFirstDependency);
|
||||||
define("metadataEditor", [embyWebComponentsBowerPath + "/metadataeditor/metadataeditor"], returnFirstDependency);
|
define("metadataEditor", [embyWebComponentsBowerPath + "/metadataeditor/metadataeditor"], returnFirstDependency);
|
||||||
|
|
|
@ -7,6 +7,8 @@ var staticFileBaseUrl = baseUrl + '/staticfiles';
|
||||||
console.log('service worker location: ' + self.location);
|
console.log('service worker location: ' + self.location);
|
||||||
console.log('service worker base url: ' + baseUrl);
|
console.log('service worker base url: ' + baseUrl);
|
||||||
|
|
||||||
|
var connectionManager;
|
||||||
|
|
||||||
function getStaticFileList() {
|
function getStaticFileList() {
|
||||||
|
|
||||||
if (staticFileList) {
|
if (staticFileList) {
|
||||||
|
@ -100,6 +102,13 @@ self.addEventListener('activate', function (event) {
|
||||||
});
|
});
|
||||||
|
|
||||||
function getApiClient(serverId) {
|
function getApiClient(serverId) {
|
||||||
|
|
||||||
|
if (connectionManager) {
|
||||||
|
return Promise.resolve(connectionManager.getApiClient(serverId));
|
||||||
|
}
|
||||||
|
|
||||||
|
//importScripts('serviceworker-cache-polyfill.js');
|
||||||
|
|
||||||
return Promise.reject();
|
return Promise.reject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue