Skip to content

Commit 4885926

Browse files
committed
Play all MP3s button, refs #2
1 parent 00dc11c commit 4885926

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

datasette_mp3_audio/__init__.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22
from markupsafe import Markup, escape
33

44

5+
@hookimpl
6+
def extra_js_urls(columns, datasette):
7+
if not columns:
8+
return None
9+
return [
10+
datasette.urls.static_plugins("datasette-mp3-audio", "datasette-mp3-audio.js")
11+
]
12+
13+
514
@hookimpl
615
def render_cell(value):
716
if not isinstance(value, str):
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
document.addEventListener("DOMContentLoaded", () => {
2+
let currentlyPlaying = null;
3+
function playAllAudios() {
4+
let audios = Array.from(document.querySelectorAll('audio'));
5+
function playNext() {
6+
if (!audios.length) {
7+
return;
8+
}
9+
currentlyPlaying = audios.shift();
10+
let listener = () => { playNext(); }
11+
currentlyPlaying.endedListener = listener;
12+
currentlyPlaying.addEventListener('ended', listener);
13+
currentlyPlaying.play();
14+
}
15+
playNext();
16+
}
17+
18+
const audios = document.querySelectorAll('audio');
19+
if (audios.length < 2) {
20+
// Not enough audio elements
21+
return;
22+
}
23+
// Add a button to play all
24+
const button = document.createElement('button');
25+
button.setAttribute('type', 'button');
26+
// Datasette button CSS looks for form button[type=button]
27+
const form = document.createElement('form');
28+
form.style.marginBottom = '1em';
29+
form.appendChild(button);
30+
button.innerText = `Play all ${audios.length} MP3s`;
31+
let isPlaying = false;
32+
button.addEventListener('click', () => {
33+
if (!isPlaying) {
34+
// First clean up any previous endedListener
35+
audios.forEach(el => {
36+
el.currentTime = 0;
37+
if (el.endedListener) {
38+
el.removeEventListener('ended', el.endedListener);
39+
}
40+
});
41+
playAllAudios();
42+
isPlaying = true;
43+
button.innerText = `Playing all ${audios.length} MP3s - Stop`;
44+
} else {
45+
if (currentlyPlaying) {
46+
currentlyPlaying.pause();
47+
}
48+
isPlaying = false;
49+
button.innerText = `Play all ${audios.length} MP3s`;
50+
}
51+
});
52+
const tableWrapper = document.querySelector('.table-wrapper');
53+
tableWrapper.parentNode.insertBefore(form, tableWrapper);
54+
});

setup.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,10 @@ def get_long_description():
3434
entry_points={"datasette": ["mp3_audio = datasette_mp3_audio"]},
3535
install_requires=["datasette"],
3636
extras_require={"test": ["pytest", "pytest-asyncio", "sqlite-utils"]},
37+
package_data={
38+
"datasette_mp3_audio": [
39+
"static/*.js",
40+
],
41+
},
3742
python_requires=">=3.7",
3843
)

0 commit comments

Comments
 (0)