diff --git a/app/api/scenes.py b/app/api/scenes.py index 4a75c8f..48922e4 100644 --- a/app/api/scenes.py +++ b/app/api/scenes.py @@ -83,6 +83,13 @@ def list_scenes( "po PlaybackSource.quality (string typu '720p' / '1080p Full HD')." ), ), + origin: str | None = Query( + default=None, + description=( + "Filtruj po playback origin (np. 'tube:hqpornercom'). Substring match — " + "'hqporner' złapie tube:hqpornercom. Diagnostyka per-hoster." + ), + ), include_stubs: bool = Query( default=False, description=( @@ -164,6 +171,18 @@ def list_scenes( ) ) + if origin: + # Substring match na origin — 'hqporner' złapie 'tube:hqpornercom'. + base = base.where( + exists( + select(1).where( + PlaybackSource.scene_id == Scene.id, + PlaybackSource.dead_at.is_(None), + PlaybackSource.origin.ilike(f"%{origin}%"), + ) + ) + ) + # Blacklisty — globalne wykluczenia. Jeśli scena ma JAKIEGOKOLWIEK blacklisted # performera, jest na blacklisted studio, lub ma JAKIKOLWIEK blacklisted tag → out. from app.models.blacklist import ( diff --git a/mobile/src/api.ts b/mobile/src/api.ts index 9cbae96..c8de20f 100644 --- a/mobile/src/api.ts +++ b/mobile/src/api.ts @@ -116,6 +116,7 @@ export class GoonClient { qs.set('released_within_days', String(params.released_within_days)); if (params.min_quality_p !== undefined) qs.set('min_quality_p', String(params.min_quality_p)); if (params.include_stubs !== undefined) qs.set('include_stubs', String(params.include_stubs)); + if (params.origin) qs.set('origin', params.origin); if (params.sort) qs.set('sort', params.sort); qs.set('page', String(params.page ?? 1)); qs.set('per_page', String(params.per_page ?? 50)); diff --git a/mobile/src/screens/ScenesFilterModal.tsx b/mobile/src/screens/ScenesFilterModal.tsx index 6b6b2bf..bd66af0 100644 --- a/mobile/src/screens/ScenesFilterModal.tsx +++ b/mobile/src/screens/ScenesFilterModal.tsx @@ -24,6 +24,7 @@ export interface FilterState { sort: ScenesSort; hasPlayback: boolean; includeStubs: boolean; + origin: string; } export const DEFAULT_FILTER: FilterState = { @@ -33,6 +34,7 @@ export const DEFAULT_FILTER: FilterState = { sort: 'created_at', hasPlayback: true, // default: ukryj sceny bez playback linka (kompletność > świeżość) includeStubs: false, // default: ukryj 5-10min hqporner trailery bez release_date + origin: '', // pusty = wszystkie źródła; substring match np. 'hqporner' }; const SORT_OPTIONS: { value: ScenesSort; label: string }[] = [ @@ -161,6 +163,18 @@ export function ScenesFilterModal({ +
+ setDraft({ ...draft, origin: v })} + placeholder="np. hqporner, porntrex, xnxx — puste = wszystkie" + placeholderTextColor={theme.muted} + autoCapitalize="none" + autoCorrect={false} + /> +
+
diff --git a/mobile/src/types.ts b/mobile/src/types.ts index 823a32c..5421a47 100644 --- a/mobile/src/types.ts +++ b/mobile/src/types.ts @@ -118,6 +118,7 @@ export interface ScenesListParams { released_within_days?: number; min_quality_p?: number; include_stubs?: boolean; + origin?: string; sort?: ScenesSort; page?: number; per_page?: number;