minifluxmpv/cmd/cmd.go
2025-01-26 16:25:44 +01:00

110 lines
2.4 KiB
Go

package cmd
import (
"context"
"fmt"
"time"
"github.com/charmbracelet/bubbles/list"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
miniflux "miniflux.app/client"
)
var (
titleStyle = lipgloss.NewStyle().MarginLeft(2)
itemStyle = lipgloss.NewStyle().PaddingLeft(4)
selectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("170"))
paginationStyle = list.DefaultStyles().PaginationStyle.PaddingLeft(4)
helpStyle = list.DefaultStyles().HelpStyle.PaddingLeft(4).PaddingBottom(1)
quitTextStyle = lipgloss.NewStyle().Margin(1, 0, 2, 4)
)
type ViewType uint
const (
ViewListFeedEntries ViewType = iota
ViewPlayer
ViewFeeds
)
type MsgChangeView ViewType
type MsgSelectedItem feedEntry
type MsgTickInternal time.Time
type MsgTick uint8
type MinifluxPlayer struct {
MinifluxClient *miniflux.Client
DefaultCategory string
MpvPath string
CurrentView ViewType
feedEntries feedEntriesModel
player playerModel
}
func (mp *MinifluxPlayer) Init() tea.Cmd {
mp.feedEntries = feedEntriesModel{
minifluxClient: mp.MinifluxClient,
}
mp.player = playerModel{}
return tea.Sequence(
tickEvery(),
mp.feedEntries.Init(),
mp.player.Init(),
)
}
func (mp *MinifluxPlayer) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "ctrl+c", "q":
return mp, tea.Quit
}
case MsgTickInternal:
fnSendTick := func() tea.Msg { return MsgTick(0) }
return mp, tea.Batch(tickEvery(), fnSendTick)
case MsgChangeView:
mp.CurrentView = ViewType(msg)
}
if mp.CurrentView == ViewListFeedEntries {
_, c := mp.feedEntries.Update(msg)
return mp, c
} else if mp.CurrentView == ViewPlayer {
_, c := mp.player.Update(msg)
return mp, c
}
return mp, nil
}
func (mp *MinifluxPlayer) View() string {
if mp.CurrentView == ViewPlayer {
return mp.player.View()
}
if mp.player.currentlyPlaying == true {
return lipgloss.JoinVertical(0.2, mp.feedEntries.View(), "", fmt.Sprintf("Currently Playing: %s (%v/%v)",
mp.player.selectedEntry.Name,
mp.player.videoPosition,
mp.player.videoDuration,
))
}
return mp.feedEntries.View()
}
func (mp *MinifluxPlayer) FetchCategories(ctx context.Context) ([]*miniflux.Category, error) {
return mp.MinifluxClient.Categories()
}
func tickEvery() tea.Cmd {
return tea.Every(time.Second, func(t time.Time) tea.Msg {
return MsgTickInternal(t)
})
}