package cmd import ( "fmt" "regexp" "sync" "time" tea "github.com/charmbracelet/bubbletea" ) const ( playerMaxTitleLength = 30 ) var ( regexpPosDur = regexp.MustCompile(`AV: (\d+):(\d+):(\d+) \/ (\d+):(\d+):(\d+)`) ) type playerModel struct { // entry *feedEntry // isPlayingVideo bool // // video information // videoDuration time.Duration // videoPosition time.Duration // TODO: make this smarter // finished entries to send messages about finishedEntries []int64 mpv *MPVPLayer sync.RWMutex } func (m *playerModel) Init() tea.Cmd { m.mpv = NewMPVPlayer() return nil } func (m *playerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case MsgPlayEntry: f := feedEntry(msg) go m.mpv.Queue(f) } // send message because it is finished fe := m.mpv.FinishedPlaying() if len(fe) > 0 { var cmds []tea.Cmd for _, e := range fe { cmds = append(cmds, func() tea.Msg { return MsgWatchedEntry(e.ID) }) } return m, tea.Batch(cmds...) } return m, nil } func (m *playerModel) View() string { // return "NO DONT ASK" // return fmt.Sprintf("IsPlaying: %v", m.mpv.IsPlaying()) if m.mpv.IsPlaying() { timePos := time.Time{}.Add(m.mpv.VideoPosition()) timeDur := time.Time{}.Add(m.mpv.VideoDuration()) // truncate name if needed // name := m.entry.Name name := m.mpv.CurrentlyPlaying().Name if len(name) > playerMaxTitleLength { name = name[0:playerMaxTitleLength] + "..." } return fmt.Sprintf("Playing: %s (%s/%s %.1f%%)", name, timePos.Format(time.TimeOnly), timeDur.Format(time.TimeOnly), videoPercentageWatched(m.mpv.VideoPosition(), m.mpv.VideoDuration()), ) } return "" }