Files
650da4a1d3 ci(test): type-check Jest spec programs and gate it in CI (#1705)
* build(test): make spec tsconfigs resolve what Jest resolves

Lib spec tsconfigs used module: commonjs with node10 resolution, which cannot
see Angular's exports-only secondary entry points, and dropped global.d.ts, so
tsc reported thousands of resolution errors and no window.electron typing.
Switch them to module: preserve with bundler resolution (ts-jest still forces
CommonJS emit outside ESM mode), add global.d.ts to every spec program, type
jest.unstable_mockModule for the ESM workspace, include the ui-epg and
ui-playback specs that jest.web-esm.workspace.ts runs under the web spec
config, and drop the snack-bar stub that shadowed the real Material types.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* ci(test): gate spec type-checking with typecheck:spec

Add tools/typecheck/spec-typecheck.mjs, which runs tsc --noEmit over every
tsconfig.spec.json with a small pool and fails on any diagnostic, wire it into
the unit-and-typecheck job after typecheck:ci, and document the gate and the
spec tsconfig conventions in the validation map. Also bring the non-Tier-A
spec configs (remote-control-web, ui-remote-control, stalker-mock-server) to
the same conventions so the gate covers the whole workspace.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* test: fix the spec type errors surfaced by typecheck:spec

With the spec programs resolving modules and ambient typings correctly,
tsc reported 432 genuine errors across the Tier A projects: read-only
capability flags assigned on Partial<> doubles, signal-store values used as
types, fixtures missing required fields, index-signature property access,
partial bridge doubles cast through incompatible shapes, and deferred
resolvers narrowed to never. Type the doubles instead of casting to any:
writable mapped types for capability flags, InstanceType<typeof StalkerStore>,
typed jest.fn signatures, protectedState: false on test signal stores, and
completed fixtures. Production changes are limited to bracket access for
index-signature properties under the libs' noPropertyAccessFromIndexSignature
setting and two narrowing guards in the global favorites loader.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* test(playback): use the ESM setup's jest global in the controls fixtures

The fixture imported jest from @jest/globals, which is not a direct
dependency. Jest provides that module at runtime, so tests passed, but on a
clean pnpm install tsc cannot resolve it and typecheck:spec failed in CI.
The ESM test setup already installs import.meta.jest as the global, typed
by @types/jest, as the other ESM specs use it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: type the parental lock doubles merged since the gate was written

The parental lock feature (#1601) and the Stalker actor route landed on master
with spec doubles declared as zero-argument jest.fn()s that the tests then
drive with the real arguments, plus a copy of the ResizableDirective override
imported from a library that does not export it. Give the doubles the lock
service's real signatures, drop the dead override as in the sibling layout
specs, use bracket access for the actor route's personId param, and keep the
Stalker layout spec within the 1200-line limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: 4gray <fourgray@proton.me>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-27 20:54:27 +02:00
..

Remote Control Web App

A lightweight, mobile-optimized web application that provides remote control functionality for IPTVnator. Control live channel switching from your phone or tablet on the same network.

Overview

This is a standalone Angular application designed to be served by IPTVnator's Electron backend via an HTTP server. It provides a beautiful, Apple TV-inspired remote control interface that communicates with the main IPTVnator desktop application to change channels.

Features

  • Apple TV-Inspired Design - Premium dark theme with glass morphism effects
  • Mobile-Optimized - Touch-friendly interface designed for phones and tablets
  • Real-time Control - Instant channel switching via REST API
  • Multi-Portal Support - Works with M3U playlists, Xtream Live TV, and Stalker ITV sections
  • Numeric Channel Input - Enter channel numbers directly from the web remote
  • Live Status Panel - Displays active channel and current EPG program when available
  • Volume Controls - Volume up/down/mute when the active player supports remote volume
  • Minimal & Fast - Lightweight app (~55 KB compressed) with no external dependencies
  • Responsive - Adapts to different screen sizes (320px - 480px+)

How It Works

Architecture

┌─────────────────┐         HTTP          ┌──────────────────┐
│   Phone/Tablet  │ ◄──────────────────► │  HTTP Server     │
│  (Browser App)  │    REST API calls    │  (Electron Main) │
└─────────────────┘                       └──────────────────┘
                                                    │ IPC
                                                    ▼
                                          ┌──────────────────┐
                                          │  Main App        │
                                          │  (Renderer)      │
                                          └──────────────────┘
  1. HTTP Server: Electron backend starts an HTTP server (default port: 8765)
  2. Static Files: Serves this Angular app's built files
  3. REST API: Exposes channel/volume/status endpoints for the web remote
  4. IPC Communication: HTTP server sends events to the main Electron window
  5. Channel Switching: Main app receives events and switches to next/previous live channel in the active live view

API Endpoints

  • GET / - Serves the remote control web interface
  • POST /api/remote-control/channel/up - Switch to previous channel
  • POST /api/remote-control/channel/down - Switch to next channel
  • POST /api/remote-control/channel/select-number - Switch by channel number
  • POST /api/remote-control/volume/up - Increase volume
  • POST /api/remote-control/volume/down - Decrease volume
  • POST /api/remote-control/volume/toggle-mute - Toggle mute
  • GET /api/remote-control/status - Get current playback status for remote UI

Usage

Enable Remote Control

  1. Open IPTVnator desktop app
  2. Go to Settings
  3. Enable "Remote Control" checkbox
  4. Optionally change the port (default: 8765)
  5. The HTTP server starts automatically

Access from Mobile Device

  1. Ensure your phone/tablet is on the same network as your computer
  2. Find your computer's IP address:
    • Windows: ipconfig (look for IPv4)
    • macOS: ifconfig or System Preferences → Network
    • Linux: ip addr or hostname -I
  3. Open browser on your mobile device
  4. Navigate to: http://<YOUR_IP>:8765
    • Example: http://192.168.1.100:8765

Controls

  • Top half of circle: Previous channel (Channel Up)
  • Bottom half of circle: Next channel (Channel Down)
  • Center blue dot: Status indicator (glowing = ready)

Development

Build

# Production build
nx build remote-control-web --configuration=production

# Development build
nx build remote-control-web

Built files are output to dist/apps/remote-control-web/browser/

Serve Locally

The app is designed to be served by the Electron backend's HTTP server. To test:

# Start Electron backend (includes HTTP server)
nx serve electron-backend

# Access at http://localhost:8765

Project Structure

apps/remote-control-web/
├── src/
│   ├── app/
│   │   ├── app.component.ts       # Root component
│   │   ├── app.config.ts          # Angular configuration
│   │   └── app.routes.ts          # Routes (single route)
│   ├── assets/                    # Static assets (if any)
│   ├── index.html                 # HTML entry point
│   └── main.ts                    # Bootstrap Angular app
├── project.json                   # Nx project configuration
├── tsconfig.json                  # TypeScript config
└── README.md                      # This file

Shared UI Library

The remote control component is located in:

libs/ui/remote-control/
├── src/lib/remote-control/
│   ├── remote-control.component.ts    # Main component logic
│   ├── remote-control.component.html  # Template
│   ├── remote-control.component.scss  # Apple TV-inspired styles
│   └── remote-control.service.ts      # HTTP service for API calls

This library is shared and can be reused in other applications if needed.

Technical Details

  • Framework: Angular 18+ (Standalone components)
  • HTTP Client: Angular HttpClient
  • Styling: SCSS with BEM methodology
  • Design System: Apple TV-inspired with glass morphism
  • Animations: CSS-only (no JavaScript animations)
  • Bundle Size: ~55 KB gzipped (production build)
  • Browser Support: Modern browsers (Chrome, Safari, Firefox, Edge)

Design Philosophy

The interface is inspired by Apple TV's remote control:

  • Minimalism: Clean, uncluttered design with essential controls only
  • Glass Morphism: Frosted glass effects with subtle reflections
  • Touch-Optimized: Large touch targets (50% of circle per button)
  • Feedback: Visual feedback on hover/press with ripple effects
  • Accessibility: Supports reduced motion preferences

Security Considerations

  • Local Network Only: The HTTP server should only be accessible on your local network
  • No Authentication: Currently no authentication - ensure your network is trusted
  • CORS: Server accepts requests from any origin on the local network

Future Enhancements

Potential improvements:

  • Volume control
  • Play/pause functionality
  • Channel search
  • Favorites quick access
  • Authentication/PIN protection
  • WebSocket for real-time status updates
  • Multi-device support with channel sync
  • HTTP Server: apps/electron-backend/src/app/server/http-server.ts
  • Remote Control Events: apps/electron-backend/src/app/events/remote-control.events.ts
  • M3U Handler: apps/web/src/app/home/video-player/video-player.component.ts (handleRemoteChannelChange method)
  • Xtream Live Handler: apps/web/src/app/xtream-electron/live-stream-layout/live-stream-layout.component.ts
  • Stalker ITV Handler: apps/web/src/app/stalker/stalker-live-stream-layout/stalker-live-stream-layout.component.ts
  • Settings UI: apps/web/src/app/settings/settings.component.html

License

Same as IPTVnator main project.