diff --git a/Network/searchAnimeinAnimeFire.go b/Network/searchAnimeinAnimeFire.go index 84a0267..2b4a064 100644 --- a/Network/searchAnimeinAnimeFire.go +++ b/Network/searchAnimeinAnimeFire.go @@ -19,7 +19,7 @@ type AnimeSearcher struct { AnimeName string } -func (as *AnimeSearcher) SearchAnimeInAnimeFire() (string, string, error) { +func (as *AnimeSearcher) SearchAnimeInAnimeFire() (string, string) { animeName := utils.NameAnimeTreating(as.AnimeName) currentPageUrl := fmt.Sprintf("%s/pesquisar/%s", "https://www.animefire.net", animeName) @@ -63,10 +63,11 @@ func (as *AnimeSearcher) SearchAnimeInAnimeFire() (string, string, error) { }) if len(animes) > 0 { - index := tui.SelectAnimes(animes) - selectedAnime := animes[index] - - return selectedAnime.Url, selectedAnime.Name, nil + selectedAnimeName, selectedUrl, err := tui.SelectAnimes(animes) + if err != nil { + message.ErrorMessage(err.Error()) + } + return selectedAnimeName, selectedUrl } nextPage, exists := doc.Find(".pagination .next a").Attr("href") diff --git a/Tui/selectAnime.go b/Tui/selectAnime.go index 0c05200..db0fa03 100644 --- a/Tui/selectAnime.go +++ b/Tui/selectAnime.go @@ -1,80 +1,96 @@ package tui import ( - message "animatic-v2/Message" - structure "animatic-v2/Structures" - "os" - "os/signal" - "syscall" + "animatic-v2/Structures" + "errors" + "github.com/charmbracelet/bubbles/table" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" ) -type selectAnimeModel struct { - cursor int - animes []structure.Anime - choice int - err error +const ( + AnimeNameColumnTitle = "Anime Name" + AnimeURLColumnTitle = "Anime URL" +) + +type SelectAnimeModel struct { + table table.Model + selectedURL string + selectedAnimeName string } -func (m *selectAnimeModel) Init() tea.Cmd { - return tea.Batch(tea.ClearScreen) +func (m *SelectAnimeModel) Init() tea.Cmd { + return nil } -func (m *selectAnimeModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (m *SelectAnimeModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + var cmd tea.Cmd + switch msg := msg.(type) { case tea.KeyMsg: - switch msg.Type { - case tea.KeyUp: - if m.cursor > 0 { - m.cursor-- - } - case tea.KeyDown: - if m.cursor < len(m.animes)-1 { - m.cursor++ - } - case tea.KeyEnter: - m.choice = m.cursor + switch msg.String() { + case "esc": + tea.Quit() + case "q", "ctrl+c": + return m, tea.Quit + case "enter": + m.selectedAnimeName = m.table.SelectedRow()[0] + m.selectedURL = m.table.SelectedRow()[1] return m, tea.Quit - case tea.KeyCtrlC: - os.Exit(0) } } - return m, nil + m.table, cmd = m.table.Update(msg) + return m, cmd } -func (m *selectAnimeModel) View() string { - cursorStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#00FF00")).Bold(true) - listStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#FFFFFF")) - s := listStyle.Render("Select the anime:\n") - for i, anime := range m.animes { - cursor := " " - if m.cursor == i { - cursor = cursorStyle.Render("▶") - } - s += cursor + " " + listStyle.Render(anime.Name) + "\n" - } - return s +func (m *SelectAnimeModel) View() string { + return m.table.View() } -func SelectAnimes(animes []structure.Anime) int { - m := &selectAnimeModel{animes: animes} // Use um ponteiro para o modelo - p := tea.NewProgram(m) +func SelectAnimes(animes []Structures.Anime) (string, string, error) { + if len(animes) == 0 { + return "", "", errors.New("Anime List is empty") + } + + columns := []table.Column{ + {Title: AnimeNameColumnTitle, Width: 50}, + {Title: AnimeURLColumnTitle, Width: 50}, + } + + rows := make([]table.Row, 0, len(animes)) + + for _, anime := range animes { + rows = append(rows, table.Row{anime.Name, anime.Url}) + } + + t := table.New( + table.WithColumns(columns), + table.WithRows(rows), + table.WithFocused(true), + table.WithHeight(len(animes)), + ) - c := make(chan os.Signal) - signal.Notify(c, os.Interrupt, syscall.SIGTERM) - go func() { - <-c - tea.ClearScreen() - tea.ShowCursor() - os.Exit(0) - }() + s := table.DefaultStyles() + s.Header = s.Header. + BorderStyle(lipgloss.NormalBorder()). + BorderForeground(lipgloss.Color("240")). + BorderBottom(true). + Bold(false) + + s.Selected = s.Selected. + Foreground(lipgloss.Color("229")). + Background(lipgloss.Color("57")). + Bold(false) + + t.SetStyles(s) + + m := &SelectAnimeModel{table: t} + p := tea.NewProgram(m) if err := p.Start(); err != nil { - message.ErrorMessage(err.Error()) - return -1 + return "", "", err } - return m.choice + return m.selectedAnimeName, m.selectedURL, nil } diff --git a/go.mod b/go.mod index dcd1d1c..51c5a0a 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.21.5 require ( github.com/PuerkitoBio/goquery v1.8.1 github.com/cavaliergopher/grab/v3 v3.0.1 + github.com/charmbracelet/bubbles v0.17.1 github.com/charmbracelet/bubbletea v0.25.0 github.com/charmbracelet/lipgloss v0.9.1 github.com/jarcoal/httpmock v1.3.1 @@ -22,7 +23,7 @@ require ( github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/termenv v0.15.2 // indirect - github.com/rivo/uniseg v0.2.0 // indirect + github.com/rivo/uniseg v0.4.3 // indirect golang.org/x/net v0.7.0 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.12.0 // indirect diff --git a/go.sum b/go.sum index 1ab30cc..04ded75 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/cavaliergopher/grab/v3 v3.0.1 h1:4z7TkBfmPjmLAAmkkAZNX/6QJ1nNFdv3SdIHXju0Fr4= github.com/cavaliergopher/grab/v3 v3.0.1/go.mod h1:1U/KNnD+Ft6JJiYoYBAimKH2XrYptb8Kl3DFGmsjpq4= +github.com/charmbracelet/bubbles v0.17.1 h1:0SIyjOnkrsfDo88YvPgAWvZMwXe26TP6drRvmkjyUu4= +github.com/charmbracelet/bubbles v0.17.1/go.mod h1:9HxZWlkCqz2PRwsCbYl7a3KXvGzFaDHpYbSYMJ+nE3o= github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM= github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg= github.com/charmbracelet/lipgloss v0.9.1 h1:PNyd3jvaJbg4jRHKWXnCj1akQm4rh8dbEzN1p/u1KWg= @@ -36,8 +38,9 @@ github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKt github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= +github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= diff --git a/main.go b/main.go index 5fdd4ab..3b38a6b 100644 --- a/main.go +++ b/main.go @@ -27,16 +27,14 @@ func main() { } animeSearcher := network.AnimeSearcher{AnimeName: animeName} - animeURL, animeSelectedName, err := animeSearcher.SearchAnimeInAnimeFire() + animeSelectedName, animeURL := animeSearcher.SearchAnimeInAnimeFire() + if runtime.GOOS != "windows" { destPath = filepath.Join("/chromeMedia/Series/", utils.SplitAnimeName(animeSelectedName)) } else { userProfile := os.Getenv("USERPROFILE") destPath = filepath.Join(userProfile, "chromeMedia\\Series\\", utils.SplitAnimeName(animeSelectedName)) } - if err != nil { - message.ErrorMessage("Failed to Locate anime") - } anime := network.Anime{URL: animeURL} epList := anime.GetEpisodes()