mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
feat(search): add workspace global search with M3U support
Moves global search into a routed workspace view, adds M3U live/radio results, lazy pagination, and DB-backed matching improvements.
This commit is contained in:
1 parent
ffc07146fe
commit
89916af9d8
65 files changed
+3010
-391
No files matched your search
@@ -203,6 +203,56 @@ state handlers that still used direct main-thread SQLite access.
|
||||
6. `DB_GLOBAL_SEARCH`
|
||||
7. `DB_GET_GLOBAL_RECENTLY_ADDED`
|
||||
|
||||
`DB_GLOBAL_SEARCH` returns a shared global-search result union rather than an
|
||||
Xtream-only row shape:
|
||||
|
||||
1. `source_type = "xtream"` rows come from the normalized `content` and
|
||||
`categories` tables joined with `playlists`. Xtream title matching uses
|
||||
`content_title_fts`, an FTS5 trigram index over `content.title`, for search
|
||||
terms with at least one 3+ character token. Tokens are quoted before being
|
||||
passed to `MATCH`, so FTS reserved words such as `and` are treated as search
|
||||
text instead of degrading to the slow fallback path. SQL prefilters keep both
|
||||
raw lower-case tokens and accent-normalized tokens, so an accented query such
|
||||
as `Café` can still reach rows stored as either `Café` or `Cafe` before the
|
||||
worker's accent-insensitive ranking step. Existing databases rebuild this
|
||||
index once through the `migration:content-title-fts-trigram:v1` app-state
|
||||
marker before legacy content cleanup/normalization migrations run; fresh
|
||||
inserts, deletes, and title updates stay synchronized through SQLite triggers.
|
||||
2. `source_type = "m3u"` rows come from M3U playlist payloads stored in
|
||||
`playlists.payload`. The worker uses SQL `payload LIKE` against channel
|
||||
`name`/`title` JSON fields only as a coarse candidate prefilter, then parses
|
||||
candidate JSON payloads and matches channel name, TVG name, and group title
|
||||
case-insensitively in the worker. M3U payload prefilters also preserve raw
|
||||
accented token variants next to normalized variants. The SQL candidate query
|
||||
is capped by the same stable 5000-row candidate limit used for Xtream search,
|
||||
so large
|
||||
matching M3U payloads are not loaded without an upper bound.
|
||||
3. The optional `sources` argument can restrict search to `xtream` or `m3u`,
|
||||
but omitted callers keep the backward-compatible behavior of searching all
|
||||
supported global-search sources.
|
||||
4. The optional pagination argument accepts `{ limit, offset }`. The worker
|
||||
keeps the legacy default of 50 results when the argument is omitted, but the
|
||||
routed global-search view requests one extra row per page to implement
|
||||
lazy loading without requiring a separate count query. Candidate selection
|
||||
uses a stable max-size pool for every page so score-based in-memory ranking
|
||||
cannot shift already-rendered items into later pages.
|
||||
5. Candidate rows are ranked in the worker after the coarse SQL prefilter.
|
||||
Exact and prefix matches sort ahead of word-prefix and substring matches;
|
||||
short first tokens such as `tv` stay anchored to the start of the title, so
|
||||
`TV Sport` matches but `Test TV` does not. These short first-token queries
|
||||
bypass trigram FTS and use the `idx_content_title` prefix index path because
|
||||
trigram tokenization cannot match 1-2 character terms.
|
||||
6. `excludeHidden` still filters hidden Xtream categories and also filters M3U
|
||||
channels whose `group.title` is listed in the playlist payload's
|
||||
`hiddenGroupTitles`.
|
||||
7. M3U radio entries are returned as live results with `radio = "true"` and the
|
||||
serialized `Channel` attached for renderer playback routing. M3U global
|
||||
search rows are not Xtream content rows: they use `xtream_id = -1`, and
|
||||
Xtream-only metadata such as `rating`, `added`, and a missing `poster_url`
|
||||
is represented as `null`.
|
||||
8. EPG-program text is not part of this contract; EPG search remains a separate
|
||||
feature because it uses different persistence and freshness rules.
|
||||
|
||||
### Playlist metadata
|
||||
|
||||
1. `DB_CREATE_PLAYLIST`
|
||||
@@ -288,7 +338,8 @@ to `epg-worker.service.ts`.
|
||||
Xtream search now guards against stale async responses:
|
||||
|
||||
1. local playlist search uses a monotonically increasing request version
|
||||
2. global search uses a separate request version in the dialog component
|
||||
2. global search uses a separate request version in the routed workspace search
|
||||
component
|
||||
3. clearing search invalidates older pending results
|
||||
|
||||
This prevents an older worker response from repainting over a newer query or a
|
||||
|
||||
Reference in new issue
Block a user