Files
k-tv/k-tv-frontend/lib/types.ts

330 lines
7.1 KiB
TypeScript

export interface ActivityEvent {
id: string;
timestamp: string;
event_type: string;
detail: string;
channel_id?: string;
}
export interface LogLine {
level: string;
target: string;
message: string;
timestamp: string;
}
export type ContentType = "movie" | "episode" | "short";
export type AccessMode = "public" | "private";
export type LogoPosition = "top_left" | "top_right" | "bottom_left" | "bottom_right";
export type FillStrategy = "best_fit" | "sequential" | "random" | "alternating" | "weighted" | "marathon";
export interface MediaFilter {
content_type?: ContentType | null;
genres: string[];
decade?: number | null;
tags: string[];
min_duration_secs?: number | null;
max_duration_secs?: number | null;
collections: string[];
series_names?: string[];
search_term?: string | null;
}
// Library browsing
export interface CollectionResponse {
id: string;
name: string;
collection_type?: string | null;
}
export interface SeriesResponse {
id: string;
name: string;
episode_count: number;
genres: string[];
year?: number | null;
}
export interface LibraryItemResponse {
id: string;
provider_id: string;
external_id: string;
title: string;
content_type: string;
duration_secs: number;
series_name?: string | null;
season_number?: number | null;
episode_number?: number | null;
year?: number | null;
genres: string[];
tags: string[];
collection_id?: string | null;
collection_name?: string | null;
collection_type?: string | null;
thumbnail_url?: string | null;
synced_at?: string | null;
}
export interface RotationPolicy {
cooldown_days?: number | null;
cooldown_generations?: number | null;
min_available_ratio: number;
}
export interface InterstitialRule {
pool_filter: MediaFilter;
strategy: FillStrategy;
min_gap_secs: number;
}
export interface MidRollRule {
prefer_chapters: boolean;
fallback_interval_mins: number;
break_duration_secs: number;
pool_filter: MediaFilter;
}
export type BlockContent =
| { type: "algorithmic"; filter: MediaFilter; strategy: FillStrategy; provider_id?: string }
| { type: "manual"; items: string[]; provider_id?: string };
export interface ProgrammingBlock {
id: string;
name: string;
start_time: string;
duration_mins: number;
content: BlockContent;
loop_on_finish?: boolean;
ignore_rotation_policy?: boolean;
interstitial_rule?: InterstitialRule | null;
mid_roll_rule?: MidRollRule | null;
access_mode?: AccessMode;
access_password?: string;
}
export type Weekday =
| 'monday' | 'tuesday' | 'wednesday' | 'thursday'
| 'friday' | 'saturday' | 'sunday'
export const WEEKDAYS: Weekday[] = [
'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday',
]
export const WEEKDAY_LABELS: Record<Weekday, string> = {
monday: 'Mon', tuesday: 'Tue', wednesday: 'Wed', thursday: 'Thu',
friday: 'Fri', saturday: 'Sat', sunday: 'Sun',
}
export interface ScheduleConfig {
day_blocks: Record<Weekday, ProgrammingBlock[]>
}
export interface ConfigSnapshot {
id: string
version_num: number
label: string | null
created_at: string
}
export interface ScheduleHistoryEntry {
id: string
generation: number
valid_from: string
valid_until: string
}
// Config
export type StreamingProtocol = "hls" | "direct_file";
export interface ProviderCapabilities {
collections: boolean;
series: boolean;
genres: boolean;
tags: boolean;
decade: boolean;
search: boolean;
streaming_protocol: StreamingProtocol;
rescan: boolean;
transcode: boolean;
}
export interface TranscodeSettings {
cleanup_ttl_hours: number;
}
export interface TranscodeStats {
cache_size_bytes: number;
item_count: number;
}
export interface ProviderInfo {
id: string;
capabilities: ProviderCapabilities;
}
export interface ConfigResponse {
allow_registration: boolean;
providers: ProviderInfo[];
provider_capabilities: ProviderCapabilities;
available_provider_types: string[];
}
export interface ProviderConfig {
id: string;
provider_type: string;
config_json: Record<string, string>;
enabled: boolean;
}
export interface ProviderTestResult {
ok: boolean;
message: string;
}
// Auth
export interface TokenResponse {
access_token: string;
token_type: string;
expires_in: number;
refresh_token?: string;
}
export interface UserResponse {
id: string;
email: string;
created_at: string;
is_admin: boolean;
}
// Channels
export interface ChannelResponse {
id: string;
owner_id: string;
name: string;
description?: string | null;
timezone: string;
schedule_config: ScheduleConfig;
rotation_policy: RotationPolicy;
auto_schedule: boolean;
access_mode: string;
logo?: string | null;
logo_position: string;
logo_opacity: number;
webhook_url?: string | null;
webhook_poll_interval_secs: number;
webhook_body_template?: string | null;
webhook_headers?: string | null;
created_at: string;
updated_at: string;
}
export interface CreateChannelRequest {
name: string;
timezone: string;
description?: string;
access_mode?: AccessMode;
access_password?: string;
webhook_url?: string;
webhook_poll_interval_secs?: number;
webhook_body_template?: string;
webhook_headers?: string;
}
export interface UpdateChannelRequest {
name?: string;
description?: string;
timezone?: string;
schedule_config?: ScheduleConfig;
rotation_policy?: RotationPolicy;
auto_schedule?: boolean;
access_mode?: string;
logo?: string | null;
logo_position?: string;
logo_opacity?: number;
webhook_url?: string | null;
webhook_poll_interval_secs?: number;
webhook_body_template?: string | null;
webhook_headers?: string | null;
}
// Media & Schedule
export interface MediaItemResponse {
id: string;
title: string;
content_type: string;
duration_secs: number;
description?: string | null;
genres: string[];
tags: string[];
year?: number | null;
series_name?: string | null;
season_number?: number | null;
episode_number?: number | null;
}
export interface ScheduledSlotResponse {
id: string;
start_at: string;
end_at: string;
item: MediaItemResponse;
source_block_id: string;
}
export interface ScheduleResponse {
id: string;
channel_id: string;
valid_from: string;
valid_until: string;
generation: number;
slots: ScheduledSlotResponse[];
}
export interface CurrentBroadcastResponse {
slot: ScheduledSlotResponse;
offset_secs: number;
}
export type LibraryItemFull = LibraryItemResponse;
export interface ShowSummary {
series_name: string;
episode_count: number;
season_count: number;
thumbnail_url?: string | null;
genres: string[];
}
export interface SeasonSummary {
season_number: number;
episode_count: number;
thumbnail_url?: string | null;
}
export interface PagedLibraryResponse {
items: LibraryItemFull[];
total: number;
}
export interface LibrarySyncLogEntry {
id: number;
provider_id: string;
started_at: string;
finished_at?: string | null;
items_found: number;
status: 'running' | 'done' | 'error';
error_msg?: string | null;
}
export interface AdminSettings {
library_sync_interval_hours: number;
[key: string]: unknown;
}