tui

package
v0.2.8-alpha Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 19, 2026 License: MIT Imports: 24 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ColorPrimary    = lipgloss.Color("#8B5CF6") // Bright Purple
	ColorSuccess    = lipgloss.Color("#22C55E") // Bright Green
	ColorWarning    = lipgloss.Color("#FBBF24") // Bright Amber
	ColorError      = lipgloss.Color("#EF4444") // Red
	ColorInfo       = lipgloss.Color("#60A5FA") // Bright Blue
	ColorMuted      = lipgloss.Color("#9CA3AF") // Light Gray
	ColorBorder     = lipgloss.Color("#6B7280") // Medium gray
	ColorBackground = lipgloss.Color("#111827") // Very dark
	ColorForeground = lipgloss.Color("#F9FAFB") // Very light
	ColorHighlight  = lipgloss.Color("#A78BFA") // Light purple
	ColorTab        = lipgloss.Color("#4B5563") // Medium dark gray
	ColorTabActive  = lipgloss.Color("#8B5CF6") // Active tab purple
)

Color palette

View Source
var (
	// Header styles
	HeaderStyle = lipgloss.NewStyle().
				Bold(true).
				Foreground(ColorPrimary).
				Background(ColorBackground).
				Padding(0, 1)

	StatusStyle = lipgloss.NewStyle().
				Foreground(ColorMuted).
				Padding(0, 1)

	// Border styles
	BorderStyle = lipgloss.NewStyle().
				Border(lipgloss.RoundedBorder()).
				BorderForeground(ColorBorder).
				Padding(0, 1)

	ActiveBorderStyle = lipgloss.NewStyle().
						Border(lipgloss.RoundedBorder()).
						BorderForeground(ColorPrimary).
						Padding(0, 1)

	// Title styles
	TitleStyle = lipgloss.NewStyle().
				Bold(true).
				Foreground(ColorPrimary).
				MarginBottom(1)

	SubtitleStyle = lipgloss.NewStyle().
					Foreground(ColorMuted).
					Italic(true)

	// List item styles
	SelectedItemStyle = lipgloss.NewStyle().
						Foreground(ColorPrimary).
						Bold(true).
						PaddingLeft(2)

	UnselectedItemStyle = lipgloss.NewStyle().
						Foreground(ColorForeground).
						PaddingLeft(2)

	CheckedItemStyle = lipgloss.NewStyle().
						Foreground(ColorSuccess).
						PaddingLeft(2)

	// Progress bar styles
	ProgressBarStyle = lipgloss.NewStyle().
						Foreground(ColorPrimary)

	ProgressEmptyStyle = lipgloss.NewStyle().
						Foreground(ColorMuted)

	// Status badge styles
	SuccessBadge = lipgloss.NewStyle().
					Foreground(ColorSuccess).
					Bold(true)

	ErrorBadge = lipgloss.NewStyle().
				Foreground(ColorError).
				Bold(true)

	WarningBadge = lipgloss.NewStyle().
					Foreground(ColorWarning).
					Bold(true)

	InfoBadge = lipgloss.NewStyle().
				Foreground(ColorInfo).
				Bold(true)

	RunningBadge = lipgloss.NewStyle().
					Foreground(ColorPrimary).
					Bold(true)

	// Log styles
	LogDebugStyle = lipgloss.NewStyle().
					Foreground(ColorMuted)

	LogInfoStyle = lipgloss.NewStyle().
					Foreground(ColorInfo)

	LogWarnStyle = lipgloss.NewStyle().
					Foreground(ColorWarning)

	LogErrorStyle = lipgloss.NewStyle().
					Foreground(ColorError).
					Bold(true)

	// Help styles
	HelpKeyStyle = lipgloss.NewStyle().
					Foreground(ColorPrimary).
					Bold(true)

	HelpDescStyle = lipgloss.NewStyle().
					Foreground(ColorMuted)

	HelpSeparatorStyle = lipgloss.NewStyle().
						Foreground(ColorBorder)

	// Dimmed text
	DimmedStyle = lipgloss.NewStyle().
				Foreground(ColorMuted)

	// Highlight
	HighlightStyle = lipgloss.NewStyle().
					Foreground(ColorPrimary).
					Bold(true)

	// Error text
	ErrorStyle = lipgloss.NewStyle().
				Foreground(ColorError).
				Bold(true)

	// Success text
	SuccessStyle = lipgloss.NewStyle().
					Foreground(ColorSuccess).
					Bold(true)

	// Tab styles
	TabStyle = lipgloss.NewStyle().
				Foreground(ColorMuted).
				Background(ColorTab).
				Padding(0, 2).
				MarginRight(1)

	ActiveTabStyle = lipgloss.NewStyle().
					Foreground(ColorForeground).
					Background(ColorTabActive).
					Padding(0, 2).
					MarginRight(1).
					Bold(true)

	// Panel style with lighter border
	PanelStyle = lipgloss.NewStyle().
				Border(lipgloss.RoundedBorder()).
				BorderForeground(ColorBorder).
				Padding(1, 2)
)

Styles

Functions

func CalculateTotalProgress

func CalculateTotalProgress(tasks map[string]*worker.TaskProgress) float64

CalculateTotalProgress computes the aggregate progress across all tasks. This is a pure function with no side effects.

Parameters:

  • tasks: Map of task IDs to TaskProgress

Returns:

  • Average progress (0.0 to 1.0), or 0.0 if no tasks exist

func Dimmed

func Dimmed(text string) string

func Error

func Error(text string) string

func FormatFileStatus

func FormatFileStatus(file FileItem) string

FormatFileStatus returns a human-readable status string for a file based on its matched state. This is a pure function with no side effects.

Status format:

  • "matched [ID]" - file has been matched to a JAV ID
  • "unmatched" - file has not been matched yet

Note: FileItem struct currently tracks Matched and ID fields only. Processing/Progress state is tracked separately in the TUI Model.

Parameters:

  • file: FileItem to format status for

Returns:

  • formatted status string

func FormatTaskStatus

func FormatTaskStatus(status worker.TaskStatus) string

FormatTaskStatus returns a human-readable status badge for a worker task. This is a pure function extracted from the TaskList component.

Status format:

  • worker.TaskStatusRunning -> "RUN"
  • worker.TaskStatusSuccess -> "OK"
  • worker.TaskStatusFailed -> "ERR"
  • worker.TaskStatusPending -> "..."

Parameters:

  • status: worker.TaskStatus enum value

Returns:

  • formatted status badge string (without styling)

func HandleProgressUpdate

func HandleProgressUpdate(tasks map[string]*worker.TaskProgress, update worker.ProgressUpdate) map[string]*worker.TaskProgress

HandleProgressUpdate updates task progress state based on a progress message. This is a pure function with no side effects - it creates a new tasks map with the updated progress data for the specified task.

Parameters:

  • tasks: Current map of task IDs to TaskProgress
  • update: Progress update containing task ID, status, and progress data

Returns:

  • New map with updated task progress (immutable transformation)

func HandleStats

func HandleStats(currentStats worker.ProgressStats, poolStats worker.PoolStats) worker.ProgressStats

HandleStats updates overall statistics based on worker pool stats. This is a pure function that creates a new ProgressStats with updated values.

Parameters:

  • currentStats: Current progress statistics
  • poolStats: New statistics from worker pool

Returns:

  • New ProgressStats with updated values

func Highlight

func Highlight(text string) string

func Info

func Info(text string) string

func IsValidView

func IsValidView(view ViewMode) bool

IsValidView checks if the given view mode is valid. Valid views: Browser(0), Dashboard(1), Logs(2), Settings(3), Help(4)

func RenderActressMergeModal

func RenderActressMergeModal(m *Model) string

RenderActressMergeModal renders the actress merge modal overlay.

func RenderManualSearchModal

func RenderManualSearchModal(m *Model) string

RenderManualSearchModal renders the manual search modal overlay

func Subtitle

func Subtitle(text string) string

func Success

func Success(text string) string

func Title

func Title(text string) string

func Warning

func Warning(text string) string

Types

type Browser

type Browser struct {
	// contains filtered or unexported fields
}

Browser component

func NewBrowser

func NewBrowser() *Browser

func (*Browser) CursorDown

func (b *Browser) CursorDown()

func (*Browser) CursorUp

func (b *Browser) CursorUp()

func (*Browser) DeselectAll

func (b *Browser) DeselectAll()

func (*Browser) Init

func (b *Browser) Init() tea.Cmd

func (*Browser) SelectAll

func (b *Browser) SelectAll()

func (*Browser) SetDestPath

func (b *Browser) SetDestPath(path string)

func (*Browser) SetItems

func (b *Browser) SetItems(items []FileItem)

func (*Browser) SetPathDisplay

func (b *Browser) SetPathDisplay(display string)

func (*Browser) SetSize

func (b *Browser) SetSize(width, height int)

func (*Browser) SetSourcePath

func (b *Browser) SetSourcePath(path string)

func (*Browser) ToggleSelection

func (b *Browser) ToggleSelection(path string)

func (*Browser) Update

func (b *Browser) Update(msg tea.Msg) (tea.Model, tea.Cmd)

func (*Browser) View

func (b *Browser) View() string

type CancelTaskMsg

type CancelTaskMsg struct {
	TaskID string
}

CancelTaskMsg signals to cancel a specific task

type Console

type Console struct {
	// contains filtered or unexported fields
}

Console component - shows live output and metadata preview

func NewConsole

func NewConsole() *Console

func (*Console) AddEntry

func (c *Console) AddEntry(entry string)

func (*Console) Clear

func (c *Console) Clear()

func (*Console) Init

func (c *Console) Init() tea.Cmd

func (*Console) ScrollDown

func (c *Console) ScrollDown()

func (*Console) ScrollToBottom

func (c *Console) ScrollToBottom()

func (*Console) ScrollToTop

func (c *Console) ScrollToTop()

func (*Console) ScrollUp

func (c *Console) ScrollUp()

func (*Console) SetSize

func (c *Console) SetSize(width, height int)

func (*Console) ToggleAutoScroll

func (c *Console) ToggleAutoScroll()

func (*Console) Update

func (c *Console) Update(msg tea.Msg) (tea.Model, tea.Cmd)

func (*Console) View

func (c *Console) View() string

type Dashboard

type Dashboard struct {
	// contains filtered or unexported fields
}

Dashboard component

func NewDashboard

func NewDashboard() *Dashboard

func (*Dashboard) Init

func (d *Dashboard) Init() tea.Cmd

func (*Dashboard) SetSize

func (d *Dashboard) SetSize(width, height int)

func (*Dashboard) Update

func (d *Dashboard) Update(msg tea.Msg) (tea.Model, tea.Cmd)

func (*Dashboard) UpdateStats

func (d *Dashboard) UpdateStats(stats worker.ProgressStats, elapsed time.Duration)

func (*Dashboard) View

func (d *Dashboard) View() string

type DownloaderInterface

type DownloaderInterface interface {
	SetDownloadExtrafanart(enabled bool)
}

DownloaderInterface defines the contract for media download operations used by ProcessingCoordinator. Only includes methods directly called by processor.go (SetDownloadExtrafanart). Implemented by: *downloader.Downloader

type ErrorMsg

type ErrorMsg struct {
	Error error
}

ErrorMsg represents an error that occurred

type FileItem

type FileItem struct {
	Path     string
	Name     string
	Size     int64
	IsDir    bool
	Selected bool
	Matched  bool
	ID       string // JAV ID if matched
	Depth    int    // Indentation depth for tree display
	Parent   string // Parent directory path
}

FileItem represents a file in the browser

func FilterVideoFiles

func FilterVideoFiles(files []FileItem, extensions []string) []FileItem

FilterVideoFiles returns only video files matching the provided extensions. This is a pure function: it creates a new slice without modifying the input.

Parameters:

  • files: slice of FileItem to filter
  • extensions: list of valid video extensions (e.g., ".mp4", ".mkv", ".avi")

Returns:

  • new slice containing only files matching the extensions

func SortFilesByStatus

func SortFilesByStatus(files []FileItem) []FileItem

SortFilesByStatus sorts files by matched state and then alphabetically by path. This is a pure function: it creates a new sorted slice without modifying the input.

Sort order:

  1. Matched files (sorted alphabetically by path)
  2. Unmatched files (sorted alphabetically by path)
  3. Directories (sorted alphabetically by path)

Parameters:

  • files: slice of FileItem to sort

Returns:

  • new sorted slice (original unchanged)

type FileSelectedMsg

type FileSelectedMsg struct {
	Path     string
	Selected bool
}

FileSelectedMsg indicates files were selected/deselected

type FolderItem

type FolderItem struct {
	Path  string
	Name  string
	IsDir bool
}

FolderItem represents a folder in the folder picker

type Header struct {
	// contains filtered or unexported fields
}

Header component

func NewHeader

func NewHeader() *Header

func (*Header) SetWidth

func (h *Header) SetWidth(width int)

func (*Header) UpdateStats

func (h *Header) UpdateStats(stats worker.ProgressStats)

func (*Header) View

func (h *Header) View() string

type HelpView

type HelpView struct {
	// contains filtered or unexported fields
}

HelpView component

func NewHelpView

func NewHelpView() *HelpView

func (*HelpView) Init

func (h *HelpView) Init() tea.Cmd

func (*HelpView) SetSize

func (h *HelpView) SetSize(width, height int)

func (*HelpView) Update

func (h *HelpView) Update(msg tea.Msg) (tea.Model, tea.Cmd)

func (*HelpView) View

func (h *HelpView) View() string

type LogEntry

type LogEntry struct {
	Level     string
	Message   string
	Timestamp time.Time
}

LogEntry represents a log message

func HandleError

func HandleError(err error) LogEntry

HandleError processes an error message and creates a log entry. This is a convenience function that wraps HandleLogMessage with "error" level.

Parameters:

  • err: Error to process

Returns:

  • Log entry with error level and error message

func HandleLogMessage

func HandleLogMessage(level, message string) LogEntry

HandleLogMessage processes a log message and creates a log entry. This is a pure function that returns a formatted log entry.

Parameters:

  • level: Log level (info, warn, error, etc.)
  • message: Log message content

Returns:

  • Formatted log entry struct

type LogMsg

type LogMsg struct {
	Level     string // debug, info, warn, error
	Message   string
	Timestamp time.Time
}

LogMsg represents a log message

type LogViewer

type LogViewer struct {
	// contains filtered or unexported fields
}

LogViewer component

func NewLogViewer

func NewLogViewer() *LogViewer

func (*LogViewer) AddLog

func (l *LogViewer) AddLog(entry LogEntry)

func (*LogViewer) Init

func (l *LogViewer) Init() tea.Cmd

func (*LogViewer) ScrollDown

func (l *LogViewer) ScrollDown()

func (*LogViewer) ScrollToBottom

func (l *LogViewer) ScrollToBottom()

func (*LogViewer) ScrollToTop

func (l *LogViewer) ScrollToTop()

func (*LogViewer) ScrollUp

func (l *LogViewer) ScrollUp()

func (*LogViewer) SetSize

func (l *LogViewer) SetSize(width, height int)

func (*LogViewer) ToggleAutoScroll

func (l *LogViewer) ToggleAutoScroll()

func (*LogViewer) Update

func (l *LogViewer) Update(msg tea.Msg) (tea.Model, tea.Cmd)

func (*LogViewer) View

func (l *LogViewer) View() string

type Model

type Model struct {
	// contains filtered or unexported fields
}

Model represents the TUI application state

func New

func New(cfg *config.Config) *Model

New creates a new TUI model

func (*Model) AddConsoleOutput

func (m *Model) AddConsoleOutput(output string)

AddConsoleOutput adds output to the console

func (*Model) AddLog

func (m *Model) AddLog(level, message string)

AddLog adds a log entry

func (*Model) CloseFolderPicker

func (m *Model) CloseFolderPicker()

CloseFolderPicker closes the folder picker

func (*Model) Error

func (m *Model) Error() error

Error returns any error that occurred

func (*Model) GetDestPath

func (m *Model) GetDestPath() string

GetDestPath returns the destination path

func (*Model) GetSelectedFiles

func (m *Model) GetSelectedFiles() []string

GetSelectedFiles returns the list of selected files

func (*Model) Init

func (m *Model) Init() tea.Cmd

Init initializes the TUI

func (*Model) NavigateToFolder

func (m *Model) NavigateToFolder(path string)

NavigateToFolder navigates to a folder in the picker

func (*Model) OpenFolderPicker

func (m *Model) OpenFolderPicker(startPath, mode string)

OpenFolderPicker opens the folder picker at the given path

func (*Model) Rescan

func (m *Model) Rescan(path string)

Rescan performs a rescan of the source path and updates the file list

func (*Model) SelectCurrentFolder

func (m *Model) SelectCurrentFolder()

SelectCurrentFolder selects the current folder and closes the picker

func (*Model) SetActressRepo

func (m *Model) SetActressRepo(repo *database.ActressRepository)

SetActressRepo sets the actress repository used by the merge modal.

func (*Model) SetDestPath

func (m *Model) SetDestPath(path string)

SetDestPath sets the destination path for organized files

func (*Model) SetDryRun

func (m *Model) SetDryRun(dryRun bool)

SetDryRun sets the dry-run mode

func (*Model) SetFiles

func (m *Model) SetFiles(files []FileItem)

SetFiles sets the files to display in the browser

func (*Model) SetMatchResults

func (m *Model) SetMatchResults(matches map[string]matcher.MatchResult)

SetMatchResults sets the match results for files

func (*Model) SetProcessor

func (m *Model) SetProcessor(processor *ProcessingCoordinator)

SetProcessor sets the processing coordinator

func (*Model) SetScanner

func (m *Model) SetScanner(s *scanner.Scanner, mat *matcher.Matcher, recursive bool)

SetScanner sets the scanner for rescanning files

func (*Model) SetSize

func (m *Model) SetSize(width, height int)

SetSize sets the window size

func (*Model) SetSourcePath

func (m *Model) SetSourcePath(path string)

SetSourcePath sets the source path being scanned

func (*Model) SetUpdateMode

func (m *Model) SetUpdateMode(updateMode bool)

SetUpdateMode sets update mode and syncs it to processor.

func (*Model) SetWorkerPool

func (m *Model) SetWorkerPool(pool *worker.Pool, progressChan chan worker.ProgressUpdate)

SetWorkerPool sets the worker pool and progress channel

func (*Model) StartProcessing

func (m *Model) StartProcessing(ctx context.Context) error

StartProcessing begins processing selected files

func (*Model) ToggleFileSelection

func (m *Model) ToggleFileSelection(path string)

ToggleFileSelection toggles selection of a file

func (*Model) Update

func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update handles messages and updates the model

func (*Model) UpdateProgress

func (m *Model) UpdateProgress(update worker.ProgressUpdate)

UpdateProgress updates task progress

func (*Model) UpdateStats

func (m *Model) UpdateStats(stats worker.ProgressStats)

UpdateStats updates statistics

func (*Model) View

func (m *Model) View() string

View renders the TUI

type PauseMsg

type PauseMsg struct{}

PauseMsg signals to pause processing

type PoolInterface

type PoolInterface interface {
	Submit(task worker.Task) error
	Wait() error
	Stop()
}

PoolInterface defines the contract for worker pool operations. Implemented by: *worker.Pool

type ProcessingCoordinator

type ProcessingCoordinator struct {
	// contains filtered or unexported fields
}

ProcessingCoordinator coordinates task execution for the TUI

func NewProcessingCoordinator

func NewProcessingCoordinator(
	pool PoolInterface,
	progressTracker ProgressTrackerInterface,
	movieRepo *database.MovieRepository,
	registry *models.ScraperRegistry,
	agg *aggregator.Aggregator,
	dl DownloaderInterface,
	org *organizer.Organizer,
	nfoGen *nfo.Generator,
	destPath string,
	moveFiles bool,
) *ProcessingCoordinator

NewProcessingCoordinator creates a new processing coordinator

IMPORTANT: This constructor requires concrete types that implement the interfaces:

  • pool must be *worker.Pool (type assertion in ProcessFiles)
  • progressTracker must be *worker.ProgressTracker (type assertion in ProcessFiles)
  • dl must be *downloader.Downloader (type assertion in ProcessFiles)

Passing incorrect types will cause a runtime panic when ProcessFiles is called.

func (*ProcessingCoordinator) GetCustomScrapers

func (pc *ProcessingCoordinator) GetCustomScrapers() []string

GetCustomScrapers returns the current custom scraper priority Returns a copy to prevent external mutation

func (*ProcessingCoordinator) ProcessFiles

func (pc *ProcessingCoordinator) ProcessFiles(
	ctx context.Context,
	files []FileItem,
	matches map[string]matcher.MatchResult,
) error

ProcessFiles processes the selected files with matched JAV IDs

func (*ProcessingCoordinator) SetConfig

func (pc *ProcessingCoordinator) SetConfig(cfg *config.Config)

SetConfig provides runtime config for template-aware NFO merge path resolution.

func (*ProcessingCoordinator) SetCustomScrapers

func (pc *ProcessingCoordinator) SetCustomScrapers(scrapers []string)

SetCustomScrapers sets custom scraper priority for manual search Makes a defensive copy to prevent data races with worker goroutines

func (*ProcessingCoordinator) SetDestPath

func (pc *ProcessingCoordinator) SetDestPath(destPath string)

