Details pane: director and cast from Trakt
With a Trakt client ID, the details of a movie or series show the director(s) or creators and up to 8 cast members with their roles below the plot, in every view. The title is found on Trakt by its TMDb/TVDB (else IMDb) id, then its people are read. Casts are cached and, like posters, only loaded once the selection rests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,8 @@ import (
|
||||
|
||||
"github.com/gdamore/tcell/v2"
|
||||
"github.com/rivo/tview"
|
||||
|
||||
"git.stinnesbeck.com/nils/arr-tui/internal/trakt"
|
||||
)
|
||||
|
||||
func rowText(screen tcell.SimulationScreen, y, x0, x1 int) string {
|
||||
@@ -137,3 +139,60 @@ func TestPosterWaitsWhileTheSelectionMoves(t *testing.T) {
|
||||
t.Error("a selection at rest should show its poster")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCastBelowThePlot(t *testing.T) {
|
||||
a := newTestApp(t)
|
||||
d := newDetailPane(a)
|
||||
dune := trakt.Ref{Kind: trakt.Movies, TMDB: 438631}
|
||||
heat := trakt.Ref{Kind: trakt.Movies, TMDB: 949}
|
||||
a.people.done[dune.Key()] = trakt.People{
|
||||
Leaders: []trakt.Person{{Name: "Denis Villeneuve", Role: "Director"}},
|
||||
Cast: []trakt.Person{{Name: "Timothée Chalamet", Role: "Paul Atreides"}, {Name: "Rebecca Ferguson", Role: "Lady Jessica"}},
|
||||
}
|
||||
a.people.done[heat.Key()] = trakt.People{}
|
||||
|
||||
// Without a Trakt client ID nothing is asked or shown.
|
||||
d.Show(detailText{head: "Dune", people: dune}, coverRef{})
|
||||
if d.cast != "" {
|
||||
t.Fatalf("cast without Trakt: %q", d.cast)
|
||||
}
|
||||
|
||||
a.trakt.Reconfigure("id")
|
||||
d.castKey, d.castShown = "", time.Time{}
|
||||
d.Show(detailText{head: "Dune", plot: "Spice.", people: dune}, coverRef{})
|
||||
if !strings.Contains(d.cast, "Director[::-] Denis Villeneuve") || !strings.Contains(d.cast, "Timothée Chalamet [gray]as Paul Atreides") {
|
||||
t.Errorf("cast %q", d.cast)
|
||||
}
|
||||
screen := tcell.NewSimulationScreen("")
|
||||
if err := screen.Init(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer screen.Fini()
|
||||
screen.SetSize(60, 20)
|
||||
d.SetRect(0, 0, 60, 20)
|
||||
d.Draw(screen)
|
||||
if got := d.text.GetText(true); !strings.Contains(got, "Spice.\n\nDirector Denis Villeneuve\nCast\nTimothée Chalamet as Paul Atreides") {
|
||||
t.Errorf("pane text %q", got)
|
||||
}
|
||||
|
||||
// A quick move to the next title waits with its cast until the selection rests.
|
||||
d.Show(detailText{head: "Heat", people: heat}, coverRef{})
|
||||
if d.cast != "" || d.castSettle == nil {
|
||||
t.Errorf("moving: cast %q", d.cast)
|
||||
}
|
||||
d.castSettle.Stop()
|
||||
}
|
||||
|
||||
func TestPeopleText(t *testing.T) {
|
||||
var cast []trakt.Person
|
||||
for i := 0; i < 10; i++ {
|
||||
cast = append(cast, trakt.Person{Name: "Actor " + string(rune('A'+i))})
|
||||
}
|
||||
got := peopleText(trakt.People{Cast: cast, Leaders: []trakt.Person{{Name: "Vince [Gilligan]"}}}, trakt.Shows)
|
||||
if !strings.HasPrefix(got, "[::b]Created by[::-] Vince [Gilligan[]") || !strings.HasSuffix(got, "[gray]and 2 more[-]") || strings.Contains(got, "Actor I") {
|
||||
t.Errorf("text %q", got)
|
||||
}
|
||||
if peopleText(trakt.People{}, trakt.Movies) != "" {
|
||||
t.Error("no people, no text")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user