/**
* App - Root component for the Torm TUI.
*
* This is the main application shell that manages:
* - Engine connection and torrent state
* - View routing (MainView, DetailView)
* - Global keyboard shortcuts
* - Modal dialogs (Add Torrent, Delete Confirmation)
*
* @module ui/App
*/
import React, { useState, useCallback, useMemo, useEffect } from 'react';
import { Box, useApp, useInput } from 'ink';
import { useDaemonClient } from './hooks/useDaemonClient.js';
import { useTorrents } from './hooks/useTorrents.js';
import { useKeyboard } from './hooks/useKeyboard.js';
import { useTerminalSize } from './hooks/useTerminalSize.js';
import { useMascotState } from './hooks/useMascotState.js';
import { usePaste } from './hooks/usePaste.js';
import { useUpdateChecker } from './hooks/useUpdateChecker.js';
import { MainView } from './views/MainView.js';
import { DetailView } from './views/DetailView.js';
import { AddTorrentModal } from './components/AddTorrentModal.js';
import { BatchAddModal } from './components/BatchAddModal.js';
import { ConfirmDialog } from './components/ConfirmDialog.js';
import { LabelEditorModal } from './components/LabelEditorModal.js';
import { SettingsModal } from './components/SettingsModal.js';
import type { StatusFilter } from './components/SearchBar.js';
import type {
PartialEngineConfig,
EngineConfig,
Peer,
} from '../engine/types.js';
/**
* View type for routing within the application.
*/
type ViewType = 'main' | 'detail';
/**
* App component - Root of the Torm TUI
*
* Responsibilities:
* - Initialize engine connection via useEngine hook
* - Manage torrent selection via useTorrents hook
* - Handle global keyboard shortcuts via useKeyboard hook
* - Route to correct view (MainView or DetailView)
* - Manage modal dialogs (Add Torrent, Delete Confirmation)
*
* State:
* - currentView: 'main' | 'detail'
* - showAddModal: boolean
* - showDeleteConfirm: boolean
* - deleteFiles: boolean
*
* Keyboard shortcuts (handled by this component):
* - q: Quit application
* - up/k: Select previous torrent
* - down/j: Select next torrent
* - p: Pause selected torrent
* - r: Resume selected torrent
* - d: Delete selected torrent (opens confirmation dialog)
* - a: Add new torrent (opens add modal)
* - l: Edit labels for selected torrent (opens label editor)
*
* @example
* ```tsx
* import { render } from 'ink';
* import { App } from './ui/App.js';
*
* render();
* ```
*/
export const App: React.FC = () => {
// Ink's useApp hook for exit functionality
const { exit } = useApp();
// Connect to daemon and get torrent state
const {
torrents,
isReady,
isConnecting,
error: daemonError,
daemonUptime,
getPeers,
addTorrent,
removeTorrent,
pauseTorrent,
resumeTorrent,
getConfig,
updateConfig,
shutdownDaemon,
} = useDaemonClient();
// State for peers (fetched async)
const [currentPeers, setCurrentPeers] = useState([]);
// State for config (fetched async)
const [config, setConfig] = useState(null);
// Labels state (managed locally since daemon doesn't have labels API yet)
const [labelsMap, setLabelsMap] = useState