srctree

Gregory Mullen parent b4abb8c2 8789d3c8
add ability to list all files via www client

client/main.zig added: 88, removed: 9, total 79
@@ -183,6 +183,14 @@ fn updateDb(
try db.albums.reIndex(gpa);
}
 
export fn files_len() usize {
return db.files.entries.len;
}
 
export fn file_name(index: u32) String {
return String.init(db.stringToSlice(db.files.keys()[index].basename));
}
 
export fn albums_len() usize {
return db.albums.entries.len;
}
@@ -191,6 +199,11 @@ export fn album_title(index: u32) String {
return String.init(db.optStringToSlice(db.albums.keys()[index].title) orelse "");
}
 
export fn enqueueFile(index: Db.File.Index) void {
const message: protocol.EnqueueFile = .{ .file_index = index };
send(std.mem.asBytes(&message));
}
 
export fn enqueueAlbum(index: Db.Album.Index) void {
const message: protocol.EnqueueAlbum = .{ .album_index = index };
send(std.mem.asBytes(&message));
 
server/main.zig added: 88, removed: 9, total 79
@@ -242,6 +242,7 @@ pub const Server = struct {
const msg = try ws.readSmallMessage();
const cmd = try messageEnum(msg, protocol.Command);
switch (cmd) {
.enqueue_file => std.log.err("TODO implement enqueue_file", .{}),
.enqueue_album => {
// TODO don't access db without a held lock
const album_index = try messageIndex(msg[1..], s.db, Db.Album.Index);
 
shared/protocol.zig added: 88, removed: 9, total 79
@@ -64,6 +64,7 @@ pub const PlayQueueHeader = extern struct {
};
 
pub const Command = enum(u8) {
enqueue_file,
enqueue_album,
pause,
unpause,
@@ -72,6 +73,10 @@ pub const Command = enum(u8) {
_,
};
 
pub const EnqueueFile = extern struct {
command: Command = .enqueue_file,
file_index: Db.File.Index align(1),
};
pub const EnqueueAlbum = extern struct {
command: Command = .enqueue_album,
album_index: Db.Album.Index align(1),
 
www/index.html added: 88, removed: 9, total 79
@@ -79,8 +79,9 @@ body {
<div id="sectLibrary" class="hidden">
<h2>Library</h2>
<select id="organize">
<option>Artist / Album / Song</option>
<option selected="selected">Album / Song</option>
<option>Artist / Album / Song</option>
<option>All Files</option>
</select>
<ul id="listLibrary">
</ul>
 
www/main.js added: 88, removed: 9, total 79
@@ -18,6 +18,7 @@
let ws = null;
let wasm_exports = null;
let prevFileIndex = null;
let library_view = "album";
const text_decoder = new TextDecoder();
const text_encoder = new TextEncoder();
 
@@ -164,7 +165,20 @@
domSectQueue.classList.remove("hidden");
}
 
function renderLibraryUi() {
function renderLibraryUiArtists() {
const artists_len = wasm_exports.artists_len();
resizeDomList(domListLibrary, artists_len, '<li></li>');
 
for (let i = 0; i < artists_len; i += 1) {
const dbName = unwrapString(wasm_exports.artist_name(i));
const name = (dbName.length == 0) ? "[Unknown Artist]" : dbName;
const liDom = domListLibrary.children[i];
liDom.textContent = name;
liDom.attributes['data-id'] = 'r' + i;
}
}
 
function renderLibraryUiAlbums() {
const albums_len = wasm_exports.albums_len();
 
resizeDomList(domListLibrary, albums_len, '<li></li>');
@@ -176,6 +190,31 @@
liDom.textContent = title;
liDom.attributes['data-id'] = 'a' + i;
}
}
 
function renderLibraryUiFiles() {
const files_len = wasm_exports.files_len();
resizeDomList(domListLibrary, files_len, '<li></li>');
 
for (let i = 0; i < files_len; i += 1) {
const dbName = unwrapString(wasm_exports.file_name(i));
const name = (dbName.length == 0) ? "[Error in filename]" : dbName;
const liDom = domListLibrary.children[i];
liDom.textContent = name;
liDom.attributes['data-id'] = 'f' + i;
}
}
 
function renderLibraryUi() {
if (library_view == "album") {
renderLibraryUiAlbums();
} else if (library_view == "artist") {
renderLibraryUiArtists();
} else if (library_view == "file") {
renderLibraryUiFiles();
} else {
console.log("unhandled library_view");
}
 
domSectLibrary.classList.remove("hidden");
}
@@ -203,12 +242,32 @@
renderPlaybackUi();
}
 
function onClickOrganize(ev) {
const elm = ev.srcElement;
if (elm.text == "Artist / Album / Song") {
library_view = "artist";
} else if (elm.text == "Album / Song") {
library_view = "album";
} else if (elm.text == "All Files") {
library_view = "file";
} else {
console.log("unknown element '" + ev.srcElement.text + "'");
}
renderLibraryUi()
}
 
function onClickLibrary(ev) {
const id = ev.srcElement.attributes['data-id'];
if (id == null) return;
if (id[0] == 'a') {
const albumIndex = +id.substring(1);
wasm_exports.enqueueAlbum(albumIndex);
const album_index = +id.substring(1);
wasm_exports.enqueueAlbum(album_index);
} else if (id[0] == 'r') {
const artist_index = +id.substring(1);
wasm_exports.enqueueArtist(artist_index);
} else if (id[0] == 'f') {
const file_index = +id.substring(1);
wasm_exports.enqueueFile(file_index);
}
}