Neither search backend orders by *where* the query matched, so a mid-word hit could outrank a prefix one — typing "parks" surfaced "Sparks of Love" above "Parks and Recreation". Add `domain/search_rank.rs`, which sorts by match position (prefix → word-start → mid-word substring → no name match), then by media kind so a container outranks its own contents. The sort is stable, so each backend's own relevance still breaks ties it was never overruled on. `repository_search` applies it to both the instant cache result and the merged cache+server union, so the list does not reshuffle when server results land. Ranking lives in Rust because "a better match" is domain vocabulary, not presentation. On the frontend, the combined `tvShows` result group splits into separate Shows and Episodes groups so a show no longer competes with its own episodes for a slot, and a People group is added so searching an actor's name reaches their bio. A stored `tvShows` order expands in place, keeping the position an upgrading user chose for it.
13 lines
439 B
Rust
13 lines
439 B
Rust
//! Canonical, provider-neutral domain model — the single source of truth for
|
|
//! the app's core data shapes, shared with the frontend via generated bindings.
|
|
//!
|
|
//! Spec: docs/specs/frontend-domain-model.md
|
|
|
|
pub mod from_jellyfin;
|
|
pub mod media;
|
|
pub mod search_rank;
|
|
|
|
pub use from_jellyfin::{kind_from_jellyfin, stream_kind_from_jellyfin, ticks_to_ms};
|
|
pub use media::{MediaKind, StreamKind};
|
|
pub use search_rank::rank_search_results;
|