playlists + lyrics: setlists with pages of their own, and the words timed to the voice
This commit is contained in:
1 parent
c4ff6269a3
commit
df3d15553a
49 files changed
+14419
-599
No files matched your search
@@ -6,6 +6,7 @@ rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
soulseek-proto = { path = "../soulseek-proto" }
|
||||
audio-formats = { path = "../audio-formats" }
|
||||
tokio.workspace = true
|
||||
tokio-util = "0.7"
|
||||
bytes.workspace = true
|
||||
|
||||
@@ -93,8 +93,11 @@ async fn run_parent(inner: &Arc<Inner>, mut stream: TcpStream) -> std::io::Resul
|
||||
responder::respond_to_search(inner.clone(), username, token, query);
|
||||
}
|
||||
Ok(dist::DistributedEvent::BranchLevel(level)) => {
|
||||
// Report our level (parent + 1) to the server.
|
||||
let _ = inner.send_server(server::branch_level(level + 1));
|
||||
// Report our level (parent + 1) to the server. Saturating: the
|
||||
// level is a peer-supplied u32, and one parent really did send
|
||||
// a value at the top of the range — `+ 1` panicked this worker
|
||||
// (debug overflow checks) mid-session on 2026-08-14.
|
||||
let _ = inner.send_server(server::branch_level(level.saturating_add(1)));
|
||||
}
|
||||
Ok(dist::DistributedEvent::BranchRoot(root)) => {
|
||||
let _ = inner.send_server(server::branch_root(&root));
|
||||
|
||||
@@ -11,9 +11,10 @@ use std::sync::RwLock;
|
||||
|
||||
use soulseek_proto::types::{Directory, File};
|
||||
|
||||
const AUDIO_EXTS: [&str; 10] = [
|
||||
"flac", "mp3", "m4a", "ogg", "opus", "wav", "aac", "wma", "ape", "aiff",
|
||||
];
|
||||
// Shared with the library scanner and the row pruner (`audio-formats`). The
|
||||
// share index deliberately offers formats this app cannot itself PLAY — a peer
|
||||
// asking for `.ape` is well served by a file we hold, and refusing to share it
|
||||
// helps nobody.
|
||||
|
||||
/// One shared file: its remote (virtual) path and where it lives locally.
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -161,8 +162,14 @@ fn walk(dir: &Path, base: &str, root: &Path, index: &mut Index) {
|
||||
let path = entry.path();
|
||||
if path.is_dir() {
|
||||
// The download staging pen is not part of anyone's library —
|
||||
// half-finished transfers are not shareable records.
|
||||
if path.file_name().is_some_and(|n| n == "(Cache)") {
|
||||
// half-finished transfers are not shareable records. `.soulstream`
|
||||
// holds the library's own database, review session and artwork
|
||||
// cache; only audio is ever indexed, so it could not be served
|
||||
// anyway, but it has no business appearing in a browse listing.
|
||||
if path
|
||||
.file_name()
|
||||
.is_some_and(|n| n == "(Cache)" || n == ".soulstream")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
walk(&path, base, root, index);
|
||||
@@ -203,10 +210,7 @@ fn to_remote_path(path: &Path, base: &str, root: &Path) -> String {
|
||||
}
|
||||
|
||||
fn is_audio(path: &Path) -> bool {
|
||||
path.extension()
|
||||
.and_then(|e| e.to_str())
|
||||
.map(|e| AUDIO_EXTS.contains(&e.to_ascii_lowercase().as_str()))
|
||||
.unwrap_or(false)
|
||||
audio_formats::is_audio_path(path)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in new issue
Block a user