diff --git a/cmd/cmd.go b/cmd/cmd.go index 2348bbd..74330e8 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -2,7 +2,6 @@ package cmd import ( "context" - "fmt" "time" "github.com/charmbracelet/bubbles/list" @@ -29,9 +28,9 @@ const ( ) type MsgChangeView ViewType -type MsgSelectedItem feedEntry -type MsgTickInternal time.Time -type MsgTick uint8 +type MsgPlayEntry feedEntry +type MsgWatchedEntry int64 +type MsgTick time.Time type MinifluxPlayer struct { MinifluxClient *miniflux.Client @@ -59,28 +58,28 @@ func (mp *MinifluxPlayer) Init() tea.Cmd { } func (mp *MinifluxPlayer) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + var cmds []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 MsgTick: + cmds = append(cmds, tickEvery()) 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 - } + // always update all models + _, cmdFeeds := mp.feedEntries.Update(msg) + _, cmdPlayer := mp.player.Update(msg) - return mp, nil + cmds = append(cmds, cmdFeeds) + cmds = append(cmds, cmdPlayer) + + return mp, tea.Batch(cmds...) } func (mp *MinifluxPlayer) View() string { @@ -88,15 +87,7 @@ func (mp *MinifluxPlayer) View() string { 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() + return lipgloss.JoinVertical(0.2, mp.feedEntries.View(), "", mp.player.View()) } func (mp *MinifluxPlayer) FetchCategories(ctx context.Context) ([]*miniflux.Category, error) { @@ -105,6 +96,6 @@ func (mp *MinifluxPlayer) FetchCategories(ctx context.Context) ([]*miniflux.Cate func tickEvery() tea.Cmd { return tea.Every(time.Second, func(t time.Time) tea.Msg { - return MsgTickInternal(t) + return MsgTick(t) }) } diff --git a/cmd/feed_entries.go b/cmd/feed_entries.go index f20014d..53bd50a 100644 --- a/cmd/feed_entries.go +++ b/cmd/feed_entries.go @@ -12,6 +12,7 @@ import ( ) type feedEntry struct { + ID int64 Name string Feed string Link string @@ -35,7 +36,7 @@ type MsgFetchedEntries []feedEntry type MsgFetchedEntriesError error func (m *feedEntriesModel) fetchEntries() tea.Msg { - entriesResult, err := m.minifluxClient.CategoryEntries(4, nil) + entriesResult, err := m.minifluxClient.CategoryEntries(4, &miniflux.Filter{Statuses: []string{miniflux.EntryStatusUnread}}) if err != nil { return MsgFetchedEntriesError(err) } @@ -43,6 +44,7 @@ func (m *feedEntriesModel) fetchEntries() tea.Msg { var feedEntries []feedEntry for _, e := range entriesResult.Entries { feedEntries = append(feedEntries, feedEntry{ + ID: e.ID, Name: e.Title, Feed: e.Feed.Title, Link: e.URL, @@ -65,21 +67,22 @@ func (m *feedEntriesModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case tea.KeyMsg: switch msg.String() { case "enter": - fnChangeView := func() tea.Msg { return MsgChangeView(ViewPlayer) } - fnGetSelected := func() tea.Msg { i, ok := m.entries.SelectedItem().(feedEntry) if ok { m.selectedEntry = &i } - return MsgSelectedItem(i) + return MsgPlayEntry(i) } - return m, tea.Sequence(fnChangeView, fnGetSelected) + return m, fnGetSelected } break + case MsgWatchedEntry: + m.markEntryRead(int64(msg)) + case MsgFetchedEntries: var items []list.Item for _, e := range msg { @@ -98,3 +101,7 @@ func (m *feedEntriesModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m *feedEntriesModel) View() string { return m.entries.View() } + +func (m *feedEntriesModel) markEntryRead(entryID int64) { + m.minifluxClient.UpdateEntries([]int64{entryID}, miniflux.EntryStatusRead) +} diff --git a/go.mod b/go.mod index 67f0ec8..dc94cec 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/charmbracelet/x/term v0.2.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect @@ -20,6 +21,7 @@ require ( github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/termenv v0.15.2 // indirect github.com/rivo/uniseg v0.4.7 // indirect + github.com/rs/zerolog v1.33.0 // indirect github.com/sahilm/fuzzy v0.1.1 // indirect github.com/simonhege/timeago v1.0.0-rc5 // indirect golang.org/x/sync v0.9.0 // indirect diff --git a/go.sum b/go.sum index 4056c75..74beac9 100644 --- a/go.sum +++ b/go.sum @@ -14,10 +14,16 @@ github.com/charmbracelet/x/ansi v0.4.5 h1:LqK4vwBNaXw2AyGIICa5/29Sbdq58GbGdFngSe github.com/charmbracelet/x/ansi v0.4.5/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= @@ -32,9 +38,13 @@ github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELU github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA= github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/simonhege/timeago v1.0.0-rc5 h1:Fx6M3eLoSdZDRX1fYf0ZKEHK6dlmvfLY+zHRwsnOGNU= @@ -42,7 +52,9 @@ github.com/simonhege/timeago v1.0.0-rc5/go.mod h1:PfcxupQPucgCUBC1uH6OI1vHaKuhDv golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=