Fixed randomize program bug. Added autoscroll to bottom of list when selecting items in the plex-library directive.

This commit is contained in:
Dan Ferguson 2020-04-24 20:01:44 -04:00
parent ebff2388ed
commit e0b96d3a99
5 changed files with 178 additions and 9 deletions

View File

@ -2,8 +2,9 @@ const angular = require('angular')
require('angular-router-browserify')(angular)
require('./ext/lazyload')(angular)
require('./ext/dragdrop')
require('./ext/angularjs-scroll-glue')
var app = angular.module('myApp', ['ngRoute', 'angularLazyImg', 'dndLists'])
var app = angular.module('myApp', ['ngRoute', 'angularLazyImg', 'dndLists', 'luegg.directives'])
app.service('plex', require('./services/plex'))
app.service('pseudotv', require('./services/pseudotv'))

View File

@ -141,12 +141,11 @@ module.exports = function ($timeout) {
index = 0
}
}
scope.channel.programs = newProgs.concat(movies)
updateChannelDuration()
}
scope.randomShuffle = () => {
randomShuffle(scope.channel.programs)
shuffle(scope.channel.programs)
updateChannelDuration()
}
function getRandomInt(min, max) {
@ -154,12 +153,16 @@ module.exports = function ($timeout) {
max = Math.floor(max)
return Math.floor(Math.random() * (max - min + 1)) + min
}
function randomShuffle(a) {
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1))
[a[i], a[j]] = [a[j], a[i]]
function shuffle(array) {
var currentIndex = array.length, temporaryValue, randomIndex
while (0 !== currentIndex) {
randomIndex = Math.floor(Math.random() * currentIndex)
currentIndex -= 1
temporaryValue = array[currentIndex]
array[currentIndex] = array[randomIndex]
array[randomIndex] = temporaryValue
}
return a
return array
}
function updateChannelDuration() {
scope.channel.duration = 0

164
web/ext/angularjs-scroll-glue.js vendored Normal file
View File

@ -0,0 +1,164 @@
/* angularjs Scroll Glue
* version 2.1.0
* https://github.com/Luegg/angularjs-scroll-glue
* An AngularJs directive that automatically scrolls to the bottom of an element on changes in it's scope.
*/
// Allow module to be loaded via require when using common js. e.g. npm
if(typeof module === "object" && module.exports){
module.exports = 'luegg.directives';
}
(function(angular, undefined){
'use strict';
function createActivationState($parse, attr, scope){
function unboundState(initValue){
var activated = initValue;
return {
getValue: function(){
return activated;
},
setValue: function(value){
activated = value;
}
};
}
function oneWayBindingState(getter, scope){
return {
getValue: function(){
return getter(scope);
},
setValue: function(){}
};
}
function twoWayBindingState(getter, setter, scope){
return {
getValue: function(){
return getter(scope);
},
setValue: function(value){
if(value !== getter(scope)){
scope.$apply(function(){
setter(scope, value);
});
}
}
};
}
if(attr !== ""){
var getter = $parse(attr);
if(getter.assign !== undefined){
return twoWayBindingState(getter, getter.assign, scope);
} else {
return oneWayBindingState(getter, scope);
}
} else {
return unboundState(true);
}
}
function createDirective(module, attrName, direction){
module.directive(attrName, ['$parse', '$window', '$timeout', function($parse, $window, $timeout){
return {
priority: 1,
restrict: 'A',
link: function(scope, $el, attrs){
var el = $el[0],
activationState = createActivationState($parse, attrs[attrName], scope);
function scrollIfGlued() {
if(activationState.getValue() && !direction.isAttached(el)){
// Ensures scroll after angular template digest
$timeout(function() {
direction.scroll(el);
});
}
}
function onScroll() {
activationState.setValue(direction.isAttached(el));
}
$timeout(scrollIfGlued, 0, false);
if (!$el[0].hasAttribute('force-glue')) {
$el.on('scroll', onScroll);
}
var hasAnchor = false;
angular.forEach($el.children(), function(child) {
if (child.hasAttribute('scroll-glue-anchor')) {
hasAnchor = true;
scope.$watch(function() { return child.offsetHeight }, function() {
scrollIfGlued();
});
}
});
if (!hasAnchor) {
scope.$watch(scrollIfGlued);
$window.addEventListener('resize', scrollIfGlued, false);
}
// Remove listeners on directive destroy
$el.on('$destroy', function() {
$el.unbind('scroll', onScroll);
});
scope.$on('$destroy', function() {
$window.removeEventListener('resize', scrollIfGlued, false);
});
}
};
}]);
}
var bottom = {
isAttached: function(el){
// + 1 catches off by one errors in chrome
return el.scrollTop + el.clientHeight + 1 >= el.scrollHeight;
},
scroll: function(el){
el.scrollTop = el.scrollHeight;
}
};
var top = {
isAttached: function(el){
return el.scrollTop <= 1;
},
scroll: function(el){
el.scrollTop = 0;
}
};
var right = {
isAttached: function(el){
return el.scrollLeft + el.clientWidth + 1 >= el.scrollWidth;
},
scroll: function(el){
el.scrollLeft = el.scrollWidth;
}
};
var left = {
isAttached: function(el){
return el.scrollLeft <= 1;
},
scroll: function(el){
el.scrollLeft = 0;
}
};
var module = angular.module('luegg.directives', []);
createDirective(module, 'scrollGlue', bottom);
createDirective(module, 'scrollGlueTop', top);
createDirective(module, 'scrollGlueBottom', bottom);
createDirective(module, 'scrollGlueLeft', left);
createDirective(module, 'scrollGlueRight', right);
}(angular));

View File

@ -37,6 +37,7 @@
<div>
<h6>Programs
<span class="small">Total: {{channel.programs.length}}</span>
<span class="badge badge-dark" style="margin-left: 15px;" ng-show="channel.programs.length !== 0">Commercials</span>
<button class="btn btn-sm btn-secondary" style="margin-left: 10px" ng-click="showShuffleOptions = !showShuffleOptions" ng-show="channel.programs.length !== 0">
Shuffle / Sort&nbsp;&nbsp;<span class="fa {{ showShuffleOptions ? 'fa-chevron-down' : 'fa-chevron-right'}}"></span>

View File

@ -102,7 +102,7 @@
</ul>
<hr/>
<h6>Selected Items</h6>
<ul class="list-group list-group-root" style="height: 180px; overflow-y: scroll" dnd-list="selection">
<ul class="list-group list-group-root" style="height: 180px; overflow-y: scroll" dnd-list="selection" scroll-glue>
<div ng-if="selection.length === 0">Select media items from your plex library above.</div>
<li class="list-group-item" ng-repeat="x in selection" style="cursor:default;" dnd-draggable="x" dnd-moved="selection.splice($index, 1)" dnd-effect-allowed="move">
{{ (x.type !== 'episode') ? x.title : (x.showTitle + ' - S' + x.season.toString().padStart(2,'0') + 'E' + x.episode.toString().padStart(2,'0'))}}