Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alphanumeric sort for Music-Library & Database #421

Merged
merged 3 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
- Fix(tui): change Theme preview to not reset to index 0 each preview.
- Fix(tui): not having the current theme selected when entering Theme preview tab.
- Fix(tui): actually report any errors when adding to the playlist. (Like "invalid file type")
- Fix(tui): sort Music-Library content Alphanumerically.

### [V0.9.1]
- Released on: August 21, 2024.
Expand Down
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ walkdir = "2.5"
wildmatch = "2.4"
ytd-rs = { version = "0.1", features = ["yt-dlp"] }
futures = "0.3"
alphanumeric-sort = "1.5"
# transistive dependency for some packages (like libsqlite), manually specified to upgrade the version, see https://github.com/rusqlite/rusqlite/issues/1543
cc = "1.1"

Expand Down
1 change: 1 addition & 0 deletions lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ tokio.workspace = true
tokio-util = { workspace = true, features = ["rt"] }
tonic.workspace = true
prost.workspace = true
alphanumeric-sort.workspace = true

[build-dependencies]
cc.workspace = true
Expand Down
18 changes: 14 additions & 4 deletions lib/src/library_db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,17 +246,22 @@ impl DataBase {
let conn = self.conn.lock();
let mut stmt = conn.prepare(&search_str)?;

let mut vec_records: Vec<TrackDB> = stmt
let mut vec_records: Vec<(String, TrackDB)> = stmt
.query_map([criteria_val], TrackDB::try_from_row_named)?
.flatten()
.map(|v| (get_pin_yin(&v.name), v))
.collect();

// Left for debug
// error!("criteria_val: {}", criteria_val);
// error!("criteria: {}", criteria);
// error!("vec: {:?}", vec_records);

vec_records.sort_by_cached_key(|k| get_pin_yin(&k.name));
// TODO: if SearchCriteria is "Album", maybe we should sort by album track index
// TODO: should we really do the search here in the libary?
vec_records.sort_by(|a, b| alphanumeric_sort::compare_str(&a.0, &b.0));

let vec_records = vec_records.into_iter().map(|v| v.1).collect();
Ok(vec_records)
}

Expand All @@ -266,15 +271,20 @@ impl DataBase {
let conn = self.conn.lock();
let mut stmt = conn.prepare(&search_str)?;

let mut vec: Vec<String> = stmt
// tuple.0 is the sort key, and tuple.1 is the actual value
let mut vec: Vec<(String, String)> = stmt
.query_map([], |row| {
let criteria: String = row.get(0)?;
Ok(criteria)
})?
.flatten()
.map(|v| (get_pin_yin(&v), v))
.collect();

vec.sort_by_cached_key(|k| get_pin_yin(k));
// TODO: should we really do the search here in the libary?
vec.sort_by(|a, b| alphanumeric_sort::compare_str(&a.0, &b.0));

let vec = vec.into_iter().map(|v| v.1).collect();
Ok(vec)
}

Expand Down
1 change: 1 addition & 0 deletions tui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ tokio-stream.workspace = true
futures.workspace = true
reqwest.workspace = true
parking_lot.workspace = true
alphanumeric-sort.workspace = true


[features]
Expand Down
23 changes: 13 additions & 10 deletions tui/src/ui/components/music_library.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::ui::{Id, LIMsg, Model, Msg, TEMsg, YSMsg};
use crate::utils::get_pin_yin;
use anyhow::{bail, Context, Result};
use std::fs::{remove_dir_all, remove_file, rename};
use std::fs::{remove_dir_all, remove_file, rename, DirEntry};
use std::path::{Path, PathBuf};
use termusiclib::config::v2::server::config_extra::ServerConfigVersionedDefaulted;
use termusiclib::config::v2::server::ScanDepth;
Expand Down Expand Up @@ -266,17 +266,16 @@ impl Model {

if depth > 0 && p.is_dir() {
if let Ok(paths) = std::fs::read_dir(p) {
let mut paths: Vec<_> = paths
let mut paths: Vec<(String, PathBuf)> = paths
.filter_map(std::result::Result::ok)
.filter(|p| !p.file_name().to_string_lossy().starts_with('.'))
.map(|v| (get_pin_yin(&v.file_name().to_string_lossy()), v.path()))
.collect();

paths.sort_by_cached_key(|k| get_pin_yin(&k.file_name().to_string_lossy()));
paths.sort_by(|a, b| alphanumeric_sort::compare_str(&a.0, &b.0));

for p in paths {
node.add_child(Self::library_dir_tree(
p.path().as_path(),
ScanDepth::Limited(depth - 1),
));
node.add_child(Self::library_dir_tree(&p.1, ScanDepth::Limited(depth - 1)));
}
}
}
Expand All @@ -286,10 +285,14 @@ impl Model {
let mut children: Vec<String> = vec![];
if p.is_dir() {
if let Ok(paths) = std::fs::read_dir(p) {
let mut paths: Vec<_> = paths.filter_map(std::result::Result::ok).collect();
let mut paths: Vec<(String, DirEntry)> = paths
.filter_map(std::result::Result::ok)
.map(|v| (get_pin_yin(&v.file_name().to_string_lossy()), v))
.collect();

paths.sort_by_cached_key(|k| get_pin_yin(&k.file_name().to_string_lossy()));
for p in paths {
paths.sort_by(|a, b| alphanumeric_sort::compare_str(&a.0, &b.0));

for (_, p) in paths {
if !p.path().is_dir() {
children.push(String::from(p.path().to_string_lossy()));
}
Expand Down
Loading