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

Merge pull request #1650 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2016-04-16 01:11:14 -04:00
commit 4aa607dbc6
45 changed files with 476 additions and 345 deletions

View file

@ -1,6 +1,6 @@
{
"name": "hls.js",
"version": "0.5.20",
"version": "0.5.21",
"license": "Apache-2.0",
"description": "Media Source Extension - HLS library, by/for Dailymotion",
"homepage": "https://github.com/dailymotion/hls.js",
@ -16,11 +16,11 @@
"test",
"tests"
],
"_release": "0.5.20",
"_release": "0.5.21",
"_resolution": {
"type": "version",
"tag": "v0.5.20",
"commit": "3fb06c59d0df49961c057b522dc08eba4b8b0f08"
"tag": "v0.5.21",
"commit": "25b13e24bbd97785da7e255db117902e692c09dd"
},
"_source": "git://github.com/dailymotion/hls.js.git",
"_target": "~0.5.7",

View file

@ -1,6 +1,6 @@
{
"name": "hls.js",
"version": "0.5.20",
"version": "0.5.21",
"license": "Apache-2.0",
"description": "Media Source Extension - HLS library, by/for Dailymotion",
"homepage": "https://github.com/dailymotion/hls.js",

View file

@ -427,7 +427,9 @@ var AbrController = function (_EventHandler) {
}, {
key: 'onFragLoading',
value: function onFragLoading(data) {
this.timer = setInterval(this.onCheck, 100);
if (!this.timer) {
this.timer = setInterval(this.onCheck, 100);
}
this.fragCurrent = data.frag;
}
}, {
@ -1188,6 +1190,7 @@ var LevelController = function (_EventHandler) {
value: function destroy() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
this._manualLevel = -1;
}
@ -1712,6 +1715,20 @@ var StreamController = function (_EventHandler) {
_logger.logger.log('buffer end: ' + bufferEnd + ' is located too far from the end of live sliding playlist, media position will be reseted to: ' + this.seekAfterBuffered.toFixed(3));
bufferEnd = this.seekAfterBuffered;
}
// if end of buffer greater than live edge, don't load any fragment
// this could happen if live playlist intermittently slides in the past.
// level 1 loaded [182580161,182580167]
// level 1 loaded [182580162,182580169]
// Loading 182580168 of [182580162 ,182580169],level 1 ..
// Loading 182580169 of [182580162 ,182580169],level 1 ..
// level 1 loaded [182580162,182580168] <============= here we should have bufferEnd > end. in that case break to avoid reloading 182580168
// level 1 loaded [182580164,182580171]
//
if (bufferEnd > end) {
break;
}
if (this.startFragRequested && !levelDetails.PTSKnown) {
/* we are switching level on live playlist, but we don't have any PTS info for that quality level ...
try to load frag matching with next SN.
@ -2516,11 +2533,11 @@ var StreamController = function (_EventHandler) {
_logger.logger.log('playback not stuck anymore @' + currentTime);
}
// check buffer upfront
// if less than 200ms is buffered, and media is expected to play but playhead is not moving,
// if less than jumpThreshold second is buffered, and media is expected to play but playhead is not moving,
// and we have a new buffer range available upfront, let's seek to that one
if (bufferInfo.len <= jumpThreshold) {
if (playheadMoving || !expectedPlaying) {
// playhead moving or media not playing
if (expectedPlaying && bufferInfo.len <= jumpThreshold) {
if (playheadMoving) {
// playhead moving
jumpThreshold = 0;
this.seekHoleNudgeDuration = 0;
} else {
@ -5158,7 +5175,9 @@ var ErrorDetails = exports.ErrorDetails = {
// Identifier for a buffer full event
BUFFER_FULL_ERROR: 'bufferFullError',
// Identifier for a buffer seek over hole event
BUFFER_SEEK_OVER_HOLE: 'bufferSeekOverHole'
BUFFER_SEEK_OVER_HOLE: 'bufferSeekOverHole',
// Identifier for an internal exception happening inside hls.js while handling an event
INTERNAL_EXCEPTION: 'internalException'
};
},{}],21:[function(require,module,exports){
@ -5170,18 +5189,18 @@ Object.defineProperty(exports, "__esModule", {
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
*
* All objects in the event handling chain should inherit from this class
*
*/
var _logger = require('./utils/logger');
var _errors = require('./errors');
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/*
*
* All objects in the event handling chain should inherit from this class
*
*/
//import {logger} from './utils/logger';
var EventHandler = function () {
function EventHandler(hls) {
_classCallCheck(this, EventHandler);
@ -5250,7 +5269,12 @@ var EventHandler = function () {
}
return this[funcName].bind(this, data);
};
eventToFunction.call(this, event, data).call();
try {
eventToFunction.call(this, event, data).call();
} catch (err) {
_logger.logger.error('internal error happened while processing ' + event + ':' + err.message);
this.hls.trigger(Event.ERROR, { type: _errors.ErrorTypes.OTHER_ERROR, details: _errors.ErrorDetails.INTERNAL_EXCEPTION, fatal: false, event: event, err: err });
}
}
}]);
@ -5259,7 +5283,7 @@ var EventHandler = function () {
exports.default = EventHandler;
},{}],22:[function(require,module,exports){
},{"./errors":20,"./utils/logger":36}],22:[function(require,module,exports){
'use strict';
module.exports = {
@ -5498,10 +5522,14 @@ var LevelHelper = function () {
if (PTSFrag) {
LevelHelper.updateFragPTS(newDetails, PTSFrag.sn, PTSFrag.startPTS, PTSFrag.endPTS);
} else {
// adjust start by sliding offset
var sliding = oldfragments[delta].start;
for (i = 0; i < newfragments.length; i++) {
newfragments[i].start += sliding;
// ensure that delta is within oldfragments range
// no need to offset start if delta === 0
if (delta > 0 && delta < oldfragments.length) {
// adjust start by sliding offset
var sliding = oldfragments[delta].start;
for (i = 0; i < newfragments.length; i++) {
newfragments[i].start += sliding;
}
}
}
// if we are here, it means we have fragments overlapping between
@ -5795,6 +5823,7 @@ var Hls = function () {
this.playlistLoader.destroy();
this.fragmentLoader.destroy();
this.levelController.destroy();
this.abrController.destroy();
this.bufferController.destroy();
this.capLevelController.destroy();
this.streamController.destroy();
@ -7281,8 +7310,8 @@ var MP4Remuxer = function () {
ptsnorm = this._PTSNormalize(pts, nextAvcDts);
dtsnorm = this._PTSNormalize(dts, nextAvcDts);
delta = Math.round((dtsnorm - nextAvcDts) / 90);
// if fragment are contiguous, or delta less than 600ms, ensure there is no overlap/hole between fragments
if (contiguous || Math.abs(delta) < 600) {
// if fragment are contiguous, or if there is a huge delta (more than 10s) between expected PTS and sample PTS
if (contiguous || Math.abs(delta) > 10000) {
if (delta) {
if (delta > 1) {
_logger.logger.log('AVC:' + delta + ' ms hole between fragments detected,filling it');
@ -7414,8 +7443,8 @@ var MP4Remuxer = function () {
ptsnorm = this._PTSNormalize(pts, nextAacPts);
dtsnorm = this._PTSNormalize(dts, nextAacPts);
delta = Math.round(1000 * (ptsnorm - nextAacPts) / pesTimeScale);
// if fragment are contiguous, or delta less than 600ms, ensure there is no overlap/hole between fragments
if (contiguous || Math.abs(delta) < 600) {
// if fragment are contiguous, or if there is a huge delta (more than 10s) between expected PTS and sample PTS
if (contiguous || Math.abs(delta) > 10000) {
// log delta
if (delta) {
if (delta > 0) {
@ -7427,7 +7456,7 @@ var MP4Remuxer = function () {
track.len -= unit.byteLength;
continue;
}
// set DTS to next DTS
// set PTS/DTS to next PTS/DTS
ptsnorm = dtsnorm = nextAacPts;
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
{
"name": "hls.js",
"version": "0.5.20",
"version": "0.5.21",
"license": "Apache-2.0",
"description": "Media Source Extension - HLS library, by/for Dailymotion",
"homepage": "https://github.com/dailymotion/hls.js",

View file

@ -30,7 +30,9 @@ class AbrController extends EventHandler {
}
onFragLoading(data) {
this.timer = setInterval(this.onCheck, 100);
if (!this.timer) {
this.timer = setInterval(this.onCheck, 100);
}
this.fragCurrent = data.frag;
}

View file

@ -20,7 +20,8 @@ class LevelController extends EventHandler {
destroy() {
if (this.timer) {
clearInterval(this.timer);
clearInterval(this.timer);
this.timer = null;
}
this._manualLevel = -1;
}

View file

@ -208,6 +208,20 @@ class StreamController extends EventHandler {
logger.log(`buffer end: ${bufferEnd} is located too far from the end of live sliding playlist, media position will be reseted to: ${this.seekAfterBuffered.toFixed(3)}`);
bufferEnd = this.seekAfterBuffered;
}
// if end of buffer greater than live edge, don't load any fragment
// this could happen if live playlist intermittently slides in the past.
// level 1 loaded [182580161,182580167]
// level 1 loaded [182580162,182580169]
// Loading 182580168 of [182580162 ,182580169],level 1 ..
// Loading 182580169 of [182580162 ,182580169],level 1 ..
// level 1 loaded [182580162,182580168] <============= here we should have bufferEnd > end. in that case break to avoid reloading 182580168
// level 1 loaded [182580164,182580171]
//
if (bufferEnd > end) {
break;
}
if (this.startFragRequested && !levelDetails.PTSKnown) {
/* we are switching level on live playlist, but we don't have any PTS info for that quality level ...
try to load frag matching with next SN.
@ -1004,11 +1018,11 @@ _checkBuffer() {
logger.log(`playback not stuck anymore @${currentTime}`);
}
// check buffer upfront
// if less than 200ms is buffered, and media is expected to play but playhead is not moving,
// if less than jumpThreshold second is buffered, and media is expected to play but playhead is not moving,
// and we have a new buffer range available upfront, let's seek to that one
if(bufferInfo.len <= jumpThreshold) {
if(playheadMoving || !expectedPlaying) {
// playhead moving or media not playing
if(expectedPlaying && bufferInfo.len <= jumpThreshold) {
if(playheadMoving) {
// playhead moving
jumpThreshold = 0;
this.seekHoleNudgeDuration = 0;
} else {

View file

@ -45,5 +45,7 @@ export const ErrorDetails = {
// Identifier for a buffer full event
BUFFER_FULL_ERROR: 'bufferFullError',
// Identifier for a buffer seek over hole event
BUFFER_SEEK_OVER_HOLE: 'bufferSeekOverHole'
BUFFER_SEEK_OVER_HOLE: 'bufferSeekOverHole',
// Identifier for an internal exception happening inside hls.js while handling an event
INTERNAL_EXCEPTION: 'internalException'
};

View file

@ -4,7 +4,8 @@
*
*/
//import {logger} from './utils/logger';
import {logger} from './utils/logger';
import {ErrorTypes, ErrorDetails} from './errors';
class EventHandler {
@ -59,7 +60,12 @@ class EventHandler {
}
return this[funcName].bind(this, data);
};
eventToFunction.call(this, event, data).call();
try {
eventToFunction.call(this, event, data).call();
} catch (err) {
logger.error(`internal error happened while processing ${event}:${err.message}`);
this.hls.trigger(Event.ERROR, {type: ErrorTypes.OTHER_ERROR, details: ErrorDetails.INTERNAL_EXCEPTION, fatal: false, event : event, err : err});
}
}
}

View file

@ -44,10 +44,14 @@ class LevelHelper {
if(PTSFrag) {
LevelHelper.updateFragPTS(newDetails,PTSFrag.sn,PTSFrag.startPTS,PTSFrag.endPTS);
} else {
// adjust start by sliding offset
var sliding = oldfragments[delta].start;
for(i = 0 ; i < newfragments.length ; i++) {
newfragments[i].start += sliding;
// ensure that delta is within oldfragments range
// no need to offset start if delta === 0
if (delta > 0 && delta < oldfragments.length) {
// adjust start by sliding offset
var sliding = oldfragments[delta].start;
for(i = 0 ; i < newfragments.length ; i++) {
newfragments[i].start += sliding;
}
}
}
// if we are here, it means we have fragments overlapping between

View file

@ -142,6 +142,7 @@ class Hls {
this.playlistLoader.destroy();
this.fragmentLoader.destroy();
this.levelController.destroy();
this.abrController.destroy();
this.bufferController.destroy();
this.capLevelController.destroy();
this.streamController.destroy();

View file

@ -190,8 +190,8 @@ class MP4Remuxer {
ptsnorm = this._PTSNormalize(pts, nextAvcDts);
dtsnorm = this._PTSNormalize(dts, nextAvcDts);
delta = Math.round((dtsnorm - nextAvcDts) / 90);
// if fragment are contiguous, or delta less than 600ms, ensure there is no overlap/hole between fragments
if (contiguous || Math.abs(delta) < 600) {
// if fragment are contiguous, or if there is a huge delta (more than 10s) between expected PTS and sample PTS
if (contiguous || Math.abs(delta) > 10000) {
if (delta) {
if (delta > 1) {
logger.log(`AVC:${delta} ms hole between fragments detected,filling it`);
@ -314,8 +314,8 @@ class MP4Remuxer {
ptsnorm = this._PTSNormalize(pts, nextAacPts);
dtsnorm = this._PTSNormalize(dts, nextAacPts);
delta = Math.round(1000 * (ptsnorm - nextAacPts) / pesTimeScale);
// if fragment are contiguous, or delta less than 600ms, ensure there is no overlap/hole between fragments
if (contiguous || Math.abs(delta) < 600) {
// if fragment are contiguous, or if there is a huge delta (more than 10s) between expected PTS and sample PTS
if (contiguous || Math.abs(delta) > 10000) {
// log delta
if (delta) {
if (delta > 0) {
@ -327,7 +327,7 @@ class MP4Remuxer {
track.len -= unit.byteLength;
continue;
}
// set DTS to next DTS
// set PTS/DTS to next PTS/DTS
ptsnorm = dtsnorm = nextAacPts;
}
}

View file

@ -29,14 +29,14 @@
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
},
"ignore": [],
"homepage": "https://github.com/PolymerElements/iron-behaviors",
"homepage": "https://github.com/polymerelements/iron-behaviors",
"_release": "1.0.13",
"_resolution": {
"type": "version",
"tag": "v1.0.13",
"commit": "a7bc3428a6da2beed21987b3a8028206826a12bc"
},
"_source": "git://github.com/PolymerElements/iron-behaviors.git",
"_source": "git://github.com/polymerelements/iron-behaviors.git",
"_target": "^1.0.0",
"_originalSource": "PolymerElements/iron-behaviors"
"_originalSource": "polymerelements/iron-behaviors"
}

View file

@ -1,6 +1,6 @@
{
"name": "iron-overlay-behavior",
"version": "1.6.2",
"version": "1.6.3",
"license": "http://polymer.github.io/LICENSE.txt",
"description": "Provides a behavior for making an element an overlay",
"private": true,
@ -35,11 +35,11 @@
},
"ignore": [],
"homepage": "https://github.com/polymerelements/iron-overlay-behavior",
"_release": "1.6.2",
"_release": "1.6.3",
"_resolution": {
"type": "version",
"tag": "v1.6.2",
"commit": "be4e703b6894af6d4013a8a9f514a384ee91e2db"
"tag": "v1.6.3",
"commit": "5b331ebaefe3214937b94ba19769154efee46244"
},
"_source": "git://github.com/polymerelements/iron-overlay-behavior.git",
"_target": "^1.0.0",

View file

@ -1,5 +1,5 @@
language: node_js
sudo: false
sudo: required
before_script:
- npm install -g bower polylint web-component-tester
- bower install
@ -8,18 +8,16 @@ env:
global:
- secure: H8AA9JkWfG/vc3MiimoIoYi45KD10hKzitLJnExkomgzFI/f5o9SGtwjCii5P8Kvf4xndftDjYwRgbYyJpSg0IJeq8rm1WS89cY8O6/1dlI/tK1j5xbVRrhqmRQncxUb3K4MAT6Z9br1jwEeamRa+NKmq+v+VEpQY5vwuQ/BHJw=
- secure: EaE1AUVgWyn0Y6kqkb54z5r39RvTJzAOmeM0lRl7wXzr5k0mq3VGlxTksJqCVd1PdJESXEhy8eldBnlkwZir/imDTNQxKm13k7ZiFC0000XAzpLZElkH2cLlYCRWcuM+vS7dA9hytV0UcGK2VGqbxfpcesB20dPSneDEUuc5X64=
- CXX=g++-4.8
node_js: stable
addons:
firefox: latest
apt:
sources:
- google-chrome
- ubuntu-toolchain-r-test
packages:
- google-chrome-stable
- g++-4.8
sauce_connect: true
script:
- xvfb-run wct
- "if [ \"${TRAVIS_PULL_REQUEST}\" = \"false\" ]; then wct -s 'default'; fi"
dist: trusty

View file

@ -1,6 +1,6 @@
{
"name": "iron-overlay-behavior",
"version": "1.6.2",
"version": "1.6.3",
"license": "http://polymer.github.io/LICENSE.txt",
"description": "Provides a behavior for making an element an overlay",
"private": true,

View file

@ -35,8 +35,8 @@ Custom property | Description | Default
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
width: 100%;
height: 100%;
background-color: var(--iron-overlay-backdrop-background-color, #000);
opacity: 0;
transition: opacity 0.2s;

View file

@ -326,13 +326,13 @@ context. You should place this element as a child of `<body>` whenever possible.
// requestAnimationFrame for non-blocking rendering
if (this.__openChangedAsync) {
cancelAnimationFrame(this.__openChangedAsync);
window.cancelAnimationFrame(this.__openChangedAsync);
}
if (this.opened) {
if (this.withBackdrop) {
this.backdropElement.prepare();
}
this.__openChangedAsync = requestAnimationFrame(function() {
this.__openChangedAsync = window.requestAnimationFrame(function() {
this.__openChangedAsync = null;
this._prepareRenderOpened();
this._renderOpened();
@ -543,11 +543,11 @@ context. You should place this element as a child of `<body>` whenever possible.
*/
_onIronResize: function() {
if (this.__onIronResizeAsync) {
cancelAnimationFrame(this.__onIronResizeAsync);
window.cancelAnimationFrame(this.__onIronResizeAsync);
this.__onIronResizeAsync = null;
}
if (this.opened && !this.__isAnimating) {
this.__onIronResizeAsync = requestAnimationFrame(function() {
this.__onIronResizeAsync = window.requestAnimationFrame(function() {
this.__onIronResizeAsync = null;
this.refit();
}.bind(this));

View file

@ -52,7 +52,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
/**
* The shared backdrop element.
* @type {Element} backdropElement
* @type {!Element} backdropElement
*/
get backdropElement() {
if (!this._backdropElement) {
@ -63,7 +63,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
/**
* The deepest active element.
* @type {Element} activeElement the active element
* @type {!Element} activeElement the active element
*/
get deepActiveElement() {
// document.activeElement can be null
@ -83,13 +83,17 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
*/
_bringOverlayAtIndexToFront: function(i) {
var overlay = this._overlays[i];
if (!overlay) {
return;
}
var lastI = this._overlays.length - 1;
var currentOverlay = this._overlays[lastI];
// Ensure always-on-top overlay stays on top.
if (!overlay.alwaysOnTop && this._overlays[lastI].alwaysOnTop) {
if (currentOverlay && this._shouldBeBehindOverlay(overlay, currentOverlay)) {
lastI--;
}
// If already the top element, return.
if (!overlay || i >= lastI) {
if (i >= lastI) {
return;
}
// Update z-index to be on top.
@ -109,7 +113,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
/**
* Adds the overlay and updates its z-index if it's opened, or removes it if it's closed.
* Also updates the backdrop z-index.
* @param {Element} overlay
* @param {!Element} overlay
*/
addOrRemoveOverlay: function(overlay) {
if (overlay.opened) {
@ -123,7 +127,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
/**
* Tracks overlays for z-index and focus management.
* Ensures the last added overlay with always-on-top remains on top.
* @param {Element} overlay
* @param {!Element} overlay
*/
addOverlay: function(overlay) {
var i = this._overlays.indexOf(overlay);
@ -137,7 +141,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
var newZ = this._getZ(overlay);
// Ensure always-on-top overlay stays on top.
if (currentOverlay && currentOverlay.alwaysOnTop && !overlay.alwaysOnTop) {
if (currentOverlay && this._shouldBeBehindOverlay(overlay, currentOverlay)) {
// This bumps the z-index of +2.
this._applyOverlayZ(currentOverlay, minimumZ);
insertionIndex--;
@ -158,7 +162,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
},
/**
* @param {Element} overlay
* @param {!Element} overlay
*/
removeOverlay: function(overlay) {
var i = this._overlays.indexOf(overlay);
@ -276,7 +280,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
},
/**
* @param {Element} element
* @param {!Element} element
* @param {number|string} z
* @private
*/
@ -285,7 +289,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
},
/**
* @param {Element} overlay
* @param {!Element} overlay
* @param {number} aboveZ
* @private
*/
@ -365,6 +369,19 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
overlay._onCaptureTab(event);
}
}
},
/**
* Returns if the overlay1 should be behind overlay2.
* @param {!Element} overlay1
* @param {!Element} overlay2
* @return {boolean}
* @private
*/
_shouldBeBehindOverlay: function(overlay1, overlay2) {
var o1 = /** @type {?} */ (overlay1);
var o2 = /** @type {?} */ (overlay2);
return !o1.alwaysOnTop && o2.alwaysOnTop;
}
};

View file

@ -22,10 +22,10 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<script>
WCT.loadSuites([
'iron-overlay-behavior.html',
'iron-overlay-behavior.html?dom=shadow'
'iron-overlay-behavior.html?dom=shadow',
'iron-overlay-backdrop.html',
'iron-overlay-backdrop.html?dom=shadow',
]);
</script>
</body></html>

View file

@ -0,0 +1,94 @@
<!doctype html>
<!--
@license
Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<html>
<head>
<title>iron-overlay-backdrop tests</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
<script src="../../webcomponentsjs/webcomponents-lite.js"></script>
<script src="../../web-component-tester/browser.js"></script>
<link rel="import" href="../../iron-test-helpers/iron-test-helpers.html">
<link rel="import" href="test-overlay.html">
<style>
html,
body {
margin: 0;
width: 100%;
height: 100%;
min-width: 0;
}
.sizer {
width: 4000px;
height: 5000px;
}
</style>
<style is="custom-style">
iron-overlay-backdrop {
/* For quicker tests */
--iron-overlay-backdrop: {
transition: none;
}
}
</style>
</head>
<body>
<div class="sizer"></div>
<test-fixture id="backdrop">
<template>
<test-overlay with-backdrop>
Overlay with backdrop
</test-overlay>
</template>
</test-fixture>
<script>
function runAfterOpen(overlay, callback) {
overlay.addEventListener('iron-overlay-opened', callback);
overlay.open();
}
suite('overlay with backdrop', function() {
var overlay;
setup(function() {
overlay = fixture('backdrop');
});
test('backdrop size matches parent size', function(done) {
runAfterOpen(overlay, function() {
Polymer.Base.async(function() {
var backdrop = overlay.backdropElement;
var parent = backdrop.parentElement;
assert.strictEqual(backdrop.offsetWidth, parent.clientWidth, 'backdrop width matches parent width');
assert.strictEqual(backdrop.offsetHeight, parent.clientHeight, 'backdrop height matches parent height');
done();
}, 1);
});
});
});
</script>
</body>
</html>

View file

@ -26,14 +26,14 @@
"web-component-tester": "*"
},
"private": true,
"homepage": "https://github.com/Polymer/polymer",
"homepage": "https://github.com/polymer/polymer",
"_release": "1.4.0",
"_resolution": {
"type": "version",
"tag": "v1.4.0",
"commit": "11c987b2eb3c73b388a79fc8aaea8ca01624f514"
},
"_source": "git://github.com/Polymer/polymer.git",
"_source": "git://github.com/polymer/polymer.git",
"_target": "^1.0.0",
"_originalSource": "Polymer/polymer"
"_originalSource": "polymer/polymer"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -510,7 +510,7 @@ body:not(.dashboardDocument) .btnNotifications {
}
.adminDrawerPanel .sidebarLink.selectedSidebarLink {
background: #66BB6A !important;
background: #52B54B !important;
color: #fff !important;
}

View file

@ -23,7 +23,7 @@
}
.levelNormal {
background-color: #4d90fe;
background-color: #444;
}
.levelWarning {

View file

@ -1,4 +1,4 @@
<div id="devicesUploadPage" data-role="page" class="page type-interior devicesPage withTabs" data-helpurl="https://github.com/MediaBrowser/Wiki/wiki/Camera%20upload" data-require="scripts/devicesupload,paper-input,jqmcheckbox">
<div id="devicesUploadPage" data-role="page" class="page type-interior devicesPage withTabs" data-helpurl="https://github.com/MediaBrowser/Wiki/wiki/Camera%20upload" data-require="scripts/devicesupload,paper-input,paper-checkbox">
<div data-role="content">
<div class="content-primary">
@ -24,9 +24,9 @@
<div class="fieldDescription">${LabelCameraUploadPathHelp}</div>
</li>
<li>
<label for="chkSubfolder">${LabelCreateCameraUploadSubfolder}</label>
<input type="checkbox" id="chkSubfolder" data-mini="true" />
<div class="fieldDescription">${LabelCreateCameraUploadSubfolderHelp}</div>
<br />
<paper-checkbox id="chkSubfolder">${LabelCreateCameraUploadSubfolder}</paper-checkbox>
<div class="fieldDescription paperCheckboxFieldDescription">${LabelCreateCameraUploadSubfolderHelp}</div>
</li>
</ul><br />

View file

@ -1,20 +1,20 @@
<div id="metadataImagesConfigurationPage" data-role="page" class="page type-interior metadataConfigurationPage withTabs" data-require="emby-collapsible,scripts/metadataimagespage,jqmcheckbox,paper-checkbox,paper-input">
<div id="metadataImagesConfigurationPage" data-role="page" class="page type-interior metadataConfigurationPage withTabs" data-require="emby-collapsible,scripts/metadataimagespage,paper-checkbox,paper-input,paper-fab,paper-icon-item,paper-item-body">
<div data-role="content">
<div class="content-primary">
<div class="tabContent">
<form class="metadataImagesConfigurationForm" style="max-width: 800px;">
<div style="width: 75%;">
<form class="metadataImagesConfigurationForm">
<div>
<label for="selectItemType" class="selectLabel">${LabelCustomizeOptionsPerMediaType}</label>
<select id="selectItemType" data-mini="true"></select>
</div>
<br />
<br />
<div class="metadataReaders" style="margin-bottom: 2em; width: 75%;">
<div class="metadataReaders" style="margin-bottom: 2em;">
</div>
<div class="metadataSavers" style="margin-bottom: 2em; width: 75%;">
<div class="metadataSavers" style="margin-bottom: 2em;">
</div>
<div class="metadataFetchers" style="margin-bottom: 2em;">
</div>

View file

@ -1,21 +1,20 @@
<div id="notificationSettingPage" data-role="page" class="page type-interior notificationConfigurationPage withTabs" data-helpurl="https://github.com/MediaBrowser/Wiki/wiki/Notifications" data-require="scripts/notificationsetting,paper-input,jqmcheckbox">
<div id="notificationSettingPage" data-role="page" class="page type-interior notificationConfigurationPage withTabs" data-helpurl="https://github.com/MediaBrowser/Wiki/wiki/Notifications" data-require="scripts/notificationsetting,paper-input,paper-checkbox">
<div data-role="content">
<div class="content-primary">
<h2 class="notificationType" style="margin-bottom: 0;"></h2>
<h1 class="notificationType" style="margin-top:0;"></h1>
<form class="notificationSettingForm">
<ul data-role="listview" class="ulForm">
<li>
<input type="checkbox" id="chkEnabled" data-mini="true" />
<label for="chkEnabled">${LabelNotificationEnabled}</label>
<paper-checkbox id="chkEnabled">${LabelNotificationEnabled}</paper-checkbox>
</li>
</ul>
<div class="monitorUsers" style="display: none;">
<label>${LabelMonitorUsers}</label>
<div class="paperCheckboxListLabel">${LabelMonitorUsers}</div>
<div class="monitorUsersList">
</div>
<br />

View file

@ -12,7 +12,7 @@
$('#txtUploadPath', page).val(config.CameraUploadPath || '');
$('#chkSubfolder', page).checked(config.EnableCameraUploadSubfolders).checkboxradio('refresh');
$('#chkSubfolder', page).checked(config.EnableCameraUploadSubfolders);
loadDeviceList(page, devices, config);
}
@ -21,32 +21,27 @@
var html = '';
html += '<fieldset data-role="controlgroup">';
html += '<legend>';
html += '<div class="paperCheckboxListLabel">';
html += Globalize.translate('LabelEnableCameraUploadFor');
html += '</legend>';
html += '</div>';
html += '<div class="paperCheckboxList paperList">';
var index = 0;
html += devices.map(function (d) {
var deviceHtml = '';
var id = "chk" + index;
deviceHtml += '<label for="' + id + '">';
deviceHtml += d.Name;
if (d.AppName) {
deviceHtml += '<br/><span>' + d.AppName + '</span>';
}
deviceHtml += '</label>';
var isChecked = config.EnabledCameraUploadDevices.indexOf(d.Id) != -1;
var checkedHtml = isChecked ? ' checked="checked"' : '';
deviceHtml += '<input type="checkbox" id="' + id + '" class="chkDevice" data-id="' + d.Id + '"' + checkedHtml + ' />';
var label = d.Name;
if (d.AppName) {
label += ' - ' + d.AppName;
}
deviceHtml += '<paper-checkbox class="chkDevice" data-id="' + d.Id + '"' + checkedHtml + '>' + label + '</paper-checkbox>';
index++;
@ -54,7 +49,7 @@
}).join('');
html += '</fieldset>';
html += '</div>';
html += '<div class="fieldDescription">';
html += Globalize.translate('LabelEnableCameraUploadForHelp');
@ -89,7 +84,11 @@
config.CameraUploadPath = $('#txtUploadPath', page).val();
config.EnabledCameraUploadDevices = $('.chkDevice:checked', page).get().map(function (c) {
config.EnabledCameraUploadDevices = $('.chkDevice', page).get().filter(function (c) {
return c.checked;
}).map(function (c) {
return c.getAttribute('data-id');

View file

@ -65,10 +65,6 @@
htmlName += name;
if (!item.LocalTrailerCount && item.Type == "Movie") {
htmlName += '<img src="css/images/editor/missingtrailer.png" title="' + Globalize.translate('MissingLocalTrailer') + '" />';
}
if (!item.ImageTags || !item.ImageTags.Primary) {
htmlName += '<img src="css/images/editor/missingprimaryimage.png" title="' + Globalize.translate('MissingPrimaryImage') + '" />';
}

View file

@ -1101,6 +1101,10 @@
return 'photos.html?topParentId=' + item.Id;
}
}
else if (item.IsFolder) {
return id ? "itemlist.html?parentId=" + id : "#";
}
if (item.Type == 'CollectionFolder') {
return 'itemlist.html?topParentId=' + item.Id + '&parentId=' + item.Id;
}

View file

@ -1134,7 +1134,6 @@
});
Events.on(ConnectionManager, 'localusersignedin', function (e, user) {
requiresDrawerRefresh = true;
setDrawerClass();
var apiClient = ConnectionManager.getApiClient(user.ServerId);
ConnectionManager.user(ConnectionManager.getApiClient(user.ServerId)).then(function (user) {
@ -1149,14 +1148,8 @@
}
});
Events.on(ConnectionManager, 'localusersignedout', function () {
requiresDrawerRefresh = true;
updateUserInHeader();
});
Events.on(MediaController, 'playerchange', function () {
updateCastIcon();
});
Events.on(ConnectionManager, 'localusersignedout', updateUserInHeader);
Events.on(MediaController, 'playerchange', updateCastIcon);
setDrawerClass();

View file

@ -144,80 +144,66 @@
var html = '';
if (!plugins.length) {
$('.imageFetchers', page).html(html).hide().trigger('create');
$('.imageFetchers', page).html(html).hide();
return;
}
var i, length, plugin, id;
html += '<div class="ui-controlgroup-label" style="margin-bottom:0;padding-left:2px;">' + Globalize.translate('LabelImageFetchers') + '</div>';
html += '<div style="display:inline-block;width: 75%;vertical-align:top;">';
html += '<div data-role="controlgroup" class="imageFetcherGroup">';
html += '<div class="paperCheckboxListLabel">' + Globalize.translate('LabelImageFetchers') + '</div>';
html += '<div class="paperList">';
for (i = 0, length = plugins.length; i < length; i++) {
plugin = plugins[i];
id = 'chkImageFetcher' + i;
var isChecked = config.DisabledImageFetchers.indexOf(plugin.Name) == -1 ? ' checked="checked"' : '';
html += '<input class="chkImageFetcher" type="checkbox" name="' + id + '" id="' + id + '" data-pluginname="' + plugin.Name + '" data-mini="true"' + isChecked + '>';
html += '<label for="' + id + '">' + plugin.Name + '</label>';
html += '<paper-icon-item class="imageFetcherItem" data-pluginname="' + plugin.Name + '">';
html += '<paper-checkbox class="chkImageFetcher" data-pluginname="' + plugin.Name + '" item-icon' + isChecked + '></paper-checkbox>';
html += '<paper-item-body>';
html += '<div>';
html += plugin.Name;
html += '</div>';
html += '</paper-item-body>';
html += '<paper-icon-button class="btnUp" icon="keyboard-arrow-up" title="' + Globalize.translate('ButtonUp') + '" style="padding:3px 8px;"></paper-icon-button>';
html += '<paper-icon-button class="btnDown" icon="keyboard-arrow-down" title="' + Globalize.translate('ButtonDown') + '" style="padding:3px 8px;"></paper-icon-button>';
html += '</paper-icon-item>';
}
html += '</div>';
html += '</div>';
html += '<div class="fieldDescription">' + Globalize.translate('LabelImageFetchersHelp') + '</div>';
if (plugins.length > 1) {
html += '<div style="display:inline-block;vertical-align:top;margin-left:5px;">';
for (i = 0, length = plugins.length; i < length; i++) {
html += '<div>';
if (i > 0) {
html += '<paper-icon-button class="btnUp" data-pluginindex="' + i + '" icon="keyboard-arrow-up" title="' + Globalize.translate('ButtonUp') + '" style="padding:3px 8px;"></paper-icon-button>';
} else {
html += '<paper-icon-button disabled class="btnUp" data-pluginindex="' + i + '" icon="keyboard-arrow-up" title="' + Globalize.translate('ButtonUp') + '" style="padding:3px 8px;"></paper-icon-button>';
}
if (i < (plugins.length - 1)) {
html += '<paper-icon-button class="btnDown" data-pluginindex="' + i + '" icon="keyboard-arrow-down" title="' + Globalize.translate('ButtonDown') + '" style="padding:3px 8px;"></paper-icon-button>';
} else {
html += '<paper-icon-button disabled class="btnDown" data-pluginindex="' + i + '" icon="keyboard-arrow-down" title="' + Globalize.translate('ButtonDown') + '" style="padding:3px 8px;"></paper-icon-button>';
}
html += '</div>';
}
}
html += '</div>';
html += '<div class="fieldDescription" style="width:75%;">' + Globalize.translate('LabelImageFetchersHelp') + '</div>';
var elem = $('.imageFetchers', page).html(html).show().trigger('create');
var elem = $('.imageFetchers', page).html(html).show();
$('.btnDown', elem).on('click', function () {
var index = parseInt(this.getAttribute('data-pluginindex'));
var elemToMove = $('.imageFetcherGroup .ui-checkbox', page)[index];
var elemToMove = $(this).parents('.imageFetcherItem')[0];
var insertAfter = $(elemToMove).next('.ui-checkbox')[0];
var insertAfter = $(elemToMove).next('.imageFetcherItem')[0];
elemToMove.parentNode.removeChild(elemToMove);
$(elemToMove).insertAfter(insertAfter);
if (insertAfter) {
elemToMove.parentNode.removeChild(elemToMove);
$(elemToMove).insertAfter(insertAfter);
}
});
$('.btnUp', elem).on('click', function () {
var index = parseInt(this.getAttribute('data-pluginindex'));
var elemToMove = $(this).parents('.imageFetcherItem')[0];
var elemToMove = $('.imageFetcherGroup .ui-checkbox', page)[index];
var insertBefore = $(elemToMove).prev('.imageFetcherItem')[0];
var insertBefore = $(elemToMove).prev('.ui-checkbox')[0];
elemToMove.parentNode.removeChild(elemToMove);
$(elemToMove).insertBefore(insertBefore);
if (insertBefore) {
elemToMove.parentNode.removeChild(elemToMove);
$(elemToMove).insertBefore(insertBefore);
}
});
}
@ -230,12 +216,12 @@
var html = '';
if (!plugins.length) {
$('.metadataSavers', page).html(html).hide().trigger('create');
$('.metadataSavers', page).html(html).hide();
return;
}
html += '<div class="paperCheckboxListLabel">' + Globalize.translate('LabelMetadataSavers') + '</div>';
html += '<div class="paperCheckboxList">';
html += '<div class="paperCheckboxList paperList">';
for (var i = 0, length = plugins.length; i < length; i++) {
@ -261,80 +247,66 @@
var html = '';
if (!plugins.length) {
$('.metadataFetchers', page).html(html).hide().trigger('create');
$('.metadataFetchers', page).html(html).hide();
return;
}
var i, length, plugin, id;
var i, length, plugin;
html += '<div class="ui-controlgroup-label" style="margin-bottom:0;padding-left:2px;">' + Globalize.translate('LabelMetadataDownloaders') + '</div>';
html += '<div style="display:inline-block;width: 75%;vertical-align:top;">';
html += '<div data-role="controlgroup" class="metadataFetcherGroup">';
html += '<div class="paperCheckboxListLabel">' + Globalize.translate('LabelMetadataDownloaders') + '</div>';
html += '<div class="paperList">';
for (i = 0, length = plugins.length; i < length; i++) {
plugin = plugins[i];
id = 'chkMetadataFetcher' + i;
var isChecked = config.DisabledMetadataFetchers.indexOf(plugin.Name) == -1 ? ' checked="checked"' : '';
html += '<input class="chkMetadataFetcher" type="checkbox" name="' + id + '" id="' + id + '" data-pluginname="' + plugin.Name + '" data-mini="true"' + isChecked + '>';
html += '<label for="' + id + '">' + plugin.Name + '</label>';
html += '<paper-icon-item class="metadataFetcherItem" data-pluginname="' + plugin.Name + '">';
html += '<paper-checkbox class="chkMetadataFetcher" data-pluginname="' + plugin.Name + '" item-icon' + isChecked + '></paper-checkbox>';
html += '<paper-item-body>';
html += '<div>';
html += plugin.Name;
html += '</div>';
html += '</paper-item-body>';
html += '<paper-icon-button class="btnUp" icon="keyboard-arrow-up" title="' + Globalize.translate('ButtonUp') + '" style="padding:3px 8px;"></paper-icon-button>';
html += '<paper-icon-button class="btnDown" icon="keyboard-arrow-down" title="' + Globalize.translate('ButtonDown') + '" style="padding:3px 8px;"></paper-icon-button>';
html += '</paper-icon-item>';
}
html += '</div>';
html += '</div>';
html += '<div class="fieldDescription">' + Globalize.translate('LabelMetadataDownloadersHelp') + '</div>';
if (plugins.length > 1) {
html += '<div style="display:inline-block;vertical-align:top;margin-left:5px;">';
for (i = 0, length = plugins.length; i < length; i++) {
html += '<div>';
if (i > 0) {
html += '<paper-icon-button class="btnUp" data-pluginindex="' + i + '" icon="keyboard-arrow-up" title="' + Globalize.translate('ButtonUp') + '" style="padding:3px 8px;"></paper-icon-button>';
} else {
html += '<paper-icon-button disabled class="btnUp" data-pluginindex="' + i + '" icon="keyboard-arrow-up" title="' + Globalize.translate('ButtonUp') + '" style="padding:3px 8px;"></paper-icon-button>';
}
if (i < (plugins.length - 1)) {
html += '<paper-icon-button class="btnDown" data-pluginindex="' + i + '" icon="keyboard-arrow-down" title="' + Globalize.translate('ButtonDown') + '" style="padding:3px 8px;"></paper-icon-button>';
} else {
html += '<paper-icon-button disabled class="btnDown" data-pluginindex="' + i + '" icon="keyboard-arrow-down" title="' + Globalize.translate('ButtonDown') + '" style="padding:3px 8px;"></paper-icon-button>';
}
html += '</div>';
}
}
html += '</div>';
html += '<div class="fieldDescription" style="width:75%;">' + Globalize.translate('LabelMetadataDownloadersHelp') + '</div>';
var elem = $('.metadataFetchers', page).html(html).show().trigger('create');
var elem = $('.metadataFetchers', page).html(html).show();
$('.btnDown', elem).on('click', function () {
var index = parseInt(this.getAttribute('data-pluginindex'));
var elemToMove = $('.metadataFetcherGroup .ui-checkbox', page)[index];
var elemToMove = $(this).parents('.metadataFetcherItem')[0];
var insertAfter = $(elemToMove).next('.ui-checkbox')[0];
var insertAfter = $(elemToMove).next('.metadataFetcherItem')[0];
elemToMove.parentNode.removeChild(elemToMove);
$(elemToMove).insertAfter(insertAfter);
if (insertAfter) {
elemToMove.parentNode.removeChild(elemToMove);
$(elemToMove).insertAfter(insertAfter);
}
});
$('.btnUp', elem).on('click', function () {
var index = parseInt(this.getAttribute('data-pluginindex'));
var elemToMove = $(this).parents('.metadataFetcherItem')[0];
var elemToMove = $('.metadataFetcherGroup .ui-checkbox', page)[index];
var insertBefore = $(elemToMove).prev('.metadataFetcherItem')[0];
var insertBefore = $(elemToMove).prev('.ui-checkbox')[0];
elemToMove.parentNode.removeChild(elemToMove);
$(elemToMove).insertBefore(insertBefore);
if (insertBefore) {
elemToMove.parentNode.removeChild(elemToMove);
$(elemToMove).insertBefore(insertBefore);
}
});
}
@ -347,42 +319,44 @@
var html = '';
if (plugins.length < 2) {
$('.metadataReaders', page).html(html).hide().trigger('create');
$('.metadataReaders', page).html(html).hide();
return;
}
html += '<div class="ui-controlgroup-label" style="margin-bottom:0;padding-left:2px;">' + Globalize.translate('LabelMetadataReaders') + '</div>';
html += '<ul data-role="listview" data-inset="true" data-mini="true" style="margin-top:.5em;margin-bottom:.5em;">';
html += '<div class="paperCheckboxListLabel">' + Globalize.translate('LabelMetadataReaders') + '</div>';
html += '<div class="paperList">';
for (var i = 0, length = plugins.length; i < length; i++) {
var plugin = plugins[i];
html += '<li data-mini="true" class="localReaderOption" data-pluginname="' + plugin.Name + '">';
html += '<paper-icon-item class="localReaderOption" data-pluginname="' + plugin.Name + '">';
html += '<paper-fab mini style="background:#52B54B;" icon="live-tv" item-icon></paper-fab>';
html += '<paper-item-body>';
html += '<div>';
html += plugin.Name;
html += '</div>';
html += '</paper-item-body>';
if (i > 0) {
html += '<a href="#" style="font-weight:normal;">' + plugin.Name + '</a>';
html += '<a class="btnLocalReaderUp btnLocalReaderMove" data-pluginindex="' + i + '" href="#" style="font-weight:normal;" data-icon="arrow-u">' + Globalize.translate('ButtonUp') + '</a>';
html += '<paper-icon-button title="' + Globalize.translate('ButtonUp') + '" icon="keyboard-arrow-up" class="btnLocalReaderUp btnLocalReaderMove" data-pluginindex="' + i + '"></paper-icon-button>';
}
else if (plugins.length > 1) {
html += '<a href="#" style="font-weight:normal;">' + plugin.Name + '</a>';
html += '<a class="btnLocalReaderDown btnLocalReaderMove" data-pluginindex="' + i + '" href="#" style="font-weight:normal;" data-icon="arrow-d">' + Globalize.translate('ButtonDown') + '</a>';
html += '<paper-icon-button title="' + Globalize.translate('ButtonDown') + '" icon="keyboard-arrow-down" class="btnLocalReaderDown btnLocalReaderMove" data-pluginindex="' + i + '"></paper-icon-button>';
}
else {
html += plugin.Name;
}
html += '</li>';
html += '</paper-icon-item>';
}
html += '</ul>';
html += '</div>';
html += '<div class="fieldDescription">' + Globalize.translate('LabelMetadataReadersHelp') + '</div>';
$('.metadataReaders', page).html(html).show().trigger('create');
$('.metadataReaders', page).html(html).show();
}
function loadPage(page) {
@ -429,7 +403,9 @@
});
config.DisabledMetadataFetchers = $('.chkMetadataFetcher:not(:checked)', form).get().map(function (c) {
config.DisabledMetadataFetchers = $('.chkMetadataFetcher', form).get().filter(function (c) {
return !c.checked;
}).map(function (c) {
return c.getAttribute('data-pluginname');
@ -441,7 +417,9 @@
});
config.DisabledImageFetchers = $('.chkImageFetcher:not(:checked)', form).get().map(function (c) {
config.DisabledImageFetchers = $('.chkImageFetcher', form).get().filter(function (c) {
return !c.checked;
}).map(function (c) {
return c.getAttribute('data-pluginname');
@ -536,7 +514,7 @@
$('.metadataReaders', page).on('click', '.btnLocalReaderMove', function () {
var li = $(this).parents('.localReaderOption');
var ul = li.parents('ul');
var list = li.parents('.paperList');
if ($(this).hasClass('btnLocalReaderDown')) {
@ -551,12 +529,12 @@
li.remove().insertBefore(prev);
}
$('.localReaderOption', ul).each(function () {
$('.localReaderOption', list).each(function () {
if ($(this).prev('.localReaderOption').length) {
$('.btnLocalReaderMove', this).addClass('btnLocalReaderUp').removeClass('btnLocalReaderDown').attr('data-icon', 'arrow-u').removeClass('ui-icon-arrow-d').addClass('ui-icon-arrow-u');
$('.btnLocalReaderMove', this).addClass('btnLocalReaderUp').removeClass('btnLocalReaderDown').attr('icon', 'keyboard-arrow-up');
} else {
$('.btnLocalReaderMove', this).addClass('btnLocalReaderDown').removeClass('btnLocalReaderUp').attr('data-icon', 'arrow-d').removeClass('ui-icon-arrow-u').addClass('ui-icon-arrow-d');
$('.btnLocalReaderMove', this).addClass('btnLocalReaderDown').removeClass('btnLocalReaderUp').attr('icon', 'keyboard-arrow-down');
}
});

View file

@ -67,7 +67,7 @@
html = LibraryBrowser.getPosterViewHtml({
items: result.Items,
shape: "square",
context: 'music',
context: 'folders',
showTitle: true,
showParentTitle: true,
lazy: true,

View file

@ -4,17 +4,15 @@
function fillItems(elem, items, cssClass, idPrefix, currentList, isEnabledList) {
var html = '<div data-role="controlgroup">';
var html = '<div class="paperCheckboxList paperList" style="padding: .5em 1em;">';
html += items.map(function (u) {
var id = idPrefix + u.Id;
var isChecked = isEnabledList ? currentList.indexOf(u.Id) != -1 : currentList.indexOf(u.Id) == -1;
var checkedHtml = isChecked ? ' checked="checked"' : '';
return '<label for="' + id + '">' + u.Name + '</label><input class="' + cssClass + '" type="checkbox" data-itemid="' + u.Id + '" id="' + id + '"' + checkedHtml + ' />';
return '<paper-checkbox class="' + cssClass + '" type="checkbox" data-itemid="' + u.Id + '"' + checkedHtml + '>' + u.Name + '</paper-checkbox>';
}).join('');
@ -86,7 +84,7 @@
fillItems($('.sendToUsersList', page), users, 'chkSendTo', 'chkSendTo', notificationConfig.SendToUsers, true);
fillItems($('.servicesList', page), services, 'chkService', 'chkService', notificationConfig.DisabledServices);
$('#chkEnabled', page).checked(notificationConfig.Enabled || false).checkboxradio('refresh');
$('#chkEnabled', page).checked(notificationConfig.Enabled || false);
$('#txtTitle', page).val(notificationConfig.Title || typeInfo.DefaultTitle);
@ -135,15 +133,21 @@
notificationConfig.Title = null;
}
notificationConfig.DisabledMonitorUsers = $('.chkMonitor:not(:checked)', page).get().map(function (c) {
notificationConfig.DisabledMonitorUsers = $('.chkMonitor', page).get().filter(function (c) {
return !c.checked;
}).map(function (c) {
return c.getAttribute('data-itemid');
});
notificationConfig.SendToUsers = $('.chkSendTo:checked', page).get().map(function (c) {
notificationConfig.SendToUsers = $('.chkSendTo', page).get().filter(function (c) {
return c.checked;
}).map(function (c) {
return c.getAttribute('data-itemid');
});
notificationConfig.DisabledServices = $('.chkService:not(:checked)', page).get().map(function (c) {
notificationConfig.DisabledServices = $('.chkService', page).get().filter(function (c) {
return !c.checked;
}).map(function (c) {
return c.getAttribute('data-itemid');
});

View file

@ -743,7 +743,7 @@ var Dashboard = {
divider: true,
name: Globalize.translate('TabLibrary'),
href: "library.html",
pageIds: ['mediaLibraryPage', 'libraryPathMappingPage'],
pageIds: ['mediaLibraryPage', 'libraryPathMappingPage', 'librarySettingsPage'],
icon: 'folder',
color: '#009688'
}, {

View file

@ -82,13 +82,12 @@
return new Promise(function (resolve, reject) {
require(['paper-checkbox', 'paper-input', 'emby-collapsible'], function () {
renderFormInternal(options);
resolve();
renderFormInternal(options, resolve);
});
});
}
function renderFormInternal(options) {
function renderFormInternal(options, resolve) {
var elem = options.elem;
var dialogOptions = options.dialogOptions;
@ -189,7 +188,7 @@
$('#selectSyncTarget', elem).on('change', function () {
loadQualityOptions(elem, this.value, options.dialogOptionsFn);
loadQualityOptions(elem, this.value, options.dialogOptionsFn).then(resolve);
}).trigger('change');
@ -319,12 +318,14 @@
return o.Id == profileId;
})[0];
var qualityOptions = options.QualityOptions || [];
if (option) {
$('.profileDescription', form).html(option.Description || '');
setQualityFieldVisible(form, options.QualityOptions.length > 0 && option.EnableQualityOptions && options.Options.indexOf('Quality') != -1);
setQualityFieldVisible(form, qualityOptions.length > 0 && option.EnableQualityOptions && options.Options.indexOf('Quality') != -1);
} else {
$('.profileDescription', form).html('');
setQualityFieldVisible(form, options.QualityOptions.length > 0 && options.Options.indexOf('Quality') != -1);
setQualityFieldVisible(form, qualityOptions.length > 0 && options.Options.indexOf('Quality') != -1);
}
}
@ -381,9 +382,9 @@
function loadQualityOptions(form, targetId, dialogOptionsFn) {
dialogOptionsFn(targetId).then(function (options) {
return dialogOptionsFn(targetId).then(function (options) {
renderTargetDialogOptions(form, options);
return renderTargetDialogOptions(form, options);
});
}

View file

@ -412,7 +412,9 @@
}).on('pageshow', ".syncActivityPage", function () {
LibraryMenu.setTabs('syncadmin', 0, getTabs);
if (this.id == 'syncActivityPage') {
LibraryMenu.setTabs('syncadmin', 0, getTabs);
}
var page = this;
Dashboard.getPluginSecurityInfo().then(function (pluginSecurityInfo) {

View file

@ -1,4 +1,4 @@
define(['jQuery'], function ($) {
define(['jQuery', 'paper-progress', 'paper-fab', 'paper-item-body', 'paper-icon-item', 'paper-icon-button'], function ($) {
function renderJob(page, job, dialogOptions) {
@ -335,7 +335,7 @@
function loadJobInfo(page, job, jobItems) {
renderJob(page, job, _jobOptions);
//renderJob(page, job, _jobOptions);
renderJobItems(page, jobItems);
Dashboard.hideLoadingMsg();
}

View file

@ -4,52 +4,46 @@
var html = '';
html += '<fieldset data-role="controlgroup">';
html += '<div class="paperCheckboxListLabel">' + Globalize.translate('HeaderLibraries') + '</div>';
html += '<legend>' + Globalize.translate('HeaderLibraries') + '</legend>';
html += '<div class="paperCheckboxList paperList">';
for (var i = 0, length = mediaFolders.length; i < length; i++) {
var folder = mediaFolders[i];
var id = 'mediaFolder' + i;
var isChecked = user.Policy.EnableAllFolders || user.Policy.EnabledFolders.indexOf(folder.Id) != -1;
var checkedAttribute = isChecked ? ' checked="checked"' : '';
html += '<input class="chkFolder" data-id="' + folder.Id + '" type="checkbox" id="' + id + '"' + checkedAttribute + ' />';
html += '<label for="' + id + '">' + folder.Name + '</label>';
html += '<paper-checkbox class="chkFolder" data-id="' + folder.Id + '" type="checkbox"' + checkedAttribute + '>' + folder.Name + '</paper-checkbox>';
}
html += '</fieldset>';
html += '</div>';
$('.folderAccess', page).html(html).trigger('create');
$('#chkEnableAllFolders', page).checked(user.Policy.EnableAllFolders).checkboxradio('refresh').trigger('change');
$('#chkEnableAllFolders', page).checked(user.Policy.EnableAllFolders).trigger('change');
}
function loadChannels(page, user, channels) {
var html = '';
html += '<fieldset data-role="controlgroup">';
html += '<div class="paperCheckboxListLabel">' + Globalize.translate('HeaderChannels') + '</div>';
html += '<legend>' + Globalize.translate('HeaderChannels') + '</legend>';
html += '<div class="paperCheckboxList paperList">';
for (var i = 0, length = channels.length; i < length; i++) {
var folder = channels[i];
var id = 'channels' + i;
var isChecked = user.Policy.EnableAllChannels || user.Policy.EnabledChannels.indexOf(folder.Id) != -1;
var checkedAttribute = isChecked ? ' checked="checked"' : '';
html += '<input class="chkChannel" data-id="' + folder.Id + '" type="checkbox" id="' + id + '"' + checkedAttribute + ' />';
html += '<label for="' + id + '">' + folder.Name + '</label>';
html += '<paper-checkbox class="chkChannel" data-id="' + folder.Id + '" type="checkbox"' + checkedAttribute + '>' + folder.Name + '</paper-checkbox>';
}
html += '</fieldset>';
html += '</div>';
$('.channelAccess', page).show().html(html).trigger('create');
@ -59,37 +53,31 @@
$('.channelAccessContainer', page).hide();
}
$('#chkEnableAllChannels', page).checked(user.Policy.EnableAllChannels).checkboxradio('refresh').trigger('change');
$('#chkEnableAllChannels', page).checked(user.Policy.EnableAllChannels).trigger('change');
}
function loadDevices(page, user, devices) {
var html = '';
html += '<fieldset data-role="controlgroup">';
html += '<div class="paperCheckboxListLabel">' + Globalize.translate('HeaderDevices') + '</div>';
html += '<legend>' + Globalize.translate('HeaderDevices') + '</legend>';
html += '<div class="paperCheckboxList paperList">';
for (var i = 0, length = devices.length; i < length; i++) {
var device = devices[i];
var id = 'device' + i;
var checkedAttribute = user.Policy.EnableAllDevices || user.Policy.EnabledDevices.indexOf(device.Id) != -1 ? ' checked="checked"' : '';
html += '<input class="chkDevice" data-id="' + device.Id + '" type="checkbox" id="' + id + '"' + checkedAttribute + ' />';
html += '<label for="' + id + '">' + device.Name;
html += '<br/><span>' + device.AppName + '</span>';
html += '</label>';
html += '<paper-checkbox class="chkChannel" data-id="' + device.Id + '" type="checkbox"' + checkedAttribute + '>' + device.Name + ' - ' + device.AppName + '</paper-checkbox>';
}
html += '</fieldset>';
html += '</div>';
$('.deviceAccess', page).show().html(html).trigger('create');
$('#chkEnableAllDevices', page).checked(user.Policy.EnableAllDevices).checkboxradio('refresh').trigger('change');
$('#chkEnableAllDevices', page).checked(user.Policy.EnableAllDevices).trigger('change');
if (user.Policy.IsAdministrator) {
page.querySelector('.deviceAccessContainer').classList.add('hide');
@ -125,29 +113,29 @@
user.Policy.EnableAllFolders = $('#chkEnableAllFolders', page).checked();
user.Policy.EnabledFolders = user.Policy.EnableAllFolders ?
[] :
$('.chkFolder:checked', page).map(function () {
return this.getAttribute('data-id');
}).get();
$('.chkFolder', page).get().filter(function (c) {
return c.checked;
}).map(function (c) {
return c.getAttribute('data-id');
});
user.Policy.EnableAllChannels = $('#chkEnableAllChannels', page).checked();
user.Policy.EnabledChannels = user.Policy.EnableAllChannels ?
[] :
$('.chkChannel:checked', page).map(function () {
return this.getAttribute('data-id');
}).get();
$('.chkChannel', page).get().filter(function (c) {
return c.checked;
}).map(function (c) {
return c.getAttribute('data-id');
});
user.Policy.EnableAllDevices = $('#chkEnableAllDevices', page).checked();
user.Policy.EnabledDevices = user.Policy.EnableAllDevices ?
[] :
$('.chkDevice:checked', page).map(function () {
return this.getAttribute('data-id');
}).get();
$('.chkDevice', page).get().filter(function (c) {
return c.checked;
}).map(function (c) {
return c.getAttribute('data-id');
});
// Legacy
user.Policy.BlockedChannels = null;

View file

@ -465,12 +465,16 @@ paper-textarea.mono textarea {
}
.paperList {
padding-top: 12px;
padding: .5em 0;
margin: 12px auto;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
background-color: #fff;
}
.paperCheckboxList.paperList {
padding: .5em 1em;
}
.ui-body-b .paperList {
background-color: #323232;
}

View file

@ -1,4 +1,4 @@
<div id="editUserPage" data-role="page" class="page type-interior userProfilesPage" data-helpurl="https://github.com/MediaBrowser/Wiki/wiki/Users" data-require="jqmcollapsible,scripts/useredit,paper-input,jqmcheckbox,paper-checkbox">
<div id="editUserPage" data-role="page" class="page type-interior userProfilesPage" data-helpurl="https://github.com/MediaBrowser/Wiki/wiki/Users" data-require="jqmcollapsible,scripts/useredit,paper-input,paper-checkbox">
<div data-role="content">
<div class="content-primary">

View file

@ -1,4 +1,4 @@
<div id="userLibraryAccessPage" data-role="page" class="page type-interior userProfilesPage" data-helpurl="https://github.com/MediaBrowser/Wiki/wiki/Users" data-require="scripts/userlibraryaccess,jqmcheckbox">
<div id="userLibraryAccessPage" data-role="page" class="page type-interior userProfilesPage" data-helpurl="https://github.com/MediaBrowser/Wiki/wiki/Users" data-require="scripts/userlibraryaccess,paper-checkbox">
<div data-role="content">
<div class="content-primary">
@ -11,40 +11,35 @@
<form class="userLibraryAccessForm">
<div class="folderAccessContainer">
<div class="ui-controlgroup-label">${HeaderLibraryAccess}</div>
<h2>${HeaderLibraryAccess}</h2>
<div>
<label for="chkEnableAllFolders">${OptionEnableAccessToAllLibraries}</label>
<input type="checkbox" id="chkEnableAllFolders" />
<div class="fieldDescription">${LibraryAccessHelp}</div>
<paper-checkbox id="chkEnableAllFolders">${OptionEnableAccessToAllLibraries}</paper-checkbox>
</div>
<div class="folderAccessListContainer">
<br />
<div class="folderAccess">
</div>
<div class="fieldDescription">${LibraryAccessHelp}</div>
</div>
</div>
<br />
<br />
<div class="channelAccessContainer" style="display:none;">
<div class="ui-controlgroup-label">${HeaderChannelAccess}</div>
<h2>${HeaderChannelAccess}</h2>
<div>
<label for="chkEnableAllChannels">${OptionEnableAccessToAllChannels}</label>
<input type="checkbox" id="chkEnableAllChannels" />
<div class="fieldDescription">${ChannelAccessHelp}</div>
<paper-checkbox id="chkEnableAllChannels">${OptionEnableAccessToAllChannels}</paper-checkbox>
</div>
<div class="channelAccessListContainer">
<br />
<div class="channelAccess">
</div>
<div class="fieldDescription">${ChannelAccessHelp}</div>
</div>
</div>
<br />
<div class="deviceAccessContainer hide">
<br />
<div class="ui-controlgroup-label">${HeaderDeviceAccess}</div>
<h2>${HeaderDeviceAccess}</h2>
<div>
<label for="chkEnableAllDevices">${OptionEnableAccessFromAllDevices}</label>
<input type="checkbox" id="chkEnableAllDevices" />
<paper-checkbox id="chkEnableAllDevices">${OptionEnableAccessFromAllDevices}</paper-checkbox>
</div>
<div class="deviceAccessListContainer">
<br />