Skip to content

feat(library): sort artists and albums without their leading article - #838

Merged
InstaZDLL merged 1 commit into
mainfrom
feat/sort-ignore-articles
Oct 11, 2026
Merged

InstaZDLL merged 1 commit into
mainfrom
feat/sort-ignore-articles

Conversation

@InstaZDLL

@InstaZDLL InstaZDLL commented Oct 11, 2026 •

Copy link
Copy Markdown
Owner

What

Artist and album listings now set a leading article aside: "The Beatles" sorts under B, "Les Rita Mitsouko" under R, "L'Impératrice" under I. Settings → Library → "Ignore articles when sorting" turns it off (on by default, app-wide).

  • NAME collation in collation.rs, next to FOLD: FOLD on the name without its leading article, then on the full name, so "Kills" and "The Kills" keep a total order. Off, it is FOLD. It replaces FOLD on ar.canonical_name, al.canonical_title and the sort_artist / sort_album / sort_name / sort_title aliases built from them. Track titles, genres and folders keep FOLD.
  • Articles: the a an le la les l der die das het el los las il lo gli. Dutch de is left out on purpose: it is as often a particle of a name ("De La Soul") as an article.
  • Canonical keys. The listings sort on canonical_name, which turns punctuation into spaces: "L'Impératrice" is stored l impératrice, so the elided l is a word like the others. The known cost: "A-ha", stored a ha, files under H.
  • One process-wide flag, read on every comparison, loaded at boot before the first listing and set by set_sort_ignore_articles after the row is saved. No index uses the collation, so flipping it changes nothing stored.
  • Frontend. useSortIgnoreArticles (module store, published once the save lands, saves serialized) adds the flag to LibraryView's fetch signature so every tab refetches; AlphabetIndex files names with sortName.ts, the TypeScript copy of strip_article, applied to the same canonical key, so the rail and the list agree.

Docs: library.md, plus one line of RFC-005. 2 keys in all 17 locales.

Testing

  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test -p waveflow-core --features sqlite: 10 collation tests, including a SQLite round-trip through the registered collation.
  • bun run typecheck, bun run lint
  • Manual test on Windows: artists and albums tabs, A–Z rail, toggling the setting.

Summary by CodeRabbit

  • Nouvelles fonctionnalités
    • Ajout d’un réglage permettant d’ignorer les articles initiaux lors du tri des artistes et des albums. Il est activé par défaut.
    • Le rail alphabétique suit le même réglage.
  • Améliorations
    • Le tri des artistes et des albums tient mieux compte des accents et de la casse. Lorsque les articles sont ignorés, les noms complets départagent les égalités.
    • La modification du réglage recharge les listes concernées.

A NAME collation, FOLD on the name without a leading article (the, a, an, le, la, les, l, der, die, das, het, el, los, las, il, lo, gli), orders artist and album listings; track titles, genres and folders keep FOLD. Settings > Library toggles it (on by default, app_setting library.sort_ignore_articles), the A-Z rail files names under the same letter, and the library view refetches when it changes.
@InstaZDLL InstaZDLL added scope: frontend React/Vite frontend (src/) scope: backend Rust/Tauri backend (src-tauri/) scope: i18n Translations (src/i18n/) scope: docs Docs, README, assets type: feat New feature size: xl > 500 lines labels Oct 11, 2026
@coderabbitai

coderabbitai Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: InstaZDLL/WaveFlow/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: b83a8259-ece5-46ea-9ff2-e4199639e751

📥 Commits

Reviewing files that changed from the base of the PR and between 0ef7dc6 and 11fd052.


