Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: indexing and autoread retoggle #115

Merged
9 changes: 7 additions & 2 deletions internal/commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ func (c Commands) GetGlamourisedArticle(ID int) (string, error) {
return "", fmt.Errorf("commands.FindGlamourisedArticle: %w", err)
}

if c.config.AutoRead {
if c.config.AutoRead && !article.Read() {
coolsloth55 marked this conversation as resolved.
Show resolved Hide resolved
err = c.store.ToggleRead(article.ID)
if err != nil {
return "", fmt.Errorf("[commands.go] GetGlamourisedArticle: %w", err)
Expand Down Expand Up @@ -291,7 +291,12 @@ func getStyleConfigWithOverrides(theme config.Theme) (sc ansi.StyleConfig) {
func glamouriseItem(item store.Item, theme config.Theme) (string, error) {
var mdown string

mdown += "# " + item.Title
title := item.Title
if item.Read() {
title = fmt.Sprintf("%s - %s", item.Title, theme.ReadIcon)
}

mdown += "# " + title
mdown += "\n"
mdown += item.Author
if !item.PublishedAt.IsZero() {
Expand Down
14 changes: 12 additions & 2 deletions internal/commands/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,12 @@ func updateList(msg tea.Msg, m model) (tea.Model, tea.Cmd) {
return m, m.list.NewStatusMessage("No items to mark.")
}

current := m.list.SelectedItem().(TUIItem)
item := m.list.SelectedItem()
if item == nil {
return m, m.list.NewStatusMessage("No item selected.")
}

current := item.(TUIItem)
err := m.commands.store.ToggleRead(current.ID)
if err != nil {
return m, tea.Quit
Expand Down Expand Up @@ -220,7 +225,12 @@ func updateList(msg tea.Msg, m model) (tea.Model, tea.Cmd) {
return m, m.list.NewStatusMessage("No items to favourite.")
}

current := m.list.SelectedItem().(TUIItem)
item := m.list.SelectedItem()
if item == nil {
return m, m.list.NewStatusMessage("No item selected.")
}

current := item.(TUIItem)
err := m.commands.store.ToggleFavourite(current.ID)
if err != nil {
return m, tea.Quit
Expand Down
2 changes: 2 additions & 0 deletions internal/commands/tui.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ type model struct {
list list.Model
help help.Model
viewport viewport.Model
lastRead *list.Item
lastReadIndex int
}

func (m model) Init() tea.Cmd {
Expand Down
111 changes: 100 additions & 11 deletions internal/commands/viewport.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,15 @@ func updateViewport(msg tea.Msg, m model) (tea.Model, tea.Cmd) {
m.viewport.GotoBottom()

case key.Matches(msg, ViewportKeyMap.Escape):
// reset cursor if last post is read and quit
index := m.list.Index()
length := len(m.list.Items())
if index >= length && length >= 1 {
m.list.Select(index - 1)
}

m.selectedArticle = nil
cmds = append(cmds, m.UpdateList())

case key.Matches(msg, ViewportKeyMap.OpenInBrowser):
current, err := m.commands.store.GetItemByID(*m.selectedArticle)
Expand All @@ -50,7 +58,6 @@ func updateViewport(msg tea.Msg, m model) (tea.Model, tea.Cmd) {
if err != nil {
return m, tea.Quit
}
cmds = append(cmds, m.UpdateList())

case key.Matches(msg, ViewportKeyMap.Read):
if m.commands.config.AutoRead {
Expand All @@ -64,17 +71,41 @@ func updateViewport(msg tea.Msg, m model) (tea.Model, tea.Cmd) {
if err != nil {
return m, tea.Quit
}
cmds = append(cmds, m.UpdateList())

if !m.commands.config.ShowRead {
index := m.list.Index()

if m.lastRead != nil && current.ID == (*m.lastRead).(TUIItem).ID {
// un-read re-add post back to list
m.list.InsertItem(index, *m.lastRead)
m.lastReadIndex = index
m.lastRead = nil
} else {
// remove post and store backup for un-read
items := m.list.Items()
item := items[index]
m.list.RemoveItem(index)
m.lastReadIndex = index
m.lastRead = &item
}
}

// trigger refresh to update read indication
content, err := m.commands.GetGlamourisedArticle(*m.selectedArticle)
if err != nil {
return m, tea.Quit
}
m.viewport.SetContent(content)

case key.Matches(msg, ViewportKeyMap.Prev):
current := m.list.Index()
if current-1 < 0 {
navIndex := m.getPrevIndex()
items := m.list.Items()
if m.isPrevOutOfBounds(navIndex) {
return m, nil
}

m.list.Select(current - 1)
items := m.list.Items()
item := items[current-1]
m.list.Select(navIndex)
item := items[navIndex]
id := item.(TUIItem).ID
m.selectedArticle = &id

Expand All @@ -84,16 +115,19 @@ func updateViewport(msg tea.Msg, m model) (tea.Model, tea.Cmd) {
}

m.viewport.SetContent(content)
if m.commands.config.AutoRead && !m.commands.config.ShowRead {
m.list.RemoveItem(m.list.Index())
}

case key.Matches(msg, ViewportKeyMap.Next):
current := m.list.Index()
navIndex := m.getNextIndex()
items := m.list.Items()
if current+1 >= len(items) {
if m.isNextOutOfBounds(navIndex, len(items)) {
return m, nil
}

m.list.Select(current + 1)
item := items[current+1]
m.list.Select(navIndex)
item := items[navIndex]
id := item.(TUIItem).ID
m.selectedArticle = &id

Expand All @@ -103,6 +137,10 @@ func updateViewport(msg tea.Msg, m model) (tea.Model, tea.Cmd) {
}

m.viewport.SetContent(content)
if m.commands.config.AutoRead && !m.commands.config.ShowRead {
m.list.RemoveItem(m.list.Index())
}

case key.Matches(msg, ViewportKeyMap.Quit):
return m, tea.Quit

Expand All @@ -122,6 +160,57 @@ func updateViewport(msg tea.Msg, m model) (tea.Model, tea.Cmd) {
return m, tea.Batch(cmds...)
}

func (m *model) isPrevOutOfBounds(i int) bool {
if len(m.list.Items()) == 0 {
return true
}
return i < 0
}

func (m *model) isNextOutOfBounds(i int, l int) bool {
maxIndex := l - 1

// when autoread and don't show read the first opened item doesn't exist in list
if m.commands.config.AutoRead && !m.commands.config.ShowRead && i == 0 {
maxIndex = l
}

if i < 0 || i > maxIndex || maxIndex < 0 || l == 0 {
return true
}
return false
}

func (m *model) getNextIndex() int {
if m.commands.config.AutoRead && !m.commands.config.ShowRead {
return m.list.Index()
}

// check for favorite within post
current, err := m.commands.store.GetItemByID(*m.selectedArticle)
if err != nil {
return m.list.Index()
}
if !m.commands.config.AutoRead && current.Read() && !m.commands.config.ShowRead {
return m.list.Index()
}

return m.list.Index() + 1
}

func (m *model) getPrevIndex() int {
current := m.list.Index()
if m.commands.config.AutoRead && !m.commands.config.ShowRead && current < len(m.list.Items()) {
return m.list.Index()
}

if current == 0 {
return 0
}

return m.list.Index() - 1
}

func viewportView(m model) string {
return m.viewport.View() + "\n" + m.viewportHelp()
}
Expand Down
6 changes: 6 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type Theme struct {
TitleColor string `yaml:"titleColor,omitempty"`
FilterColor string `yaml:"filterColor,omitempty"`
SelectedItemColor string `yaml:"selectedItemColor,omitempty"`
ReadIcon string `yaml:"readIcon,omitempty"`
}

// need to add to Load() below if loading from config file
Expand Down Expand Up @@ -111,6 +112,7 @@ func New(configPath string, pager string, previewFeeds []string, version string)
SelectedItemColor: "170",
TitleColor: "62",
FilterColor: "62",
ReadIcon: "\u2713",
},
Ordering: constants.DefaultOrdering,
HTTPOptions: &HTTPOptions{
Expand Down Expand Up @@ -157,6 +159,10 @@ func (c *Config) Load() error {
c.Ordering = fileConfig.Ordering
}

if len(fileConfig.Theme.ReadIcon) > 0 {
c.Theme.ReadIcon = fileConfig.Theme.ReadIcon
}

if fileConfig.Theme.Glamour != "" {
c.Theme.Glamour = fileConfig.Theme.Glamour
}
Expand Down
Loading