Files
euzuandGitHub 16d32d1298 DVR Feature (#819)
feat: complete DVR and improve streaming, security, configuration, and UI

Complete the Digital Video Recorder subsystem and add a broad set of
reliability, security, streaming, configuration, processing, and Web UI
improvements across Tuliprox.

DVR:

* complete live recording and provider-aware VOD download support
* add recording queue, workers, scheduling, and recurring recording rules
* add conflict detection and capacity-aware scheduling
* add pause, resume, retry, edit, cancel, and delete workflows
* add recording quotas and configurable retention policies
* add crash recovery and startup reconciliation
* add durable lifecycle notifications with per-channel retries
* add DVR health monitoring and diagnostic tooling
* add secure access to recordings, thumbnails, and subtitles
* add WebSocket notifications for recording and rule changes
* add Web UI management for recordings, rules, progress, and task state
* add RBAC, configuration, documentation, and i18n support

Streaming and HLS:

* fix shared-stream idle handling and release dead provider streams correctly
* stop tee streams when both client and cache consumers are gone
* cancel provisioning probes when client streams terminate
* fix transient HLS origin work accounting and intermittent 503 responses
* make stream buffer byte limits configurable
* make shared subscriber idle timeout configurable
* make initial HLS manifest wait timeout configurable
* add configurable TS chunk packet count
* add configurable HLS refresh failure backoff
* centralize redirect limits and retry jitter handling
* improve provider DNS refresh behavior and failover tuning
* preserve UTF-8 characters in catchup templates
* improve stream history validation and persistence error handling

Security:

* use constant-time credential comparisons
* harden library and media path handling against traversal and symlink escapes
* only trust forwarded client IP headers from configured trusted proxies
* redact credentials and sensitive URL data from logs
* reject invalid authentication status-code configuration
* deny users with unresolved plans or invalid content filters
* improve authentication error handling across proxy and HLS endpoints

Configuration and reliability:

* prevent invalid api-proxy.yml reloads from terminating the running server
* fully validate API proxy configuration before persisting changes
* log configuration and EPG cleanup failures instead of silently discarding them
* keep the last valid configuration active after failed hot reloads
* align backend and shared media-server validation
* remove duplicated path and normalization logic
* improve DNS-store recovery and Windows rename fallback handling
* reject invalid duration, timestamp, and numeric conversions safely
* fix playlist bouquet save error handling
* fix provider record update detection
* fix cache boundary handling
* improve startup and persistence failure diagnostics

Filtering, search, sorting, and processing:

* add field-scoped playlist explorer search
* centralize shared stream-history search field definitions
* extend the filter DSL with string, set, and numeric operators
* add EPG ID, channel number, and detected quality as filterable fields
* add filter dry-run preview API with match statistics and samples
* report filter syntax errors with line and column information
* add natural numeric-aware sorting
* add quality-aware channel deduplication
* add accent-independent deduplication
* move natural sorting and quality detection helpers into shared code
* persist explorer search-field selection across reloads

User plans and content access:

* add reusable API user plans for capability tiers
* support inherited cluster and connection limits with per-user overrides
* add plan-level and user-level content filters
* enforce content filters across Xtream, M3U, direct playback, resource access,
  stream info, short EPG, categories, and XMLTV
* add trial plans with automatic expiry and Trial status
* add plan selection and content filtering to the user editor
* add full plan management to the API configuration Web UI
* migrate the API user database to schema V7 with plan and filter persistence

Web UI and accessibility:

* add live logging console to the stats page
* improve login error handling and prevent duplicate authentication requests
* add keyboard navigation to tabs, menus, tables, and search
* add ARIA roles, labels, validation state, and live-region feedback
* add confirmation dialogs for destructive actions
* add unsaved-change warnings and Ctrl/Cmd+S shortcuts
* add loading, progress, empty, and in-flight states across views
* improve dropdown and single-selection behavior
* add clipboard and credential-copy helpers
* persist table pagination and explorer search preferences
* improve error recovery when UI context providers are unavailable
* remove multiple panic-prone unwrap and browser API paths
* replace remaining hardcoded UI strings with translation keys

Maintenance:

* resolve backend and frontend compiler and Clippy warnings
* update packages and test fixtures
* consolidate duplicated helpers and validation logic
* improve documentation for configuration, filters, plans, DVR, and REST APIs
* add and update tests for migrations, filters, deduplication, sorting,
  configuration, streaming, and accessibility behavior
2026-08-21 14:50:12 +02:00

114 lines
2.6 KiB
SCSS

.tp__input {
display: flex;
flex-flow: column;
overflow: hidden;
box-sizing: border-box;
gap: var(--gap-default);
.tp__input-wrapper {
display: flex;
flex-flow: row nowrap;
overflow: hidden;
box-sizing: border-box;
border: 1px solid var(--input-border-color);
border-radius: var(--border-radius);
background-color: var(--input-background-color);
align-items: center;
padding-right: var(--padding-mini);
&:focus-within {
border-color: var(--input-focus-border-color);
}
.svg-icon {
height: 2rem;
width: 2rem;
}
.tp__icon-button {
.svg-icon {
min-width: 1.5rem;
height: 1.5rem;
width: 1.5rem;
}
}
.tp__icon-button.active {
fill: currentColor;
}
}
label {
padding-left: 2px;
color: var(--modest-text-color);
font-weight: bold;
font-size: var(--font-size-norm);
}
&--required label::after {
content: " *";
color: var(--error-color, #d9534f);
}
&--error .tp__input-wrapper {
border-color: var(--error-color, #d9534f);
}
}
.tp__input-error {
color: var(--error-color, #d9534f);
font-size: var(--font-size-norm);
padding-left: 2px;
}
textarea,
input {
background-clip: content-box;
box-sizing: border-box;
width: 100%;
font-family: inherit;
font-size: var(--font-size-md);
line-height: 1.5rem;
border: none;
color: var(--text-color);
background-color: var(--input-background-color);
padding: 6px 12px;
flex: 1 1 auto;
caret-color: var(--text-color) !important;
&:focus,
&:hover {
outline: none;
background-color: var(--input-background-color);
}
}
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
-webkit-box-shadow: 0 0 0 1000px var(--input-autofill-background-color) inset !important;
-webkit-text-fill-color: var(--text-color) !important;
transition: background-color 5000s ease-in-out 0s;
background-color: transparent !important;
color: var(--text-color) !important;
border: none !important;
caret-color: var(--text-color) !important;
}
body:not([data-theme="bright"]) input[type="date"]::-webkit-calendar-picker-indicator,
body:not([data-theme="bright"]) input[type="datetime-local"]::-webkit-calendar-picker-indicator {
filter: invert(1) brightness(0.6) saturate(0) opacity(0.7);
}
body[data-theme="bright"] input[type="date"]::-webkit-calendar-picker-indicator,
body[data-theme="bright"] input[type="datetime-local"]::-webkit-calendar-picker-indicator {
filter: none;
}
.tp__input-date-tools {
input {
padding-right: 0;
}
}