⛔ Files ignored due to path filters (17)
  • src/i18n/locales/ar.json is excluded by !src/i18n/locales/**
  • src/i18n/locales/de.json is excluded by !src/i18n/locales/**
  • src/i18n/locales/en.json is excluded by !src/i18n/locales/**
  • src/i18n/locales/es.json is excluded by !src/i18n/locales/**
  • src/i18n/locales/fr.json is excluded by !src/i18n/locales/**
  • src/i18n/locales/hi.json is excluded by !src/i18n/locales/**
  • src/i18n/locales/id.json is excluded by !src/i18n/locales/**
  • src/i18n/locales/it.json is excluded by !src/i18n/locales/**
  • src/i18n/locales/ja.json is excluded by !src/i18n/locales/**
  • src/i18n/locales/ko.json is excluded by !src/i18n/locales/**
  • src/i18n/locales/nl.json is excluded by !src/i18n/locales/**
  • src/i18n/locales/pt-BR.json is excluded by !src/i18n/locales/**
  • src/i18n/locales/pt.json is excluded by !src/i18n/locales/**
  • src/i18n/locales/ru.json is excluded by !src/i18n/locales/**
  • src/i18n/locales/tr.json is excluded by !src/i18n/locales/**
  • src/i18n/locales/zh-CN.json is excluded by !src/i18n/locales/**
  • src/i18n/locales/zh-TW.json is excluded by !src/i18n/locales/**

📒 Files selected for processing (15)
  • docs/features/library.md
  • docs/rfcs/RFC-005-remote-source-and-sync-v2.md
  • src-tauri/crates/app/src/commands/browse.rs
  • src-tauri/crates/app/src/commands/preferences.rs
  • src-tauri/crates/app/src/commands/track.rs
  • src-tauri/crates/app/src/lib.rs
  • src-tauri/crates/core/src/repository/sqlite/collation.rs
  • src-tauri/crates/core/src/repository/sqlite/track.rs
  • src/components/common/AlphabetIndex.tsx
  • src/components/views/LibraryView.tsx
  • src/components/views/SettingsView.tsx
  • src/components/views/settings/settingsCatalog.ts
  • src/hooks/useSortIgnoreArticles.ts
  • src/lib/sortName.ts
  • src/lib/tauri/preferences.ts

Included review availability: This review used your included allowance. 3 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 4 reviews per hour.



📝 Walkthrough

Walkthrough

Le tri des artistes et des albums utilise désormais la collation NAME, qui peut ignorer les articles initiaux. Une préférence contrôle ce comportement. Le backend la persiste et l’applique à SQLite ; l’interface l’expose, recharge les listes concernées et adapte le rail alphabétique.

Changes

Tri des noms et intégration de la préférence

Layer / File(s) Summary
Collation des noms
src/lib/sortName.ts, src-tauri/crates/core/src/repository/sqlite/collation.rs
Ajout de stripArticle côté frontend et d’une collation SQLite NAME. Lorsque l’option est active, cette collation compare d’abord les noms sans article, puis les noms complets. Les tests couvrent les cas limites et l’ordre SQLite.
Utilisation de NAME dans les tris
src-tauri/crates/app/src/commands/browse.rs, src-tauri/crates/app/src/commands/track.rs, src-tauri/crates/core/src/repository/sqlite/track.rs, docs/features/library.md, docs/rfcs/RFC-005-remote-source-and-sync-v2.md
Les tris des artistes et des albums ainsi que plusieurs tris de pistes, de résultats de recherche et de listes unifiées utilisent NAME à la place de FOLD. Les critères secondaires concernés restent en place. La documentation décrit ces changements ; les titres de pistes, genres et dossiers conservent FOLD.
Persistance et accès à la préférence
src-tauri/crates/app/src/commands/preferences.rs, src-tauri/crates/app/src/lib.rs, src/lib/tauri/preferences.ts, src/hooks/useSortIgnoreArticles.ts
Le backend charge la préférence au démarrage, fournit les commandes de lecture et d’écriture, et met à jour la collation après une écriture réussie. Le frontend expose ces commandes avec un hook qui charge et sérialise les mises à jour.
Réglage et actualisation de l’interface
src/components/views/SettingsView.tsx, src/components/views/settings/settingsCatalog.ts, src/components/views/LibraryView.tsx, src/components/common/AlphabetIndex.tsx
La vue des réglages ajoute le commutateur et ses clés de recherche. La signature de rechargement des bibliothèques dépend de la préférence. Le rail alphabétique retire aussi les articles lorsque l’option est active.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant SettingsView
  participant useSortIgnoreArticles
  participant preferences.ts
  participant Tauri
  participant app_setting
  participant SQLite NAME
  SettingsView->>useSortIgnoreArticles: demande le changement de préférence
  useSortIgnoreArticles->>preferences.ts: persiste la nouvelle valeur
  preferences.ts->>Tauri: appelle set_sort_ignore_articles
  Tauri->>app_setting: enregistre la valeur
  Tauri->>SQLite NAME: applique la valeur après réussite
  SQLite NAME-->>useSortIgnoreArticles: confirme la réussite de l’écriture
  useSortIgnoreArticles-->>SettingsView: publie la nouvelle valeur
Loading

Merge Risk | ⚪ Minimal · up to 11fd0

Merge Risk: ⚪ Minimal · up to 11fd0

The change adds article-aware sorting for artists and albums, on by default with a setting to turn it off. No actionable merge-blocking risk was found in the supplied material.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 11fd0

The setting changes library ordering rather than access permissions. Concurrent updates can leave saved and active sorting inconsistent, but the reviewed effects are confined to presentation. No privilege expansion was found in the reviewed paths.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • observed — The new preference authority is app-wide: a caller able to invoke the setter can change ordering for all NAME consumers in the application process, not just one library tab. Its write authority is limited to the fixed boolean preference row.

Trust Boundaries and Controls

  • observed — The changed browse ordering paths preserve the existing SQL-construction boundary: unrecognized sort keys fall back to defaults, directions reduce to ASC/DESC, and filter values are bound. The new preference command likewise uses fixed SQL with bound values rather than exposing a general database mutation interface.

Resilience and Maintainability Implications

  • inferred — For a single setter invocation, a failed database save returns before changing live sorting. If the process terminates after commit but before publication, the next startup reloads the committed row. The inspected NAME consumers affect returned ordering, and the collation documents that no stored index depends on it, containing the identified transition limitations to presentation state.

Pre-merge checks | Passed 4 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 76.09% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 46 functions across 13 files. (2 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check Passed Le titre est concis, respecte le format Conventional Commits et décrit clairement la modification principale du tri des artistes et des albums.
Description check Passed La description présente le comportement, les choix techniques, les mises à jour de documentation et les validations exécutées. Elle ne reprend pas les sections formelles « Checklist » et « Linked issu…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.

Full details: Docstring Coverage

Explanation

Docstring coverage is 76.09% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 46 functions across 13 files. (2 skipped: 2 unsupported.)


  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR


🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@InstaZDLL InstaZDLL self-assigned this Oct 11, 2026
@InstaZDLL
InstaZDLL merged commit bcff313 into main Oct 11, 2026
17 checks passed
@InstaZDLL
InstaZDLL deleted the feat/sort-ignore-articles branch October 11, 2026 18:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: backend Rust/Tauri backend (src-tauri/) scope: docs Docs, README, assets scope: frontend React/Vite frontend (src/) scope: i18n Translations (src/i18n/) size: xl > 500 lines type: feat New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant