Files
arr-tui/internal/ui/configapply.go
T
nilsandClaude Opus 5.5 4dba794b26 Trending, most watched and anticipated movies and series from Trakt
With an empty search box, Movies and Series show one of Trakt's public
lists: trending now, most watched this week, anticipated, popular, and
for movies the US box office. [ ] switch lists, r reloads. Each entry is
looked up in Radarr (tmdb:) or Sonarr (tvdb:), so it behaves like a
search result: details, poster, tick when in the library, add, releases.

Needs a Trakt client ID: new optional trakt.client_id setting (Config
view section "Trakt", ARR_TUI_TRAKT_CLIENT_ID), masked like the API keys
and checked by Test. ARR_TUI_TRAKT_URL points at another server for
development.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 23:05:35 +02:00

88 lines
2.6 KiB
Go

package ui
import (
"os"
"time"
"git.stinnesbeck.com/nils/arr-tui/internal/config"
)
// SetConfigSource tells the app which file the settings came from and what that
// file contains, so the Config view can save changes. raw is the file as
// written (see config.LoadFile), not the effective settings.
func (a *App) SetConfigSource(path string, raw *config.Config) {
a.cfgPath, a.cfgFile = path, raw
if a.settings != nil {
a.settings.describe()
}
}
// applyConfig puts new settings into effect without a restart.
func (a *App) applyConfig(c *config.Config) {
old := a.cfg
a.cfg = c
if old.Radarr.Service != c.Radarr.Service || old.Sonarr.Service != c.Sonarr.Service || old.SABnzbd != c.SABnzbd {
a.radarr.Reconfigure(c.Radarr.URL, c.Radarr.APIKey)
a.sonarr.Reconfigure(c.Sonarr.URL, c.Sonarr.APIKey)
a.sab.Reconfigure(c.SABnzbd.URL, c.SABnzbd.APIKey)
a.probeAll() // the indicators, right away
for _, f := range a.reconnect {
f()
}
}
if old.Trakt.ClientID != c.Trakt.ClientID {
a.trakt.Reconfigure(c.Trakt.ClientID)
}
if old.Trakt.ClientID != c.Trakt.ClientID || old.Radarr.Service != c.Radarr.Service || old.Sonarr.Service != c.Sonarr.Service {
for _, v := range a.searches {
v.forgetLists()
}
}
if old.UI.RefreshSeconds != c.UI.RefreshSeconds {
a.downloads.setInterval(time.Duration(c.UI.RefreshSeconds) * time.Second)
}
a.bell = c.UI.Bell
if old.UI.Theme != c.UI.Theme {
a.setTheme(chooseTheme(c.UI.Theme, terminalAnswers()))
}
if c.UI.ShouldNotifyDownloads() != a.notifyDone {
a.setNotifyDownloads(c.UI.ShouldNotifyDownloads())
}
if old.UI.ShowCovers() != c.UI.ShowCovers() || old.UI.CoverStyle != c.UI.CoverStyle {
a.covers = c.UI.ShowCovers()
a.restyleCovers()
}
}
// restyleCovers applies a changed poster style or switch to every detail pane.
func (a *App) restyleCovers() {
blocks, graphics := resolveCovers(a.cfg.UI.CoverStyle, os.Getenv)
if a.gfx != nil {
a.gfx.deleteAll() // the terminal's copies belong to the old images
}
a.coverStyle = blocks
switch {
case graphics && a.gfx == nil:
a.gfx = a.newGraphics()
case !graphics:
a.gfx = nil
}
a.coverCache = newCoverCache() // stored copies depend on the style (their height)
for _, p := range a.panes {
p.cover.style, p.cover.gfx = blocks, a.gfx
p.cover.cells = nil
p.Show(p.detail, p.lastRef) // fetch the poster again for the new style
}
}
// forgetPane drops a detail pane that is no longer shown (a closed drill-down).
func (a *App) forgetPane(d *detailPane) {
for i, p := range a.panes {
if p == d {
a.panes = append(a.panes[:i], a.panes[i+1:]...)
return
}
}
}