diff --git a/internal/commands/commands.go b/internal/commands/commands.go index 8e1a92f..a72a5db 100644 --- a/internal/commands/commands.go +++ b/internal/commands/commands.go @@ -262,15 +262,6 @@ func (c Commands) fetchAllFeeds() ([]store.Item, []ErrorItem, error) { return items, errorItems, nil } -func includes[T comparable](arr []T, item T) bool { - for _, v := range arr { - if v == item { - return true - } - } - return false -} - func (c Commands) Monitor(prog *tea.Program) { if c.config.RefreshInterval == 0 { return diff --git a/internal/commands/feeds.go b/internal/commands/feeds.go index 120bea4..143e475 100644 --- a/internal/commands/feeds.go +++ b/internal/commands/feeds.go @@ -70,6 +70,7 @@ func (c Commands) GetAllFeeds() ([]store.Item, error) { for _, f := range c.config.Feeds { if f.URL == is[i].FeedURL { is[i].FeedName = f.Name + is[i].Tags = f.Tags } } } diff --git a/internal/commands/filter.go b/internal/commands/filter.go index 78fafce..22b7907 100644 --- a/internal/commands/filter.go +++ b/internal/commands/filter.go @@ -16,15 +16,17 @@ import ( // Struct to aid in filtering items into ranks for BubbleTea type Filterer struct { FeedNames []string + Tags []string Term struct { Title string FeedNames []string + Tags []string } - Config config.FilterConfig + Config config.Config } -// Filters by feednames -func (f *Filterer) FilterByFeedName(filterValues []string, targetFilterValues []string) fuzzy.Matches { +// Generalized function for filtering over a list of options (Used for filtering by feed name and tags) +func (f *Filterer) FilterAgainstStrings(filterValues []string, targetFilterValues []string) fuzzy.Matches { // find matching feeds and keep the best matching one in case there are multiple ranksGrouped := map[int]fuzzy.Match{} for _, feedName := range filterValues { @@ -63,6 +65,7 @@ func (f *Filterer) GetItem(filterValue string) TUIItem { i.Title = splits[0] i.FeedName = strings.ToLower(splits[1]) + i.Tags = splits[2:] return i } @@ -121,22 +124,26 @@ func (f *Filterer) ExtractFiltersFor(tags ...string) []string { func (f *Filterer) Filter(targets []string) []fuzzy.Match { var targetTitles []string var targetFeedNames []string + var targetTags []string for _, target := range targets { i := f.GetItem(target) title := i.Title - if f.Config.DefaultIncludeFeedName { + if f.Config.Filtering.DefaultIncludeFeedName { title = strings.Join([]string{i.FeedName, i.Title}, " ") } targetTitles = append(targetTitles, title) targetFeedNames = append(targetFeedNames, i.FeedName) + targetTags = append(targetTags, strings.Join(i.Tags, " ")) } var ranks fuzzy.Matches - if len(f.FeedNames) == 0 { + if len(f.FeedNames) == 0 && len(f.Tags) == 0 { ranks = fuzzy.Find(f.Term.Title, targetTitles) + } else if len(f.FeedNames) > 0 { + ranks = f.FilterAgainstStrings(f.FeedNames, targetFeedNames) } else { - ranks = f.FilterByFeedName(f.FeedNames, targetFeedNames) + ranks = f.FilterAgainstStrings(f.Tags, targetTags) } sort.Stable(ranks) @@ -144,17 +151,18 @@ func (f *Filterer) Filter(targets []string) []fuzzy.Match { return ranks } -func NewFilterer(term string, config config.FilterConfig) Filterer { +func NewFilterer(term string, config config.Config) Filterer { var f Filterer f.Config = config f.Term.Title = term f.FeedNames = f.ExtractFiltersFor("feedname", "feed", "f") + f.Tags = f.ExtractFiltersFor("tag", "t") return f } -func CustomFilter(config config.FilterConfig) list.FilterFunc { +func CustomFilter(config config.Config) list.FilterFunc { return func(term string, targets []string) []list.Rank { filterer := NewFilterer(term, config) diff --git a/internal/commands/tui.go b/internal/commands/tui.go index 50a8823..2df8355 100644 --- a/internal/commands/tui.go +++ b/internal/commands/tui.go @@ -35,9 +35,12 @@ type TUIItem struct { ID int Read bool Favourite bool + Tags []string } -func (i TUIItem) FilterValue() string { return fmt.Sprintf("%s||%s", i.Title, i.FeedName) } +func (i TUIItem) FilterValue() string { + return fmt.Sprintf("%s||%s||%s", i.Title, i.FeedName, strings.Join(i.Tags, "||")) +} type model struct { selectedArticle *int @@ -170,6 +173,7 @@ func ItemToTUIItem(i store.Item) TUIItem { URL: i.Link, Read: i.Read(), Favourite: i.Favourite, + Tags: i.Tags, } } @@ -244,7 +248,7 @@ func Render(items []list.Item, cmds *Commands, errors []string, cfg *config.Conf l.FilterInput.PromptStyle = lipgloss.NewStyle().Foreground(lipgloss.Color(cfg.Theme.FilterColor)) - l.Filter = CustomFilter(cfg.Filtering) + l.Filter = CustomFilter(*cfg) ListKeyMap.SetOverrides(&l) diff --git a/internal/config/config.go b/internal/config/config.go index ee23385..979b4d5 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -20,8 +20,9 @@ var ( ) type Feed struct { - URL string `yaml:"url"` - Name string `yaml:"name,omitempty"` + URL string `yaml:"url"` + Name string `yaml:"name,omitempty"` + Tags []string `yaml:"tags,omitempty"` } type MinifluxBackend struct { diff --git a/internal/store/store.go b/internal/store/store.go index 427f131..3cee586 100644 --- a/internal/store/store.go +++ b/internal/store/store.go @@ -23,6 +23,7 @@ type Item struct { Link string GUID string Content string + Tags []string ReadAt time.Time PublishedAt time.Time UpdatedAt time.Time