Channel ui changes. Confirmation popup for deleting channels. Adjust program order and start time when reopening a channel to match what's currently on air. 'Cyclic Shuffle'. Button to delete all programs.
This commit is contained in:
parent
326797431f
commit
5b8d9c5995
@ -8,9 +8,11 @@ module.exports = function ($scope, pseudotv) {
|
||||
$scope.channels = channels
|
||||
})
|
||||
$scope.removeChannel = (channel) => {
|
||||
pseudotv.removeChannel(channel).then((channels) => {
|
||||
$scope.channels = channels
|
||||
})
|
||||
if (confirm("Are you sure to delete channel: " + channel.name + "?")) {
|
||||
pseudotv.removeChannel(channel).then((channels) => {
|
||||
$scope.channels = channels
|
||||
})
|
||||
}
|
||||
}
|
||||
$scope.onChannelConfigDone = (channel) => {
|
||||
if (typeof channel !== 'undefined') {
|
||||
|
||||
@ -9,6 +9,7 @@ module.exports = function ($timeout, $location) {
|
||||
onDone: "=onDone"
|
||||
},
|
||||
link: function (scope, element, attrs) {
|
||||
scope.millisecondsOffset = 0;
|
||||
if (typeof scope.channel === 'undefined' || scope.channel == null) {
|
||||
scope.channel = {}
|
||||
scope.channel.programs = []
|
||||
@ -31,9 +32,36 @@ module.exports = function ($timeout, $location) {
|
||||
scope.channel.number = 1
|
||||
scope.channel.name = "Channel 1"
|
||||
}
|
||||
scope.showRotatedNote = false;
|
||||
} else {
|
||||
scope.beforeEditChannelNumber = scope.channel.number
|
||||
let t = Date.now();
|
||||
let originalStart = scope.channel.startTime.getTime();
|
||||
let n = scope.channel.programs.length;
|
||||
let totalDuration = scope.channel.duration;
|
||||
let m = (t - originalStart) % totalDuration;
|
||||
let x = 0;
|
||||
let runningProgram = -1;
|
||||
let offset = 0;
|
||||
for (let i = 0; i < n; i++) {
|
||||
let d = scope.channel.programs[i].duration;
|
||||
if (x + d > m) {
|
||||
runningProgram = i
|
||||
offset = m - x;
|
||||
break;
|
||||
} else {
|
||||
x += d;
|
||||
}
|
||||
}
|
||||
scope.millisecondsOffset = (t - offset) % 1000;
|
||||
scope.channel.startTime = new Date(t - offset - scope.millisecondsOffset);
|
||||
// move runningProgram to index 0
|
||||
scope.channel.programs = scope.channel.programs.slice(runningProgram, this.length)
|
||||
.concat(scope.channel.programs.slice(0, runningProgram) );
|
||||
updateChannelDuration();
|
||||
setTimeout( () => { scope.showRotatedNote = true }, 1, 'funky');
|
||||
}
|
||||
|
||||
scope.finshedProgramEdit = (program) => {
|
||||
scope.channel.programs[scope.selectedProgram] = program
|
||||
scope._selectedProgram = null
|
||||
@ -151,6 +179,15 @@ module.exports = function ($timeout, $location) {
|
||||
shuffle(scope.channel.programs)
|
||||
updateChannelDuration()
|
||||
}
|
||||
scope.cyclicShuffle = () => {
|
||||
cyclicShuffle(scope.channel.programs);
|
||||
updateChannelDuration();
|
||||
}
|
||||
scope.wipeSchedule = () => {
|
||||
wipeSchedule(scope.channel.programs);
|
||||
updateChannelDuration();
|
||||
}
|
||||
|
||||
function getRandomInt(min, max) {
|
||||
min = Math.ceil(min)
|
||||
max = Math.floor(max)
|
||||
@ -167,8 +204,75 @@ module.exports = function ($timeout, $location) {
|
||||
}
|
||||
return array
|
||||
}
|
||||
function wipeSchedule(array) {
|
||||
array.splice(0, array.length)
|
||||
return array;
|
||||
}
|
||||
function cyclicShuffle(array) {
|
||||
let shows = {};
|
||||
let next = {};
|
||||
let counts = {};
|
||||
// some precalculation, useful to stop the shuffle from being quadratic...
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
var vid = array[i];
|
||||
if (vid.type != 'movie' && vid.season != 0) {
|
||||
let countKey = {
|
||||
title: vid.showTitle,
|
||||
s: vid.season,
|
||||
e: vid.episode,
|
||||
}
|
||||
let key = JSON.stringify(countKey);
|
||||
let c = ( (typeof(counts[key]) === 'undefined') ? 0 : counts[key] );
|
||||
counts[key] = c + 1;
|
||||
let showEntry = {
|
||||
c: c,
|
||||
it: array[i],
|
||||
}
|
||||
if ( typeof(shows[vid.showTitle]) === 'undefined') {
|
||||
shows[vid.showTitle] = [];
|
||||
}
|
||||
shows[vid.showTitle].push(showEntry);
|
||||
}
|
||||
}
|
||||
//this is O(|N| log|M|) where |N| is the total number of TV
|
||||
// episodes and |M| is the maximum number of episodes
|
||||
// in a single show. I am pretty sure this is a lower bound
|
||||
// on the time complexity that's possible here.
|
||||
Object.keys(shows).forEach(function(key,index) {
|
||||
shows[key].sort( (a,b) => {
|
||||
if (a.c == b.c) {
|
||||
if (a.it.season == b.it.season) {
|
||||
if (a.it.episode == b.it.episode) {
|
||||
return 0;
|
||||
} else {
|
||||
return (a.it.episode < b.it.episode)?-1: 1;
|
||||
}
|
||||
} else {
|
||||
return (a.it.season < b.it.season)?-1: 1;
|
||||
}
|
||||
} else {
|
||||
return (a.c < b.c)? -1: 1;
|
||||
}
|
||||
});
|
||||
next[key] = Math.floor( Math.random() * shows[key].length );
|
||||
});
|
||||
shuffle(array);
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (array[i].type !== 'movie' && array[i].season != 0) {
|
||||
let title = array[i].showTitle;
|
||||
var sequence = shows[title];
|
||||
var j = next[title];
|
||||
array[i] = sequence[j].it;
|
||||
|
||||
next[title] = (j + 1) % sequence.length;
|
||||
}
|
||||
}
|
||||
return array
|
||||
}
|
||||
|
||||
scope.updateChannelDuration = updateChannelDuration
|
||||
function updateChannelDuration() {
|
||||
scope.showRotatedNote = false;
|
||||
scope.channel.duration = 0
|
||||
for (let i = 0, l = scope.channel.programs.length; i < l; i++) {
|
||||
scope.channel.programs[i].start = new Date(scope.channel.startTime.valueOf() + scope.channel.duration)
|
||||
@ -204,8 +308,10 @@ module.exports = function ($timeout, $location) {
|
||||
scope.error.startTime = "Start time must not be set in the future."
|
||||
else if (channel.programs.length === 0)
|
||||
scope.error.programs = "No programs have been selected. Select at least one program."
|
||||
else
|
||||
else {
|
||||
channel.startTime.setMilliseconds( scope.millisecondsOffset);
|
||||
scope.onDone(JSON.parse(angular.toJson(channel)))
|
||||
}
|
||||
$timeout(() => { scope.error = {} }, 3500)
|
||||
}
|
||||
}
|
||||
@ -229,4 +335,4 @@ module.exports = function ($timeout, $location) {
|
||||
}
|
||||
function validURL(url) {
|
||||
return /^(ftp|http|https):\/\/[^ "]+$/.test(url);
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,10 +72,13 @@
|
||||
<label id="channelStartTime" class="small">Channel Timeline Start {{maxDate}}</label>
|
||||
<input for="channelStartTime" class="form-control form-control-sm" type="datetime-local" ng-model="channel.startTime" />
|
||||
</div>
|
||||
<p class="text-center text-info small" ng-show='showRotatedNote' >The channel is already live, the program schedule has been rotated so that the currently-playing program is at the top of the list.</p>
|
||||
|
||||
<hr />
|
||||
<div>
|
||||
<h6>Programs
|
||||
<span class="small">Total: {{channel.programs.length}}</span>
|
||||
<span class="btn fa fa-trash" ng-click="wipeSchedule()"></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"
|
||||
@ -108,9 +111,12 @@
|
||||
<button class="btn btn-sm btn-warning form-control form-control-sm" type="button" ng-click="blockShuffle(blockCount, randomizeBlockShuffle)">Block Shuffle</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group col-md-6" style="padding: 5px;">
|
||||
<div class="input-group col-md-3" style="padding: 5px;">
|
||||
<button class="btn btn-sm btn-warning form-control form-control-sm" type="button" ng-click="randomShuffle()">Random Shuffle</button>
|
||||
</div>
|
||||
<div class="input-group col-md-3" style="padding: 5px;">
|
||||
<button class="btn btn-sm btn-warning form-control form-control-sm" type="button" ng-click="cyclicShuffle()">Cyclic Shuffle</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="input-group col-md-6" style="padding: 5px;">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user