~chrisppy/beagles

c15f9b92e48e78d3dca0b6b1e12cfc674843a923 — Chris Palmer 1 year, 11 months ago 1d92da5
Breaking Change: Finish adding subscription page
5 files changed, 103 insertions(+), 15 deletions(-)

M CHANGELOG.md
M db/db.go
M model/feed.go
M ui/tree.go
M ui/ui.go
M CHANGELOG.md => CHANGELOG.md +3 -3
@@ 6,9 6,9 @@
      deleting the database and starting anew
  - Multiple performance fixes for update
  - Fix navigation keys to use native cview navigation
  - Add Subscription Page
  - Add Tree config theme for subscription page
  - Add Unread key command to config
  - Add subscription Page
  - Add tree config theme for subscription page
  - Add unread key command to config
  - Add tree to config
  - Add favorite to item model


M db/db.go => db/db.go +57 -6
@@ 397,14 397,27 @@ func (s *Storage) MarkRead(key string) error {
		return fmt.Errorf("key was empty, unable to mark read")
	}

	item := s.Items[key]
	if item.Read {
		return nil
	}

	db, err := openDB(s.Path)
	if err != nil {
		return fmt.Errorf("unable to open db: %s", err.Error())
	}

	item := s.Items[key]
	item.Read = true

	feedKey := item.FeedURL
	feed, ok := s.Feeds[feedKey]
	if !ok {
		return fmt.Errorf("unable to find feed, unable to mark read")
	}
	if feed.Unread > 0 {
		feed.Unread--
	}

	itemJSON, err := json.Marshal(item)
	if err != nil {
		if err := db.Close(); err != nil {


@@ 413,6 426,14 @@ func (s *Storage) MarkRead(key string) error {
		return fmt.Errorf("unable to marshal item: %s", err.Error())
	}

	feedJSON, err := json.Marshal(feed)
	if err != nil {
		if err := db.Close(); err != nil {
			return err
		}
		return fmt.Errorf("unable to marshal feed item: %s", err.Error())
	}

	if err := db.Update(func(tx *bolt.Tx) error {
		// Remove from Queue Database
		if err := tx.Bucket([]byte(queueTbl)).Delete([]byte(key)); err != nil {


@@ 424,13 445,18 @@ func (s *Storage) MarkRead(key string) error {
			return fmt.Errorf("error putting into item bucket: %s", err.Error())
		}

		// increment unread in Feed Database
		if err := tx.Bucket([]byte(feedTbl)).Put([]byte(feedKey), feedJSON); err != nil {
			return fmt.Errorf("error putting into feed bucket: %s", err.Error())
		}

		return nil

	}); err != nil {
		if err := db.Close(); err != nil {
			return err
		}
		return fmt.Errorf("item, and queue: %s", err.Error())
		return fmt.Errorf("feed, item, and queue: %s", err.Error())
	}

	if err := db.Close(); err != nil {


@@ 446,7 472,12 @@ func (s *Storage) MarkRead(key string) error {
// add the item from the list.
func (s *Storage) MarkUnread(key string) error {
	if key == "" {
		return fmt.Errorf("item key was empty, unable to mark unread")
		return fmt.Errorf("key was empty, unable to mark unread")
	}

	item := s.Items[key]
	if !item.Read {
		return nil
	}

	db, err := openDB(s.Path)


@@ 454,9 485,16 @@ func (s *Storage) MarkUnread(key string) error {
		return fmt.Errorf("unable to open db: %s", err.Error())
	}

	item := s.Items[key]
	item.Read = false

	feedKey := item.FeedURL
	feed, ok := s.Feeds[feedKey]
	if !ok {
		return fmt.Errorf("unable to find feed, unable to mark unread")
	}

	feed.Unread++

	queue := &model.QueueItem{
		Item:        *item,
		PlaybackPOS: 0,


@@ 478,8 516,16 @@ func (s *Storage) MarkUnread(key string) error {
		return fmt.Errorf("unable to marshal queue item: %s", err.Error())
	}

	feedJSON, err := json.Marshal(feed)
	if err != nil {
		if err := db.Close(); err != nil {
			return err
		}
		return fmt.Errorf("unable to marshal feed item: %s", err.Error())
	}

	if err := db.Update(func(tx *bolt.Tx) error {
		// Remove from Queue Database
		// Add to Queue Database
		if err := tx.Bucket([]byte(queueTbl)).Put([]byte(key), queueJSON); err != nil {
			return fmt.Errorf("error putting into queue bucket: %s", err.Error())
		}


@@ 489,13 535,18 @@ func (s *Storage) MarkUnread(key string) error {
			return fmt.Errorf("error putting into item bucket: %s", err.Error())
		}

		// increment unread in Feed Database
		if err := tx.Bucket([]byte(feedTbl)).Put([]byte(feedKey), feedJSON); err != nil {
			return fmt.Errorf("error putting into feed bucket: %s", err.Error())
		}

		return nil

	}); err != nil {
		if err := db.Close(); err != nil {
			return err
		}
		return fmt.Errorf("item, and queue: %s", err.Error())
		return fmt.Errorf("feed, item, and queue: %s", err.Error())
	}

	if err := db.Close(); err != nil {

M model/feed.go => model/feed.go +3 -0
@@ 35,6 35,7 @@ type Feed struct {
	UpdateURL   string          `json:"updateurl"`
	Link        string          `json:"link"`
	Items       map[string]bool `json:"items"`
	Unread      int             `json:"unread"`
}

// CreateFeed will process the RSS/ATOM Feed into our Feed structure


@@ 49,6 50,7 @@ func CreateFeed(feed *gofeed.Feed, url string) *Feed {
		UpdateURL:   url,
		Link:        feed.FeedLink,
		Items:       make(map[string]bool),
		Unread:      len(feed.Items),
	}

	if f.Link == "" {


@@ 76,6 78,7 @@ func (f *Feed) FindNewItems() (map[string]*Item, error) {
		}

		i := CreateItem(item)
		i.FeedURL = f.UpdateURL
		items[i.Link] = i
	}


M ui/tree.go => ui/tree.go +37 -6
@@ 72,13 72,17 @@ func newTree(config *config.Config) *tree {
	}
}

func (w *tree) add(item *model.Feed, itemMap model.Items) {
func (w *tree) add(f *model.Feed, itemMap model.Items) {
	i := 0
	items := make([]*tui.TreeNode, len(item.Items))
	for k := range item.Items {
	items := make([]*tui.TreeNode, len(f.Items))
	for k := range f.Items {
		it := itemMap[k]

		n := tui.NewTreeNode(it.Title)
		name := it.Title
		if strings.Contains(it.Type, "audio") {
			name = fmt.Sprintf("🎧 %s", name)
		}
		n := tui.NewTreeNode(name)
		n.SetReference(it.Link)

		n.SetColor(tcell.GetColor(w.TextColor))


@@ 96,9 100,13 @@ func (w *tree) add(item *model.Feed, itemMap model.Items) {
		return w.Dates[a].Sub(w.Dates[b]) < 0
	})

	node := tui.NewTreeNode(item.Title)
	title := f.Title
	if f.Unread != 0 {
		title = fmt.Sprintf("%s (*%d)", title, f.Unread)
	}
	node := tui.NewTreeNode(title)
	node.SetColor(tcell.GetColor(w.TextColor))
	node.SetReference(item.UpdateURL)
	node.SetReference(f.UpdateURL)
	node.SetChildren(items)
	node.Collapse()



@@ 133,6 141,29 @@ func (w *tree) markUnread() {
	n.SetColor(tcell.GetColor(w.TextColor))
}

func (w *tree) updateReadCount(feeds model.Feeds, itemMap model.Items) {
	item, ok := itemMap[w.getKey()]
	if !ok {
		return
	}

	f, ok := feeds[item.FeedURL]
	if !ok {
		return
	}

	for _, c := range w.ChildNodes {
		if f.UpdateURL == fmt.Sprintf("%v", c.GetReference()) {
			title := f.Title
			if f.Unread != 0 {
				title = fmt.Sprintf("%s (*%d)", title, f.Unread)
			}
			c.SetText(title)
			break
		}
	}
}

func (w *tree) refresh(feeds model.Feeds, itemMap model.Items) {
	w.Node.ClearChildren()


M ui/ui.go => ui/ui.go +3 -0
@@ 280,6 280,7 @@ func (i *UI) markUnread(event *tcell.EventKey) *tcell.EventKey {
			}
			i.list.refresh(i.DB.Queue)
			i.subTree.markUnread()
			i.subTree.updateReadCount(i.DB.Feeds, i.DB.Items)
		})
	}



@@ 333,6 334,8 @@ func (i *UI) markRead(event *tcell.EventKey) *tcell.EventKey {
				i.list.removeByKey(key)
				i.list.refresh(i.DB.Queue)
				i.subTree.markRead()
				i.subTree.updateReadCount(i.DB.Feeds, i.DB.Items)

			}
		})
		return nil