SetDestPath sets the destination path for organized files

func (*ProcessingCoordinator) SetDownloadEnabled

func (pc *ProcessingCoordinator) SetDownloadEnabled(enabled bool)

SetDownloadEnabled sets whether media downloads are enabled

func (*ProcessingCoordinator) SetDownloadExtrafanart

func (pc *ProcessingCoordinator) SetDownloadExtrafanart(enabled bool)

SetDownloadExtrafanart sets whether extrafanart downloads are enabled

func (*ProcessingCoordinator) SetDryRun

func (pc *ProcessingCoordinator) SetDryRun(dryRun bool)

SetDryRun sets whether to run in dry-run mode (preview only)

func (*ProcessingCoordinator) SetForceRefresh

func (pc *ProcessingCoordinator) SetForceRefresh(forceRefresh bool)

SetForceRefresh sets whether to force refresh from scrapers (clear cache)

func (*ProcessingCoordinator) SetForceUpdate

func (pc *ProcessingCoordinator) SetForceUpdate(forceUpdate bool)

SetForceUpdate sets whether to force update existing files

func (*ProcessingCoordinator) SetLinkMode

func (pc *ProcessingCoordinator) SetLinkMode(mode organizer.LinkMode)

SetLinkMode sets how copy operations materialize files (copy/hardlink/softlink). Link mode is ignored when move mode is enabled.

func (*ProcessingCoordinator) SetMergeStrategies

func (pc *ProcessingCoordinator) SetMergeStrategies(scalarStrategy, arrayStrategy string)

SetMergeStrategies sets scalar/array merge behavior for update mode.

func (*ProcessingCoordinator) SetMoveFiles

func (pc *ProcessingCoordinator) SetMoveFiles(moveFiles bool)

SetMoveFiles sets whether to move files instead of copying

func (*ProcessingCoordinator) SetNFOEnabled

func (pc *ProcessingCoordinator) SetNFOEnabled(enabled bool)

SetNFOEnabled sets whether NFO generation is enabled

func (*ProcessingCoordinator) SetOptions

func (pc *ProcessingCoordinator) SetOptions(scrape, download, organize, nfo bool)

SetOptions configures which operations to perform

func (*ProcessingCoordinator) SetOptionsFromConfig

func (pc *ProcessingCoordinator) SetOptionsFromConfig(cfg *config.Config)

SetOptionsFromConfig configures which operations to perform based on the application config This should be called after SetConfig to apply metadata.nfo.enabled setting

func (*ProcessingCoordinator) SetOrganizeEnabled

func (pc *ProcessingCoordinator) SetOrganizeEnabled(enabled bool)

SetOrganizeEnabled sets whether file organization is enabled

func (*ProcessingCoordinator) SetScrapeEnabled

func (pc *ProcessingCoordinator) SetScrapeEnabled(enabled bool)

SetScrapeEnabled sets whether metadata scraping is enabled

func (*ProcessingCoordinator) SetTemplateEngine

func (pc *ProcessingCoordinator) SetTemplateEngine(engine *template.Engine)

func (*ProcessingCoordinator) SetUpdateMode

func (pc *ProcessingCoordinator) SetUpdateMode(enabled bool)

SetUpdateMode sets whether update-mode merge behavior is enabled.

func (*ProcessingCoordinator) Stop

func (pc *ProcessingCoordinator) Stop()

Stop stops the worker pool

func (*ProcessingCoordinator) Wait

func (pc *ProcessingCoordinator) Wait() error

Wait waits for all tasks to complete

type ProgressMsg

type ProgressMsg struct {
	TaskID    string
	Type      worker.TaskType
	Status    worker.TaskStatus
	Progress  float64
	Message   string
	BytesDone int64
	Error     error
	Timestamp time.Time
}

ProgressMsg represents a progress update from a worker

type ProgressTrackerInterface

type ProgressTrackerInterface interface {
	Update(id string, progress float64, message string, bytesProcessed int64)
	Complete(id string, message string)
	Fail(id string, err error)
}

ProgressTrackerInterface defines the contract for progress tracking operations. Implemented by: *worker.ProgressTracker

type QuitMsg

type QuitMsg struct{}

QuitMsg signals the application should quit

type RescanMsg

type RescanMsg struct {
	Path string
}

RescanMsg signals to rescan a new folder path

type ResumeMsg

type ResumeMsg struct{}

ResumeMsg signals to resume processing

type ScanCompleteMsg

type ScanCompleteMsg struct {
	FilesFound int
	Skipped    int
	Errors     int
}

ScanCompleteMsg indicates file scanning is complete

type SettingsView

type SettingsView struct {
	// contains filtered or unexported fields
}

SettingsView component

func NewSettingsView

func NewSettingsView() *SettingsView

func (*SettingsView) Init

func (s *SettingsView) Init() tea.Cmd

func (*SettingsView) SetSize

func (s *SettingsView) SetSize(width, height int)

func (*SettingsView) Update

func (s *SettingsView) Update(msg tea.Msg) (tea.Model, tea.Cmd)

func (*SettingsView) UpdateSettings

func (s *SettingsView) UpdateSettings(
	cursor int,
	dryRun, forceUpdate, forceRefresh, moveFiles bool,
	scrapeEnabled, downloadEnabled, downloadExtrafanart, organizeEnabled, nfoEnabled, updateMode bool,
)

func (*SettingsView) View

func (s *SettingsView) View() string

type StartProcessingMsg

type StartProcessingMsg struct{}

StartProcessingMsg signals to start processing selected files

type State

type State struct {
	// View state
	CurrentView ViewMode

	// File browser state
	Cursor      int
	FileCount   int
	SelectedIdx int // Currently selected file index in browser

	// Modal states
	ShowingFolderPicker bool
	ShowingManualSearch bool
	EditingPath         bool

	// Processing state
	IsProcessing       bool
	IsPaused           bool
	ProcessingComplete bool
}

State represents the testable business state of the TUI. This is separated from the Model struct to enable unit testing independent of Bubble Tea's event-driven framework.

Philosophy: 60% testable (business logic), 40% excluded (UI rendering). This struct contains ONLY business state fields that can be tested with pure functions, NOT UI-specific fields like viewport, help, styles.

func CycleView

func CycleView(state State) State

CycleView cycles to the next view in sequence. Order: Browser -> Dashboard -> Logs -> Settings -> Browser (skips Help view). Returns a new state with the updated view.

func MoveCursorDown

func MoveCursorDown(state State, maxItems int) State

MoveCursorDown moves the cursor down by one position. Returns a new state with the updated cursor (clamped to < maxItems).

func MoveCursorUp

func MoveCursorUp(state State) State

MoveCursorUp moves the cursor up by one position. Returns a new state with the updated cursor (clamped to >= 0).

func NewState

func NewState() *State

NewState creates a new State with sensible defaults

func SetFileCount

func SetFileCount(state State, count int) State

SetFileCount updates the file count in the state. Used when files are loaded or rescanned.

func SwitchToView

func SwitchToView(state State, view ViewMode) State

SwitchToView switches to the specified view. Returns a new state with the updated view. This is a pure function with no side effects.

func ToggleHelp

func ToggleHelp(state State, previousView ViewMode) State

ToggleHelp toggles between the current view and the Help view. Returns a new state with the toggled view.

type StatsMsg

type StatsMsg struct {
	TotalTasks      int
	Pending         int
	Running         int
	Success         int
	Failed          int
	Canceled        int
	TotalBytes      int64
	DoneBytes       int64
	OverallProgress float64
	ElapsedTime     time.Duration
}

StatsMsg provides overall statistics update

type TaskCompleteMsg

type TaskCompleteMsg struct {
	TaskID   string
	Type     worker.TaskType
	Success  bool
	Error    error
	Duration time.Duration
}

TaskCompleteMsg indicates a task has completed

type TaskList

type TaskList struct {
	// contains filtered or unexported fields
}

TaskList component

func NewTaskList

func NewTaskList() *TaskList

func (*TaskList) Init

func (t *TaskList) Init() tea.Cmd

func (*TaskList) SetSize

func (t *TaskList) SetSize(width, height int)

func (*TaskList) Update

func (t *TaskList) Update(msg tea.Msg) (tea.Model, tea.Cmd)

func (*TaskList) UpdateTask

func (t *TaskList) UpdateTask(update worker.ProgressUpdate)

func (*TaskList) View

func (t *TaskList) View() string

type TickMsg

type TickMsg time.Time

TickMsg is sent periodically to update the UI

type ViewMode

type ViewMode int

ViewMode represents the current view

const (
	ViewBrowser ViewMode = iota
	ViewDashboard
	ViewLogs
	ViewSettings
	ViewHelp
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL