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

View file

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

View file

@ -427,7 +427,9 @@ var AbrController = function (_EventHandler) {
}, { }, {
key: 'onFragLoading', key: 'onFragLoading',
value: function onFragLoading(data) { value: function onFragLoading(data) {
if (!this.timer) {
this.timer = setInterval(this.onCheck, 100); this.timer = setInterval(this.onCheck, 100);
}
this.fragCurrent = data.frag; this.fragCurrent = data.frag;
} }
}, { }, {
@ -1188,6 +1190,7 @@ var LevelController = function (_EventHandler) {
value: function destroy() { value: function destroy() {
if (this.timer) { if (this.timer) {
clearInterval(this.timer); clearInterval(this.timer);
this.timer = null;
} }
this._manualLevel = -1; 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)); _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; 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) { if (this.startFragRequested && !levelDetails.PTSKnown) {
/* we are switching level on live playlist, but we don't have any PTS info for that quality level ... /* 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. try to load frag matching with next SN.
@ -2516,11 +2533,11 @@ var StreamController = function (_EventHandler) {
_logger.logger.log('playback not stuck anymore @' + currentTime); _logger.logger.log('playback not stuck anymore @' + currentTime);
} }
// check buffer upfront // 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 // and we have a new buffer range available upfront, let's seek to that one
if (bufferInfo.len <= jumpThreshold) { if (expectedPlaying && bufferInfo.len <= jumpThreshold) {
if (playheadMoving || !expectedPlaying) { if (playheadMoving) {
// playhead moving or media not playing // playhead moving
jumpThreshold = 0; jumpThreshold = 0;
this.seekHoleNudgeDuration = 0; this.seekHoleNudgeDuration = 0;
} else { } else {
@ -5158,7 +5175,9 @@ var ErrorDetails = exports.ErrorDetails = {
// Identifier for a buffer full event // Identifier for a buffer full event
BUFFER_FULL_ERROR: 'bufferFullError', BUFFER_FULL_ERROR: 'bufferFullError',
// Identifier for a buffer seek over hole event // 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){ },{}],21:[function(require,module,exports){
@ -5170,17 +5189,17 @@ 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 _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; }; }(); /*
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 * All objects in the event handling chain should inherit from this class
* *
*/ */
//import {logger} from './utils/logger'; 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"); } }
var EventHandler = function () { var EventHandler = function () {
function EventHandler(hls) { function EventHandler(hls) {
@ -5250,7 +5269,12 @@ var EventHandler = function () {
} }
return this[funcName].bind(this, data); return this[funcName].bind(this, data);
}; };
try {
eventToFunction.call(this, event, data).call(); 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; exports.default = EventHandler;
},{}],22:[function(require,module,exports){ },{"./errors":20,"./utils/logger":36}],22:[function(require,module,exports){
'use strict'; 'use strict';
module.exports = { module.exports = {
@ -5498,12 +5522,16 @@ var LevelHelper = function () {
if (PTSFrag) { if (PTSFrag) {
LevelHelper.updateFragPTS(newDetails, PTSFrag.sn, PTSFrag.startPTS, PTSFrag.endPTS); LevelHelper.updateFragPTS(newDetails, PTSFrag.sn, PTSFrag.startPTS, PTSFrag.endPTS);
} else { } else {
// 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 // adjust start by sliding offset
var sliding = oldfragments[delta].start; var sliding = oldfragments[delta].start;
for (i = 0; i < newfragments.length; i++) { for (i = 0; i < newfragments.length; i++) {
newfragments[i].start += sliding; newfragments[i].start += sliding;
} }
} }
}
// if we are here, it means we have fragments overlapping between // if we are here, it means we have fragments overlapping between
// old and new level. reliable PTS info is thus relying on old level // old and new level. reliable PTS info is thus relying on old level
newDetails.PTSKnown = oldDetails.PTSKnown; newDetails.PTSKnown = oldDetails.PTSKnown;
@ -5795,6 +5823,7 @@ var Hls = function () {
this.playlistLoader.destroy(); this.playlistLoader.destroy();
this.fragmentLoader.destroy(); this.fragmentLoader.destroy();
this.levelController.destroy(); this.levelController.destroy();
this.abrController.destroy();
this.bufferController.destroy(); this.bufferController.destroy();
this.capLevelController.destroy(); this.capLevelController.destroy();
this.streamController.destroy(); this.streamController.destroy();
@ -7281,8 +7310,8 @@ var MP4Remuxer = function () {
ptsnorm = this._PTSNormalize(pts, nextAvcDts); ptsnorm = this._PTSNormalize(pts, nextAvcDts);
dtsnorm = this._PTSNormalize(dts, nextAvcDts); dtsnorm = this._PTSNormalize(dts, nextAvcDts);
delta = Math.round((dtsnorm - nextAvcDts) / 90); delta = Math.round((dtsnorm - nextAvcDts) / 90);
// if fragment are contiguous, or delta less than 600ms, ensure there is no overlap/hole between fragments // 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) < 600) { if (contiguous || Math.abs(delta) > 10000) {
if (delta) { if (delta) {
if (delta > 1) { if (delta > 1) {
_logger.logger.log('AVC:' + delta + ' ms hole between fragments detected,filling it'); _logger.logger.log('AVC:' + delta + ' ms hole between fragments detected,filling it');
@ -7414,8 +7443,8 @@ var MP4Remuxer = function () {
ptsnorm = this._PTSNormalize(pts, nextAacPts); ptsnorm = this._PTSNormalize(pts, nextAacPts);
dtsnorm = this._PTSNormalize(dts, nextAacPts); dtsnorm = this._PTSNormalize(dts, nextAacPts);
delta = Math.round(1000 * (ptsnorm - nextAacPts) / pesTimeScale); 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 fragment are contiguous, or if there is a huge delta (more than 10s) between expected PTS and sample PTS
if (contiguous || Math.abs(delta) < 600) { if (contiguous || Math.abs(delta) > 10000) {
// log delta // log delta
if (delta) { if (delta) {
if (delta > 0) { if (delta > 0) {
@ -7427,7 +7456,7 @@ var MP4Remuxer = function () {
track.len -= unit.byteLength; track.len -= unit.byteLength;
continue; continue;
} }
// set DTS to next DTS // set PTS/DTS to next PTS/DTS
ptsnorm = dtsnorm = nextAacPts; 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", "name": "hls.js",
"version": "0.5.20", "version": "0.5.21",
"license": "Apache-2.0", "license": "Apache-2.0",
"description": "Media Source Extension - HLS library, by/for Dailymotion", "description": "Media Source Extension - HLS library, by/for Dailymotion",
"homepage": "https://github.com/dailymotion/hls.js", "homepage": "https://github.com/dailymotion/hls.js",

View file

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

View file

@ -21,6 +21,7 @@ class LevelController extends EventHandler {
destroy() { destroy() {
if (this.timer) { if (this.timer) {
clearInterval(this.timer); clearInterval(this.timer);
this.timer = null;
} }
this._manualLevel = -1; 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)}`); 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; 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) { if (this.startFragRequested && !levelDetails.PTSKnown) {
/* we are switching level on live playlist, but we don't have any PTS info for that quality level ... /* 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. try to load frag matching with next SN.
@ -1004,11 +1018,11 @@ _checkBuffer() {
logger.log(`playback not stuck anymore @${currentTime}`); logger.log(`playback not stuck anymore @${currentTime}`);
} }
// check buffer upfront // 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 // and we have a new buffer range available upfront, let's seek to that one
if(bufferInfo.len <= jumpThreshold) { if(expectedPlaying && bufferInfo.len <= jumpThreshold) {
if(playheadMoving || !expectedPlaying) { if(playheadMoving) {
// playhead moving or media not playing // playhead moving
jumpThreshold = 0; jumpThreshold = 0;
this.seekHoleNudgeDuration = 0; this.seekHoleNudgeDuration = 0;
} else { } else {

View file

@ -45,5 +45,7 @@ export const ErrorDetails = {
// Identifier for a buffer full event // Identifier for a buffer full event
BUFFER_FULL_ERROR: 'bufferFullError', BUFFER_FULL_ERROR: 'bufferFullError',
// Identifier for a buffer seek over hole event // 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 { class EventHandler {
@ -59,7 +60,12 @@ class EventHandler {
} }
return this[funcName].bind(this, data); return this[funcName].bind(this, data);
}; };
try {
eventToFunction.call(this, event, data).call(); 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,12 +44,16 @@ class LevelHelper {
if(PTSFrag) { if(PTSFrag) {
LevelHelper.updateFragPTS(newDetails,PTSFrag.sn,PTSFrag.startPTS,PTSFrag.endPTS); LevelHelper.updateFragPTS(newDetails,PTSFrag.sn,PTSFrag.startPTS,PTSFrag.endPTS);
} else { } else {
// 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 // adjust start by sliding offset
var sliding = oldfragments[delta].start; var sliding = oldfragments[delta].start;
for(i = 0 ; i < newfragments.length ; i++) { for(i = 0 ; i < newfragments.length ; i++) {
newfragments[i].start += sliding; newfragments[i].start += sliding;
} }
} }
}
// if we are here, it means we have fragments overlapping between // if we are here, it means we have fragments overlapping between
// old and new level. reliable PTS info is thus relying on old level // old and new level. reliable PTS info is thus relying on old level
newDetails.PTSKnown = oldDetails.PTSKnown; newDetails.PTSKnown = oldDetails.PTSKnown;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -35,8 +35,8 @@ Custom property | Description | Default
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
width: 100vw; width: 100%;
height: 100vh; height: 100%;
background-color: var(--iron-overlay-backdrop-background-color, #000); background-color: var(--iron-overlay-backdrop-background-color, #000);
opacity: 0; opacity: 0;
transition: opacity 0.2s; 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 // requestAnimationFrame for non-blocking rendering
if (this.__openChangedAsync) { if (this.__openChangedAsync) {
cancelAnimationFrame(this.__openChangedAsync); window.cancelAnimationFrame(this.__openChangedAsync);
} }
if (this.opened) { if (this.opened) {
if (this.withBackdrop) { if (this.withBackdrop) {
this.backdropElement.prepare(); this.backdropElement.prepare();
} }
this.__openChangedAsync = requestAnimationFrame(function() { this.__openChangedAsync = window.requestAnimationFrame(function() {
this.__openChangedAsync = null; this.__openChangedAsync = null;
this._prepareRenderOpened(); this._prepareRenderOpened();
this._renderOpened(); this._renderOpened();
@ -543,11 +543,11 @@ context. You should place this element as a child of `<body>` whenever possible.
*/ */
_onIronResize: function() { _onIronResize: function() {
if (this.__onIronResizeAsync) { if (this.__onIronResizeAsync) {
cancelAnimationFrame(this.__onIronResizeAsync); window.cancelAnimationFrame(this.__onIronResizeAsync);
this.__onIronResizeAsync = null; this.__onIronResizeAsync = null;
} }
if (this.opened && !this.__isAnimating) { if (this.opened && !this.__isAnimating) {
this.__onIronResizeAsync = requestAnimationFrame(function() { this.__onIronResizeAsync = window.requestAnimationFrame(function() {
this.__onIronResizeAsync = null; this.__onIronResizeAsync = null;
this.refit(); this.refit();
}.bind(this)); }.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. * The shared backdrop element.
* @type {Element} backdropElement * @type {!Element} backdropElement
*/ */
get backdropElement() { get backdropElement() {
if (!this._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. * The deepest active element.
* @type {Element} activeElement the active element * @type {!Element} activeElement the active element
*/ */
get deepActiveElement() { get deepActiveElement() {
// document.activeElement can be null // 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) { _bringOverlayAtIndexToFront: function(i) {
var overlay = this._overlays[i]; var overlay = this._overlays[i];
if (!overlay) {
return;
}
var lastI = this._overlays.length - 1; var lastI = this._overlays.length - 1;
var currentOverlay = this._overlays[lastI];
// Ensure always-on-top overlay stays on top. // Ensure always-on-top overlay stays on top.
if (!overlay.alwaysOnTop && this._overlays[lastI].alwaysOnTop) { if (currentOverlay && this._shouldBeBehindOverlay(overlay, currentOverlay)) {
lastI--; lastI--;
} }
// If already the top element, return. // If already the top element, return.
if (!overlay || i >= lastI) { if (i >= lastI) {
return; return;
} }
// Update z-index to be on top. // 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. * 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. * Also updates the backdrop z-index.
* @param {Element} overlay * @param {!Element} overlay
*/ */
addOrRemoveOverlay: function(overlay) { addOrRemoveOverlay: function(overlay) {
if (overlay.opened) { 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. * Tracks overlays for z-index and focus management.
* Ensures the last added overlay with always-on-top remains on top. * Ensures the last added overlay with always-on-top remains on top.
* @param {Element} overlay * @param {!Element} overlay
*/ */
addOverlay: function(overlay) { addOverlay: function(overlay) {
var i = this._overlays.indexOf(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); var newZ = this._getZ(overlay);
// Ensure always-on-top overlay stays on top. // 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 bumps the z-index of +2.
this._applyOverlayZ(currentOverlay, minimumZ); this._applyOverlayZ(currentOverlay, minimumZ);
insertionIndex--; 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) { removeOverlay: function(overlay) {
var i = this._overlays.indexOf(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 * @param {number|string} z
* @private * @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 * @param {number} aboveZ
* @private * @private
*/ */
@ -365,6 +369,19 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
overlay._onCaptureTab(event); 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> <script>
WCT.loadSuites([ WCT.loadSuites([
'iron-overlay-behavior.html', '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> </script>
</body></html> </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": "*" "web-component-tester": "*"
}, },
"private": true, "private": true,
"homepage": "https://github.com/Polymer/polymer", "homepage": "https://github.com/polymer/polymer",
"_release": "1.4.0", "_release": "1.4.0",
"_resolution": { "_resolution": {
"type": "version", "type": "version",
"tag": "v1.4.0", "tag": "v1.4.0",
"commit": "11c987b2eb3c73b388a79fc8aaea8ca01624f514" "commit": "11c987b2eb3c73b388a79fc8aaea8ca01624f514"
}, },
"_source": "git://github.com/Polymer/polymer.git", "_source": "git://github.com/polymer/polymer.git",
"_target": "^1.0.0", "_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 { .adminDrawerPanel .sidebarLink.selectedSidebarLink {
background: #66BB6A !important; background: #52B54B !important;
color: #fff !important; color: #fff !important;
} }

View file

@ -23,7 +23,7 @@
} }
.levelNormal { .levelNormal {
background-color: #4d90fe; background-color: #444;
} }
.levelWarning { .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 data-role="content">
<div class="content-primary"> <div class="content-primary">
@ -24,9 +24,9 @@
<div class="fieldDescription">${LabelCameraUploadPathHelp}</div> <div class="fieldDescription">${LabelCameraUploadPathHelp}</div>
</li> </li>
<li> <li>
<label for="chkSubfolder">${LabelCreateCameraUploadSubfolder}</label> <br />
<input type="checkbox" id="chkSubfolder" data-mini="true" /> <paper-checkbox id="chkSubfolder">${LabelCreateCameraUploadSubfolder}</paper-checkbox>
<div class="fieldDescription">${LabelCreateCameraUploadSubfolderHelp}</div> <div class="fieldDescription paperCheckboxFieldDescription">${LabelCreateCameraUploadSubfolderHelp}</div>
</li> </li>
</ul><br /> </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 data-role="content">
<div class="content-primary"> <div class="content-primary">
<div class="tabContent"> <div class="tabContent">
<form class="metadataImagesConfigurationForm" style="max-width: 800px;"> <form class="metadataImagesConfigurationForm">
<div style="width: 75%;"> <div>
<label for="selectItemType" class="selectLabel">${LabelCustomizeOptionsPerMediaType}</label> <label for="selectItemType" class="selectLabel">${LabelCustomizeOptionsPerMediaType}</label>
<select id="selectItemType" data-mini="true"></select> <select id="selectItemType" data-mini="true"></select>
</div> </div>
<br /> <br />
<br /> <br />
<div class="metadataReaders" style="margin-bottom: 2em; width: 75%;"> <div class="metadataReaders" style="margin-bottom: 2em;">
</div> </div>
<div class="metadataSavers" style="margin-bottom: 2em; width: 75%;"> <div class="metadataSavers" style="margin-bottom: 2em;">
</div> </div>
<div class="metadataFetchers" style="margin-bottom: 2em;"> <div class="metadataFetchers" style="margin-bottom: 2em;">
</div> </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 data-role="content">
<div class="content-primary"> <div class="content-primary">
<h2 class="notificationType" style="margin-bottom: 0;"></h2> <h1 class="notificationType" style="margin-top:0;"></h1>
<form class="notificationSettingForm"> <form class="notificationSettingForm">
<ul data-role="listview" class="ulForm"> <ul data-role="listview" class="ulForm">
<li> <li>
<input type="checkbox" id="chkEnabled" data-mini="true" /> <paper-checkbox id="chkEnabled">${LabelNotificationEnabled}</paper-checkbox>
<label for="chkEnabled">${LabelNotificationEnabled}</label>
</li> </li>
</ul> </ul>
<div class="monitorUsers" style="display: none;"> <div class="monitorUsers" style="display: none;">
<label>${LabelMonitorUsers}</label> <div class="paperCheckboxListLabel">${LabelMonitorUsers}</div>
<div class="monitorUsersList"> <div class="monitorUsersList">
</div> </div>
<br /> <br />

View file

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

View file

@ -65,10 +65,6 @@
htmlName += name; 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) { if (!item.ImageTags || !item.ImageTags.Primary) {
htmlName += '<img src="css/images/editor/missingprimaryimage.png" title="' + Globalize.translate('MissingPrimaryImage') + '" />'; htmlName += '<img src="css/images/editor/missingprimaryimage.png" title="' + Globalize.translate('MissingPrimaryImage') + '" />';
} }

View file

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

View file

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

View file

@ -144,80 +144,66 @@
var html = ''; var html = '';
if (!plugins.length) { if (!plugins.length) {
$('.imageFetchers', page).html(html).hide().trigger('create'); $('.imageFetchers', page).html(html).hide();
return; return;
} }
var i, length, plugin, id; var i, length, plugin, id;
html += '<div class="ui-controlgroup-label" style="margin-bottom:0;padding-left:2px;">' + Globalize.translate('LabelImageFetchers') + '</div>'; html += '<div class="paperCheckboxListLabel">' + Globalize.translate('LabelImageFetchers') + '</div>';
html += '<div class="paperList">';
html += '<div style="display:inline-block;width: 75%;vertical-align:top;">';
html += '<div data-role="controlgroup" class="imageFetcherGroup">';
for (i = 0, length = plugins.length; i < length; i++) { for (i = 0, length = plugins.length; i < length; i++) {
plugin = plugins[i]; plugin = plugins[i];
id = 'chkImageFetcher' + i;
var isChecked = config.DisabledImageFetchers.indexOf(plugin.Name) == -1 ? ' checked="checked"' : ''; 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 += '<paper-icon-item class="imageFetcherItem" data-pluginname="' + plugin.Name + '">';
html += '<label for="' + id + '">' + plugin.Name + '</label>';
}
html += '</div>'; html += '<paper-checkbox class="chkImageFetcher" data-pluginname="' + plugin.Name + '" item-icon' + isChecked + '></paper-checkbox>';
html += '</div>';
if (plugins.length > 1) { html += '<paper-item-body>';
html += '<div style="display:inline-block;vertical-align:top;margin-left:5px;">';
for (i = 0, length = plugins.length; i < length; i++) {
html += '<div>'; html += '<div>';
html += plugin.Name;
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 += '</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" style="width:75%;">' + Globalize.translate('LabelImageFetchersHelp') + '</div>'; html += '<div class="fieldDescription">' + 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 () { $('.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];
if (insertAfter) {
elemToMove.parentNode.removeChild(elemToMove); elemToMove.parentNode.removeChild(elemToMove);
$(elemToMove).insertAfter(insertAfter); $(elemToMove).insertAfter(insertAfter);
}
}); });
$('.btnUp', elem).on('click', function () { $('.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];
if (insertBefore) {
elemToMove.parentNode.removeChild(elemToMove); elemToMove.parentNode.removeChild(elemToMove);
$(elemToMove).insertBefore(insertBefore); $(elemToMove).insertBefore(insertBefore);
}
}); });
} }
@ -230,12 +216,12 @@
var html = ''; var html = '';
if (!plugins.length) { if (!plugins.length) {
$('.metadataSavers', page).html(html).hide().trigger('create'); $('.metadataSavers', page).html(html).hide();
return; return;
} }
html += '<div class="paperCheckboxListLabel">' + Globalize.translate('LabelMetadataSavers') + '</div>'; 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++) { for (var i = 0, length = plugins.length; i < length; i++) {
@ -261,80 +247,66 @@
var html = ''; var html = '';
if (!plugins.length) { if (!plugins.length) {
$('.metadataFetchers', page).html(html).hide().trigger('create'); $('.metadataFetchers', page).html(html).hide();
return; 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 class="paperCheckboxListLabel">' + Globalize.translate('LabelMetadataDownloaders') + '</div>';
html += '<div class="paperList">';
html += '<div style="display:inline-block;width: 75%;vertical-align:top;">';
html += '<div data-role="controlgroup" class="metadataFetcherGroup">';
for (i = 0, length = plugins.length; i < length; i++) { for (i = 0, length = plugins.length; i < length; i++) {
plugin = plugins[i]; plugin = plugins[i];
id = 'chkMetadataFetcher' + i;
var isChecked = config.DisabledMetadataFetchers.indexOf(plugin.Name) == -1 ? ' checked="checked"' : ''; 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 += '<paper-icon-item class="metadataFetcherItem" data-pluginname="' + plugin.Name + '">';
html += '<label for="' + id + '">' + plugin.Name + '</label>';
}
html += '</div>'; html += '<paper-checkbox class="chkMetadataFetcher" data-pluginname="' + plugin.Name + '" item-icon' + isChecked + '></paper-checkbox>';
html += '</div>';
if (plugins.length > 1) { html += '<paper-item-body>';
html += '<div style="display:inline-block;vertical-align:top;margin-left:5px;">';
for (i = 0, length = plugins.length; i < length; i++) {
html += '<div>'; html += '<div>';
html += plugin.Name;
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 += '</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" style="width:75%;">' + Globalize.translate('LabelMetadataDownloadersHelp') + '</div>'; html += '<div class="fieldDescription">' + 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 () { $('.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];
if (insertAfter) {
elemToMove.parentNode.removeChild(elemToMove); elemToMove.parentNode.removeChild(elemToMove);
$(elemToMove).insertAfter(insertAfter); $(elemToMove).insertAfter(insertAfter);
}
}); });
$('.btnUp', elem).on('click', function () { $('.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];
if (insertBefore) {
elemToMove.parentNode.removeChild(elemToMove); elemToMove.parentNode.removeChild(elemToMove);
$(elemToMove).insertBefore(insertBefore); $(elemToMove).insertBefore(insertBefore);
}
}); });
} }
@ -347,42 +319,44 @@
var html = ''; var html = '';
if (plugins.length < 2) { if (plugins.length < 2) {
$('.metadataReaders', page).html(html).hide().trigger('create'); $('.metadataReaders', page).html(html).hide();
return; return;
} }
html += '<div class="ui-controlgroup-label" style="margin-bottom:0;padding-left:2px;">' + Globalize.translate('LabelMetadataReaders') + '</div>'; html += '<div class="paperCheckboxListLabel">' + 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="paperList">';
for (var i = 0, length = plugins.length; i < length; i++) { for (var i = 0, length = plugins.length; i < length; i++) {
var plugin = plugins[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) { if (i > 0) {
html += '<a href="#" style="font-weight:normal;">' + plugin.Name + '</a>'; html += '<paper-icon-button title="' + Globalize.translate('ButtonUp') + '" icon="keyboard-arrow-up" class="btnLocalReaderUp btnLocalReaderMove" data-pluginindex="' + i + '"></paper-icon-button>';
html += '<a class="btnLocalReaderUp btnLocalReaderMove" data-pluginindex="' + i + '" href="#" style="font-weight:normal;" data-icon="arrow-u">' + Globalize.translate('ButtonUp') + '</a>';
} }
else if (plugins.length > 1) { else if (plugins.length > 1) {
html += '<a href="#" style="font-weight:normal;">' + plugin.Name + '</a>'; html += '<paper-icon-button title="' + Globalize.translate('ButtonDown') + '" icon="keyboard-arrow-down" class="btnLocalReaderDown btnLocalReaderMove" data-pluginindex="' + i + '"></paper-icon-button>';
html += '<a class="btnLocalReaderDown btnLocalReaderMove" data-pluginindex="' + i + '" href="#" style="font-weight:normal;" data-icon="arrow-d">' + Globalize.translate('ButtonDown') + '</a>';
}
else {
html += plugin.Name;
}
html += '</li>';
} }
html += '</ul>'; html += '</paper-icon-item>';
}
html += '</div>';
html += '<div class="fieldDescription">' + Globalize.translate('LabelMetadataReadersHelp') + '</div>'; html += '<div class="fieldDescription">' + Globalize.translate('LabelMetadataReadersHelp') + '</div>';
$('.metadataReaders', page).html(html).show().trigger('create'); $('.metadataReaders', page).html(html).show();
} }
function loadPage(page) { 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'); 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'); return c.getAttribute('data-pluginname');
@ -536,7 +514,7 @@
$('.metadataReaders', page).on('click', '.btnLocalReaderMove', function () { $('.metadataReaders', page).on('click', '.btnLocalReaderMove', function () {
var li = $(this).parents('.localReaderOption'); var li = $(this).parents('.localReaderOption');
var ul = li.parents('ul'); var list = li.parents('.paperList');
if ($(this).hasClass('btnLocalReaderDown')) { if ($(this).hasClass('btnLocalReaderDown')) {
@ -551,12 +529,12 @@
li.remove().insertBefore(prev); li.remove().insertBefore(prev);
} }
$('.localReaderOption', ul).each(function () { $('.localReaderOption', list).each(function () {
if ($(this).prev('.localReaderOption').length) { 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 { } 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({ html = LibraryBrowser.getPosterViewHtml({
items: result.Items, items: result.Items,
shape: "square", shape: "square",
context: 'music', context: 'folders',
showTitle: true, showTitle: true,
showParentTitle: true, showParentTitle: true,
lazy: true, lazy: true,

View file

@ -4,17 +4,15 @@
function fillItems(elem, items, cssClass, idPrefix, currentList, isEnabledList) { 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) { html += items.map(function (u) {
var id = idPrefix + u.Id;
var isChecked = isEnabledList ? currentList.indexOf(u.Id) != -1 : currentList.indexOf(u.Id) == -1; var isChecked = isEnabledList ? currentList.indexOf(u.Id) != -1 : currentList.indexOf(u.Id) == -1;
var checkedHtml = isChecked ? ' checked="checked"' : ''; 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(''); }).join('');
@ -86,7 +84,7 @@
fillItems($('.sendToUsersList', page), users, 'chkSendTo', 'chkSendTo', notificationConfig.SendToUsers, true); fillItems($('.sendToUsersList', page), users, 'chkSendTo', 'chkSendTo', notificationConfig.SendToUsers, true);
fillItems($('.servicesList', page), services, 'chkService', 'chkService', notificationConfig.DisabledServices); 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); $('#txtTitle', page).val(notificationConfig.Title || typeInfo.DefaultTitle);
@ -135,15 +133,21 @@
notificationConfig.Title = null; 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'); 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'); 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'); return c.getAttribute('data-itemid');
}); });

View file

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

View file

@ -82,13 +82,12 @@
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
require(['paper-checkbox', 'paper-input', 'emby-collapsible'], function () { require(['paper-checkbox', 'paper-input', 'emby-collapsible'], function () {
renderFormInternal(options); renderFormInternal(options, resolve);
resolve();
}); });
}); });
} }
function renderFormInternal(options) { function renderFormInternal(options, resolve) {
var elem = options.elem; var elem = options.elem;
var dialogOptions = options.dialogOptions; var dialogOptions = options.dialogOptions;
@ -189,7 +188,7 @@
$('#selectSyncTarget', elem).on('change', function () { $('#selectSyncTarget', elem).on('change', function () {
loadQualityOptions(elem, this.value, options.dialogOptionsFn); loadQualityOptions(elem, this.value, options.dialogOptionsFn).then(resolve);
}).trigger('change'); }).trigger('change');
@ -319,12 +318,14 @@
return o.Id == profileId; return o.Id == profileId;
})[0]; })[0];
var qualityOptions = options.QualityOptions || [];
if (option) { if (option) {
$('.profileDescription', form).html(option.Description || ''); $('.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 { } else {
$('.profileDescription', form).html(''); $('.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) { 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 () { }).on('pageshow', ".syncActivityPage", function () {
if (this.id == 'syncActivityPage') {
LibraryMenu.setTabs('syncadmin', 0, getTabs); LibraryMenu.setTabs('syncadmin', 0, getTabs);
}
var page = this; var page = this;
Dashboard.getPluginSecurityInfo().then(function (pluginSecurityInfo) { 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) { function renderJob(page, job, dialogOptions) {
@ -335,7 +335,7 @@
function loadJobInfo(page, job, jobItems) { function loadJobInfo(page, job, jobItems) {
renderJob(page, job, _jobOptions); //renderJob(page, job, _jobOptions);
renderJobItems(page, jobItems); renderJobItems(page, jobItems);
Dashboard.hideLoadingMsg(); Dashboard.hideLoadingMsg();
} }

View file

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

View file

@ -465,12 +465,16 @@ paper-textarea.mono textarea {
} }
.paperList { .paperList {
padding-top: 12px; padding: .5em 0;
margin: 12px auto; 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); 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; background-color: #fff;
} }
.paperCheckboxList.paperList {
padding: .5em 1em;
}
.ui-body-b .paperList { .ui-body-b .paperList {
background-color: #323232; 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 data-role="content">
<div class="content-primary"> <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 data-role="content">
<div class="content-primary"> <div class="content-primary">
@ -11,40 +11,35 @@
<form class="userLibraryAccessForm"> <form class="userLibraryAccessForm">
<div class="folderAccessContainer"> <div class="folderAccessContainer">
<div class="ui-controlgroup-label">${HeaderLibraryAccess}</div> <h2>${HeaderLibraryAccess}</h2>
<div> <div>
<label for="chkEnableAllFolders">${OptionEnableAccessToAllLibraries}</label> <paper-checkbox id="chkEnableAllFolders">${OptionEnableAccessToAllLibraries}</paper-checkbox>
<input type="checkbox" id="chkEnableAllFolders" />
<div class="fieldDescription">${LibraryAccessHelp}</div>
</div> </div>
<div class="folderAccessListContainer"> <div class="folderAccessListContainer">
<br /> <br />
<div class="folderAccess"> <div class="folderAccess">
</div> </div>
<div class="fieldDescription">${LibraryAccessHelp}</div>
</div> </div>
</div> </div>
<br /> <br />
<br />
<div class="channelAccessContainer" style="display:none;"> <div class="channelAccessContainer" style="display:none;">
<div class="ui-controlgroup-label">${HeaderChannelAccess}</div> <h2>${HeaderChannelAccess}</h2>
<div> <div>
<label for="chkEnableAllChannels">${OptionEnableAccessToAllChannels}</label> <paper-checkbox id="chkEnableAllChannels">${OptionEnableAccessToAllChannels}</paper-checkbox>
<input type="checkbox" id="chkEnableAllChannels" />
<div class="fieldDescription">${ChannelAccessHelp}</div>
</div> </div>
<div class="channelAccessListContainer"> <div class="channelAccessListContainer">
<br /> <br />
<div class="channelAccess"> <div class="channelAccess">
</div> </div>
<div class="fieldDescription">${ChannelAccessHelp}</div>
</div> </div>
</div> </div>
<br /> <br />
<div class="deviceAccessContainer hide"> <div class="deviceAccessContainer hide">
<br /> <h2>${HeaderDeviceAccess}</h2>
<div class="ui-controlgroup-label">${HeaderDeviceAccess}</div>
<div> <div>
<label for="chkEnableAllDevices">${OptionEnableAccessFromAllDevices}</label> <paper-checkbox id="chkEnableAllDevices">${OptionEnableAccessFromAllDevices}</paper-checkbox>
<input type="checkbox" id="chkEnableAllDevices" />
</div> </div>
<div class="deviceAccessListContainer"> <div class="deviceAccessListContainer">
<br /> <br />