Compare commits

..

No commits in common. "9b6e947ff36450c0e6dd341f7bf361339cf4eb17" and "fa7fc95ccb39a85b2e42dfb9271e250f90a45440" have entirely different histories.

5 changed files with 35 additions and 188 deletions

View File

@ -1,11 +0,0 @@
alter table series
add column date_updated timestamp;
update series
set date_updated='2023-04-15';
pragma writable_schema=on;
update sqlite_master
set sql=replace(sql, 'date_updated timestamp', 'date_updated timestamp not null')
where type='table' and name='series';
pragma writable_schema=off;

View File

@ -96,7 +96,7 @@
<div id='queue-container'> <div id='queue-container'>
<h2>Playlist</h2> <h2>Playlist</h2>
<div> <div>
<h3>Now Playing:</h3> <h3>Up Next:</h3>
<a href='#' id='clear-playlist'>Clear Playlist</a> <a href='#' id='clear-playlist'>Clear Playlist</a>
</div> </div>
<ol> <ol>

View File

@ -40,8 +40,6 @@ var Player = /** @class */ (function () {
var _this = this; var _this = this;
this.playlist = playlist; this.playlist = playlist;
this.playlist.setPlayEpisodeHandler(function (episode) { return _this.playEpisode(episode); }); this.playlist.setPlayEpisodeHandler(function (episode) { return _this.playEpisode(episode); });
this.playlist.setNowPlayingEpisodeHandler(function () { return _this.currentEpisode(); });
this.playlist.setStopHandler(function () { return _this.stopPlaybackAndResetUi(); });
var controls = getOrThrow(document.getElementById('controls')); var controls = getOrThrow(document.getElementById('controls'));
var timeVolume = getOrThrow(document.getElementById('timeVolume')); var timeVolume = getOrThrow(document.getElementById('timeVolume'));
this.nowPlaying = getOrThrow(document.getElementById('nowPlaying')); this.nowPlaying = getOrThrow(document.getElementById('nowPlaying'));
@ -163,7 +161,6 @@ var Player = /** @class */ (function () {
text: message, text: message,
gravity: 'bottom', gravity: 'bottom',
position: 'right', position: 'right',
stopOnFocus: false,
style: { style: {
marginBottom: '10ex', marginBottom: '10ex',
background: '#a00', background: '#a00',
@ -324,8 +321,6 @@ var Playlist = /** @class */ (function () {
this.queueExpandedHeight = 'calc(100% - 6ex)'; this.queueExpandedHeight = 'calc(100% - 6ex)';
// event handlers // event handlers
this.changedHandlers = []; this.changedHandlers = [];
this.nowPlayingEpisodeHandler = null;
this.stopHandler = null;
this.playEpisodeHandler = null; this.playEpisodeHandler = null;
// the actual episode queue // the actual episode queue
this.episodes = []; this.episodes = [];
@ -340,7 +335,6 @@ var Playlist = /** @class */ (function () {
this.queueTab.addEventListener('click', function () { return _this.toggleQueueUI(); }); this.queueTab.addEventListener('click', function () { return _this.toggleQueueUI(); });
this.overlay.addEventListener('click', function () { return _this.toggleQueueUI(); }); this.overlay.addEventListener('click', function () { return _this.toggleQueueUI(); });
this.clearButton.addEventListener('click', function () { return _this.clearPlaylist(); }); this.clearButton.addEventListener('click', function () { return _this.clearPlaylist(); });
this.unshiftCurrent();
} }
Playlist.prototype.addPlaylistChangedHandler = function (handler) { Playlist.prototype.addPlaylistChangedHandler = function (handler) {
this.changedHandlers.push(handler); this.changedHandlers.push(handler);
@ -348,12 +342,6 @@ var Playlist = /** @class */ (function () {
Playlist.prototype.setPlayEpisodeHandler = function (handler) { Playlist.prototype.setPlayEpisodeHandler = function (handler) {
this.playEpisodeHandler = handler; this.playEpisodeHandler = handler;
}; };
Playlist.prototype.setNowPlayingEpisodeHandler = function (handler) {
this.nowPlayingEpisodeHandler = handler;
};
Playlist.prototype.setStopHandler = function (handler) {
this.stopHandler = handler;
};
Playlist.prototype.hasNextEpisode = function () { Playlist.prototype.hasNextEpisode = function () {
return this.episodes.length > 0; return this.episodes.length > 0;
}; };
@ -382,16 +370,6 @@ var Playlist = /** @class */ (function () {
this.playlistChanged(); this.playlistChanged();
}; };
Playlist.prototype.unshiftEpisodes = function (episodes) { Playlist.prototype.unshiftEpisodes = function (episodes) {
this.shiftCurrent();
var nowPlaying = this.nowPlayingEpisodeHandler
? this.nowPlayingEpisodeHandler()
: null;
if (nowPlaying) {
var litem = this.createQueueListItem(nowPlaying);
this.episodes.unshift([nowPlaying, litem]);
this.episodeHash.add(nowPlaying.id);
this.queueList.prepend(litem);
}
for (var i = episodes.length - 1; i >= 0; i--) { for (var i = episodes.length - 1; i >= 0; i--) {
var episode = episodes[i]; var episode = episodes[i];
if (this.isQueued(episode)) if (this.isQueued(episode))
@ -404,7 +382,6 @@ var Playlist = /** @class */ (function () {
this.notify(episodes.length == 1 this.notify(episodes.length == 1
? 'Episode added to queue.' ? 'Episode added to queue.'
: "".concat(episodes.length, " episodes added to queue.")); : "".concat(episodes.length, " episodes added to queue."));
this.unshiftCurrent();
this.playlistChanged(); this.playlistChanged();
}; };
Playlist.prototype.removeEpisode = function (episode, ignoreChanged, notify) { Playlist.prototype.removeEpisode = function (episode, ignoreChanged, notify) {
@ -429,50 +406,20 @@ var Playlist = /** @class */ (function () {
}; };
Playlist.prototype.clearPlaylist = function () { Playlist.prototype.clearPlaylist = function () {
var removed = this.episodes.length; var removed = this.episodes.length;
if (this.nowPlayingEpisodeHandler &&
this.nowPlayingEpisodeHandler() != null) {
if (this.stopHandler)
this.stopHandler();
removed++;
}
this.episodes.length = 0; this.episodes.length = 0;
this.episodeHash.clear(); this.episodeHash.clear();
this.queueList.innerHTML = ''; this.queueList.innerHTML = '';
this.unshiftCurrent();
this.playlistChanged(); this.playlistChanged();
if (removed > 0) { if (removed > 0) {
this.notify('Playlist cleared.'); this.notify('Playlist cleared.');
} }
}; };
Playlist.prototype.playlistChanged = function () { Playlist.prototype.playlistChanged = function () {
this.shiftCurrent();
this.unshiftCurrent();
for (var _i = 0, _a = this.changedHandlers; _i < _a.length; _i++) { for (var _i = 0, _a = this.changedHandlers; _i < _a.length; _i++) {
var handler = _a[_i]; var handler = _a[_i];
handler(); handler();
} }
}; };
Playlist.prototype.shiftCurrent = function () {
var _a;
(_a = this.queueList.firstChild) === null || _a === void 0 ? void 0 : _a.remove();
};
Playlist.prototype.unshiftCurrent = function () {
var currentEpisode = this.nowPlayingEpisodeHandler
? this.nowPlayingEpisodeHandler()
: null;
if (currentEpisode) {
this.queueList.prepend(this.createQueueListItem(currentEpisode, false));
}
else {
var litem = document.createElement('li');
litem.classList.add('episode');
litem.title = 'No episode playing';
var label = document.createElement('label');
label.innerHTML = 'No episode playing';
litem.appendChild(label);
this.queueList.prepend(litem);
}
};
Playlist.prototype.toggleQueueUI = function () { Playlist.prototype.toggleQueueUI = function () {
if (this.queueContainer.style.height !== this.queueExpandedHeight) { if (this.queueContainer.style.height !== this.queueExpandedHeight) {
this.queueContainer.style.height = this.queueExpandedHeight; this.queueContainer.style.height = this.queueExpandedHeight;
@ -491,17 +438,8 @@ var Playlist = /** @class */ (function () {
this.queueTab.classList.remove('expanded'); this.queueTab.classList.remove('expanded');
} }
}; };
Playlist.prototype.reQueueNowPlaying = function () { Playlist.prototype.createQueueListItem = function (episode) {
var currentEpisode = this.nowPlayingEpisodeHandler
? this.nowPlayingEpisodeHandler()
: null;
if (currentEpisode) {
this.unshiftEpisodes([currentEpisode]);
}
};
Playlist.prototype.createQueueListItem = function (episode, withControls) {
var _this = this; var _this = this;
if (withControls === void 0) { withControls = true; }
var item = document.createElement('li'); var item = document.createElement('li');
item.classList.add('episode'); item.classList.add('episode');
item.title = episode.title; item.title = episode.title;
@ -511,27 +449,24 @@ var Playlist = /** @class */ (function () {
sspan.innerHTML = episode.series.title; sspan.innerHTML = episode.series.title;
var aside = document.createElement('aside'); var aside = document.createElement('aside');
aside.appendChild(sspan); aside.appendChild(sspan);
var controls = document.createElement('div');
controls.classList.add('controls');
var playBtn = document.createElement('a');
playBtn.href = '#';
playBtn.innerHTML = 'Play Now';
playBtn.addEventListener('click', function () {
if (_this.playEpisodeHandler)
_this.playEpisodeHandler(episode);
});
var remBtn = document.createElement('a');
remBtn.href = '#';
remBtn.innerHTML = 'Remove';
remBtn.addEventListener('click', function () { return _this.removeEpisode(episode); });
controls.appendChild(playBtn);
controls.appendChild(remBtn);
item.appendChild(label); item.appendChild(label);
item.appendChild(aside); item.appendChild(aside);
if (withControls) { item.appendChild(controls);
var controls = document.createElement('div');
controls.classList.add('controls');
var playBtn = document.createElement('a');
playBtn.href = '#';
playBtn.innerHTML = 'Play Now';
playBtn.addEventListener('click', function () {
_this.reQueueNowPlaying();
if (_this.playEpisodeHandler)
_this.playEpisodeHandler(episode);
});
var remBtn = document.createElement('a');
remBtn.href = '#';
remBtn.innerHTML = 'Remove';
remBtn.addEventListener('click', function () { return _this.removeEpisode(episode); });
controls.appendChild(playBtn);
controls.appendChild(remBtn);
item.appendChild(controls);
}
return item; return item;
}; };
Playlist.prototype.notify = function (message) { Playlist.prototype.notify = function (message) {
@ -539,7 +474,6 @@ var Playlist = /** @class */ (function () {
text: message, text: message,
gravity: 'bottom', gravity: 'bottom',
position: 'right', position: 'right',
stopOnFocus: false,
style: { style: {
marginBottom: '10ex', marginBottom: '10ex',
background: '#090', background: '#090',

View File

@ -26,9 +26,6 @@ class Player {
public constructor(playlist: Playlist) { public constructor(playlist: Playlist) {
this.playlist = playlist; this.playlist = playlist;
this.playlist.setPlayEpisodeHandler((episode) => this.playEpisode(episode)); this.playlist.setPlayEpisodeHandler((episode) => this.playEpisode(episode));
this.playlist.setNowPlayingEpisodeHandler(() => this.currentEpisode());
this.playlist.setStopHandler(() => this.stopPlaybackAndResetUi());
const controls = getOrThrow(document.getElementById('controls')); const controls = getOrThrow(document.getElementById('controls'));
const timeVolume = getOrThrow(document.getElementById('timeVolume')); const timeVolume = getOrThrow(document.getElementById('timeVolume'));
this.nowPlaying = getOrThrow(document.getElementById('nowPlaying')); this.nowPlaying = getOrThrow(document.getElementById('nowPlaying'));
@ -166,7 +163,6 @@ class Player {
text: message, text: message,
gravity: 'bottom', gravity: 'bottom',
position: 'right', position: 'right',
stopOnFocus: false,
style: { style: {
marginBottom: '10ex', marginBottom: '10ex',
background: '#a00', background: '#a00',

View File

@ -10,8 +10,6 @@ class Playlist {
// event handlers // event handlers
private changedHandlers: Array<() => void> = []; private changedHandlers: Array<() => void> = [];
private nowPlayingEpisodeHandler: (() => Episode | null) | null = null;
private stopHandler: (() => void) | null = null;
private playEpisodeHandler: ((episode: Episode) => void) | null = null; private playEpisodeHandler: ((episode: Episode) => void) | null = null;
// the actual episode queue // the actual episode queue
@ -38,8 +36,6 @@ class Playlist {
this.queueTab.addEventListener('click', () => this.toggleQueueUI()); this.queueTab.addEventListener('click', () => this.toggleQueueUI());
this.overlay.addEventListener('click', () => this.toggleQueueUI()); this.overlay.addEventListener('click', () => this.toggleQueueUI());
this.clearButton.addEventListener('click', () => this.clearPlaylist()); this.clearButton.addEventListener('click', () => this.clearPlaylist());
this.unshiftCurrent();
} }
public addPlaylistChangedHandler(handler: () => void): void { public addPlaylistChangedHandler(handler: () => void): void {
@ -50,14 +46,6 @@ class Playlist {
this.playEpisodeHandler = handler; this.playEpisodeHandler = handler;
} }
public setNowPlayingEpisodeHandler(handler: () => Episode | null): void {
this.nowPlayingEpisodeHandler = handler;
}
public setStopHandler(handler: () => void): void {
this.stopHandler = handler;
}
public hasNextEpisode(): boolean { public hasNextEpisode(): boolean {
return this.episodes.length > 0; return this.episodes.length > 0;
} }
@ -90,16 +78,6 @@ class Playlist {
} }
public unshiftEpisodes(episodes: Array<Episode>): void { public unshiftEpisodes(episodes: Array<Episode>): void {
this.shiftCurrent();
const nowPlaying = this.nowPlayingEpisodeHandler
? this.nowPlayingEpisodeHandler()
: null;
if (nowPlaying) {
const litem = this.createQueueListItem(nowPlaying);
this.episodes.unshift([nowPlaying, litem]);
this.episodeHash.add(nowPlaying.id);
this.queueList.prepend(litem);
}
for (let i = episodes.length - 1; i >= 0; i--) { for (let i = episodes.length - 1; i >= 0; i--) {
const episode = episodes[i]; const episode = episodes[i];
if (this.isQueued(episode)) this.removeEpisode(episode, true, false); if (this.isQueued(episode)) this.removeEpisode(episode, true, false);
@ -113,7 +91,6 @@ class Playlist {
? 'Episode added to queue.' ? 'Episode added to queue.'
: `${episodes.length} episodes added to queue.` : `${episodes.length} episodes added to queue.`
); );
this.unshiftCurrent();
this.playlistChanged(); this.playlistChanged();
} }
@ -141,19 +118,10 @@ class Playlist {
} }
public clearPlaylist(): void { public clearPlaylist(): void {
let removed = this.episodes.length; const removed = this.episodes.length;
if (
this.nowPlayingEpisodeHandler &&
this.nowPlayingEpisodeHandler() != null
) {
if (this.stopHandler) this.stopHandler();
removed++;
}
this.episodes.length = 0; this.episodes.length = 0;
this.episodeHash.clear(); this.episodeHash.clear();
this.queueList.innerHTML = ''; this.queueList.innerHTML = '';
this.unshiftCurrent();
this.playlistChanged(); this.playlistChanged();
if (removed > 0) { if (removed > 0) {
this.notify('Playlist cleared.'); this.notify('Playlist cleared.');
@ -161,35 +129,11 @@ class Playlist {
} }
private playlistChanged(): void { private playlistChanged(): void {
this.shiftCurrent();
this.unshiftCurrent();
for (const handler of this.changedHandlers) { for (const handler of this.changedHandlers) {
handler(); handler();
} }
} }
private shiftCurrent(): void {
this.queueList.firstChild?.remove();
}
private unshiftCurrent(): void {
const currentEpisode = this.nowPlayingEpisodeHandler
? this.nowPlayingEpisodeHandler()
: null;
if (currentEpisode) {
this.queueList.prepend(this.createQueueListItem(currentEpisode, false));
} else {
const litem = document.createElement('li');
litem.classList.add('episode');
litem.title = 'No episode playing';
const label = document.createElement('label');
label.innerHTML = 'No episode playing';
litem.appendChild(label);
this.queueList.prepend(litem);
}
}
private toggleQueueUI(): void { private toggleQueueUI(): void {
if (this.queueContainer.style.height !== this.queueExpandedHeight) { if (this.queueContainer.style.height !== this.queueExpandedHeight) {
this.queueContainer.style.height = this.queueExpandedHeight; this.queueContainer.style.height = this.queueExpandedHeight;
@ -208,19 +152,7 @@ class Playlist {
} }
} }
private reQueueNowPlaying(): void { private createQueueListItem(episode: Episode): HTMLLIElement {
const currentEpisode = this.nowPlayingEpisodeHandler
? this.nowPlayingEpisodeHandler()
: null;
if (currentEpisode) {
this.unshiftEpisodes([currentEpisode]);
}
}
private createQueueListItem(
episode: Episode,
withControls = true
): HTMLLIElement {
const item = document.createElement('li'); const item = document.createElement('li');
item.classList.add('episode'); item.classList.add('episode');
item.title = episode.title; item.title = episode.title;
@ -230,26 +162,23 @@ class Playlist {
sspan.innerHTML = episode.series.title; sspan.innerHTML = episode.series.title;
const aside = document.createElement('aside'); const aside = document.createElement('aside');
aside.appendChild(sspan); aside.appendChild(sspan);
const controls = document.createElement('div');
controls.classList.add('controls');
const playBtn = document.createElement('a');
playBtn.href = '#';
playBtn.innerHTML = 'Play Now';
playBtn.addEventListener('click', () => {
if (this.playEpisodeHandler) this.playEpisodeHandler(episode);
});
const remBtn = document.createElement('a');
remBtn.href = '#';
remBtn.innerHTML = 'Remove';
remBtn.addEventListener('click', () => this.removeEpisode(episode));
controls.appendChild(playBtn);
controls.appendChild(remBtn);
item.appendChild(label); item.appendChild(label);
item.appendChild(aside); item.appendChild(aside);
if (withControls) { item.appendChild(controls);
const controls = document.createElement('div');
controls.classList.add('controls');
const playBtn = document.createElement('a');
playBtn.href = '#';
playBtn.innerHTML = 'Play Now';
playBtn.addEventListener('click', () => {
this.reQueueNowPlaying();
if (this.playEpisodeHandler) this.playEpisodeHandler(episode);
});
const remBtn = document.createElement('a');
remBtn.href = '#';
remBtn.innerHTML = 'Remove';
remBtn.addEventListener('click', () => this.removeEpisode(episode));
controls.appendChild(playBtn);
controls.appendChild(remBtn);
item.appendChild(controls);
}
return item; return item;
} }
@ -258,7 +187,6 @@ class Playlist {
text: message, text: message,
gravity: 'bottom', gravity: 'bottom',
position: 'right', position: 'right',
stopOnFocus: false,
style: { style: {
marginBottom: '10ex', marginBottom: '10ex',
background: '#090', background: '#090',