158 lines
5.6 KiB
Plaintext
158 lines
5.6 KiB
Plaintext
<div class="row-between">
|
|
<h1>My Music · Songs</h1>
|
|
<a href="/mymusic/songs/new" class="btn-primary">Upload song</a>
|
|
</div>
|
|
|
|
<nav class="tabs">
|
|
<a href="/mymusic/songs" class="active">Songs</a>
|
|
<a href="/mymusic/playlists">Playlists</a>
|
|
</nav>
|
|
|
|
<% if (songs.length === 0) { %>
|
|
<p class="muted">No songs yet.</p>
|
|
<% } else { %>
|
|
|
|
<div id="bulk-toolbar" style="display:none">
|
|
<span><span id="bulk-count">0</span> selected</span>
|
|
<div class="bulk-dropdown">
|
|
<button type="button" id="bulk-add-btn" class="btn-secondary">Add to Playlist ▼</button>
|
|
<ul class="bulk-menu" id="bulk-menu">
|
|
<li><a id="bulk-new-playlist" href="#">+ New Playlist</a></li>
|
|
<li class="has-submenu">
|
|
<span>Existing Playlist</span>
|
|
<ul class="bulk-submenu">
|
|
<% playlists.forEach(function(pl) { %>
|
|
<li><a class="bulk-pl-item" data-playlist-id="<%= pl.id %>" href="#"><%= pl.title %></a></li>
|
|
<% }) %>
|
|
<% if (!playlists.length) { %>
|
|
<li class="bulk-submenu-empty">No playlists yet</li>
|
|
<% } %>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<table class="data-table">
|
|
<thead>
|
|
<tr>
|
|
<th class="col-check"><input type="checkbox" id="select-all" title="Select all"></th>
|
|
<th>Title</th><th>Artist</th><th>Album</th><th>Visibility</th><th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<% songs.forEach((s) => { %>
|
|
<tr>
|
|
<td class="col-check"><input type="checkbox" class="song-select" value="<%= s.id %>"></td>
|
|
<td><a href="/songs/<%= s.slug %>"><%= s.title %></a></td>
|
|
<td><%= s.artist %></td>
|
|
<td><%= s.album || '' %></td>
|
|
<td>
|
|
<% if (s.visibility === 'logged_in') { %>
|
|
<span class="badge badge-logged-in">Members</span>
|
|
<% } else if (s.visibility === 'private') { %>
|
|
<span class="badge badge-private">Private</span>
|
|
<% } else { %>
|
|
<span class="badge badge-public">Public</span>
|
|
<% } %>
|
|
</td>
|
|
<td class="actions">
|
|
<a href="/mymusic/songs/<%= s.id %>/edit">Edit</a>
|
|
<form method="post" action="/mymusic/songs/<%= s.id %>/delete" class="inline-form" onsubmit="return confirm('Delete this song?');">
|
|
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
|
|
<button type="submit" class="linklike danger">Delete</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
<% }) %>
|
|
</tbody>
|
|
</table>
|
|
|
|
<script>
|
|
(function () {
|
|
var toolbar = document.getElementById('bulk-toolbar');
|
|
var countSpan = document.getElementById('bulk-count');
|
|
var addBtn = document.getElementById('bulk-add-btn');
|
|
var menu = document.getElementById('bulk-menu');
|
|
var newBtn = document.getElementById('bulk-new-playlist');
|
|
var selectAll = document.getElementById('select-all');
|
|
var csrfToken = (document.querySelector('meta[name="csrf-token"]') || {}).content || '';
|
|
|
|
function allBoxes() { return document.querySelectorAll('.song-select'); }
|
|
function checkedBoxes(){ return document.querySelectorAll('.song-select:checked'); }
|
|
function getIds() { return Array.from(checkedBoxes()).map(function(el){ return el.value; }); }
|
|
|
|
function updateToolbar() {
|
|
var checked = checkedBoxes().length;
|
|
var total = allBoxes().length;
|
|
toolbar.style.display = checked ? '' : 'none';
|
|
countSpan.textContent = checked;
|
|
selectAll.indeterminate = checked > 0 && checked < total;
|
|
selectAll.checked = checked > 0 && checked === total;
|
|
}
|
|
|
|
document.addEventListener('change', function(e) {
|
|
if (e.target.matches('#select-all')) {
|
|
var state = e.target.checked;
|
|
allBoxes().forEach(function(cb){ cb.checked = state; });
|
|
}
|
|
if (e.target.matches('.song-select') || e.target.matches('#select-all')) {
|
|
updateToolbar();
|
|
}
|
|
});
|
|
|
|
addBtn.addEventListener('click', function(e) {
|
|
e.stopPropagation();
|
|
menu.classList.toggle('open');
|
|
});
|
|
|
|
document.addEventListener('click', function() {
|
|
menu.classList.remove('open');
|
|
});
|
|
|
|
newBtn.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
var ids = getIds();
|
|
if (!ids.length) return;
|
|
window.location.href = '/mymusic/playlists/new?songs=' + ids.join(',');
|
|
});
|
|
|
|
document.addEventListener('click', function(e) {
|
|
var item = e.target.closest('.bulk-pl-item');
|
|
if (!item) return;
|
|
e.preventDefault();
|
|
var playlistId = item.dataset.playlistId;
|
|
var songIds = getIds();
|
|
if (!songIds.length || !playlistId) return;
|
|
var body = new URLSearchParams({ playlistId: playlistId, _csrf: csrfToken });
|
|
songIds.forEach(function(id){ body.append('songIds[]', id); });
|
|
fetch('/mymusic/songs/bulk-add', { method: 'POST', body: body })
|
|
.then(function(r){ return r.json(); })
|
|
.then(function(data) {
|
|
if (data.ok) {
|
|
allBoxes().forEach(function(cb){ cb.checked = false; });
|
|
selectAll.checked = false;
|
|
updateToolbar();
|
|
showToast('Added ' + data.added + ' song' + (data.added === 1 ? '' : 's') + ' to playlist');
|
|
}
|
|
})
|
|
.catch(function(err){ console.error(err); });
|
|
menu.classList.remove('open');
|
|
});
|
|
|
|
function showToast(msg) {
|
|
var t = document.createElement('div');
|
|
t.className = 'bulk-toast';
|
|
t.textContent = msg;
|
|
document.body.appendChild(t);
|
|
setTimeout(function(){ t.classList.add('visible'); }, 10);
|
|
setTimeout(function(){
|
|
t.classList.remove('visible');
|
|
setTimeout(function(){ t.remove(); }, 300);
|
|
}, 2800);
|
|
}
|
|
})();
|
|
</script>
|
|
|
|
<% } %>
|