diff --git a/config.example.ini b/config.example.ini index 46a20ca..4bc8e0b 100644 --- a/config.example.ini +++ b/config.example.ini @@ -19,18 +19,22 @@ mouse-support=false # Tag is special as you need to add the tag after, see the example below. # # The syntax is: -# timelines=feed,[name],[keys...] +# timelines=feed,[name],[keys...],[showBoosts],[showReplies] # # Tha values in brackets are optional. You can see the syntax for keys under the # [input] section. # +# showBoosts and showReplies must be formated as bools. So either true or false. +# They always defaults to true. +# # Some examples: # # home timeline with the name Home # timelines=home,Home # -# local timeline with the name Local and it gets focus when you press 2 -# timelines=local,Local,'2' +# local timeline with the name Local and it gets focus when you press 2. It will +# also hide boosts in the timeline, but show toots that are replies. +# timelines=local,Local,'2',false,true # # notification timeline with the name [N]otifications and it gets focus when you # press n or N @@ -119,6 +123,11 @@ show-filter-phrase=true # default=true show-help=true +# If you always want tut to jump to the newest post. May ruin your reading +# experience. +# default=false +stick-to-top=false + # 0 = No terminal title # 1 = Show title in terminal and top bar # 2 = Only show terminal title, and no top bar in tut. @@ -251,7 +260,7 @@ link-viewer=xdg-open link-terminal=false [open-custom] -# This sections allows you to set up to five custom programs to upen URLs with. +# This sections allows you to set up to five custom programs to open URLs with. # If the url points to an image, you can set c1-name to img and c1-use to imv. # If the program runs in a terminal and you want to run it in the same terminal # as tut. Set cX-terminal to true. The name will show up in the UI, so keep it @@ -364,7 +373,7 @@ background= # default= text= -# The color to display sublte elements or subtle text. Like lines and help text. +# The color to display subtle elements or subtle text. Like lines and help text. # default= subtle= @@ -404,6 +413,10 @@ status-bar-view-background= # default= status-bar-view-text= +# The color of the text in the command bar at the bottom. +# default= +command-text= + # Background of selected list items. # default= list-selected-background= @@ -488,7 +501,7 @@ timeline-name-text= # with single quotation marks or double ones. # # The single ones are for single chars like 'a', 'b', 'c' and double marks are -# for special keys like "Enter". Remember that they are case sensetive. +# for special keys like "Enter". Remember that they are case sensitive. # # To find the names of special keys you have to go to the following site and # look for "var KeyNames = map[Key]string{" diff --git a/config/config.go b/config/config.go index 1af4833..fe22d80 100644 --- a/config/config.go +++ b/config/config.go @@ -12,9 +12,9 @@ import ( "strings" "text/template" - "github.com/RasmusLindroth/tut/feed" "github.com/gdamore/tcell/v2" "github.com/gobwas/glob" + "golang.org/x/exp/slices" "gopkg.in/ini.v1" ) @@ -82,11 +82,43 @@ const ( LeaderLoadNewer ) +type FeedType uint + +const ( + Favorites FeedType = iota + Favorited + Boosts + Followers + Following + FollowRequests + Blocking + Muting + History + InvalidFeed + Notifications + Saved + Tag + Tags + Thread + TimelineFederated + TimelineHome + TimelineLocal + Conversations + User + UserList + Lists + List + ListUsersIn + ListUsersAdd +) + type Timeline struct { - FeedType feed.FeedType - Subaction string - Name string - Key Key + FeedType FeedType + Subaction string + Name string + Key Key + ShowBoosts bool + ShowReplies bool } type General struct { @@ -96,7 +128,7 @@ type General struct { DateFormat string DateRelative int MaxWidth int - StartTimeline feed.FeedType + StartTimeline FeedType NotificationFeed bool QuoteReply bool CharLimit int @@ -115,6 +147,7 @@ type General struct { LeaderActions []LeaderAction TimelineName bool Timelines []Timeline + StickToTop bool } type Style struct { @@ -160,6 +193,8 @@ type Style struct { TimelineNameText tcell.Color IconColor tcell.Color + + CommandText tcell.Color } type Media struct { @@ -621,6 +656,12 @@ func parseStyle(cfg *ini.File, cnfPath string, cnfDir string) Style { } else { style.TimelineNameText = style.Subtle } + s = tcfg.Section("").Key("command-text").String() + if len(s) > 0 { + style.CommandText = tcell.GetColor(s) + } else { + style.CommandText = style.StatusBarText + } } else { s := cfg.Section("style").Key("background").String() style.Background = parseColor(s, "#27822", xrdbColors) @@ -740,6 +781,13 @@ func parseStyle(cfg *ini.File, cnfPath string, cnfDir string) Style { } else { style.TimelineNameText = style.Subtle } + + s = cfg.Section("style").Key("command-text").String() + if len(s) > 0 { + style.CommandText = parseColor(s, "white", xrdbColors) + } else { + style.CommandText = style.StatusBarText + } } return style @@ -771,13 +819,13 @@ func parseGeneral(cfg *ini.File) General { tl := cfg.Section("general").Key("timeline").In("home", []string{"home", "direct", "local", "federated"}) switch tl { case "direct": - general.StartTimeline = feed.Conversations + general.StartTimeline = Conversations case "local": - general.StartTimeline = feed.TimelineLocal + general.StartTimeline = TimelineLocal case "federated": - general.StartTimeline = feed.TimelineFederated + general.StartTimeline = TimelineFederated default: - general.StartTimeline = feed.TimelineHome + general.StartTimeline = TimelineHome } general.NotificationFeed = cfg.Section("general").Key("notification-feed").MustBool(true) @@ -789,6 +837,7 @@ func parseGeneral(cfg *ini.File) General { general.ShowIcons = cfg.Section("general").Key("show-icons").MustBool(true) general.ShowHelp = cfg.Section("general").Key("show-help").MustBool(true) general.RedrawUI = cfg.Section("general").Key("redraw-ui").MustBool(true) + general.StickToTop = cfg.Section("general").Key("stick-to-top").MustBool(false) lp := cfg.Section("general").Key("list-placement").In("left", []string{"left", "right", "top", "bottom"}) switch lp { @@ -950,50 +999,72 @@ func parseGeneral(cfg *ini.File) General { tl := Timeline{} switch cmd { case "home": - tl.FeedType = feed.TimelineHome + tl.FeedType = TimelineHome case "direct": - tl.FeedType = feed.Conversations + tl.FeedType = Conversations case "local": - tl.FeedType = feed.TimelineLocal + tl.FeedType = TimelineLocal case "federated": - tl.FeedType = feed.TimelineFederated + tl.FeedType = TimelineFederated case "bookmarks": - tl.FeedType = feed.Saved + tl.FeedType = Saved case "saved": - tl.FeedType = feed.Saved + tl.FeedType = Saved case "favorited": - tl.FeedType = feed.Favorited + tl.FeedType = Favorited case "notifications": - tl.FeedType = feed.Notification + tl.FeedType = Notifications case "lists": - tl.FeedType = feed.Lists + tl.FeedType = Lists case "tag": - tl.FeedType = feed.Tag + tl.FeedType = Tag tl.Subaction = subaction default: fmt.Printf("timeline %s is invalid\n", parts[0]) os.Exit(1) } tl.Name = parts[1] + tfs := []bool{true, true} + tfStr := []string{"true", "false"} + stop := len(parts) if len(parts) > 2 { - vals := []string{""} - vals = append(vals, parts[2:]...) - tl.Key = inputStrOrErr(vals, false) + if slices.Contains(tfStr, parts[len(parts)-2]) && + slices.Contains(tfStr, parts[len(parts)-1]) && + len(parts)-2 > 1 { + tfs[0] = parts[len(parts)-2] == "true" + tfs[1] = parts[len(parts)-1] == "true" + stop = len(parts) - 2 + } else if slices.Contains(tfStr, parts[len(parts)-1]) && + len(parts)-1 > 1 { + tfs[0] = parts[len(parts)-1] == "true" + stop = len(parts) - 1 + } + if stop > 2 { + vals := []string{""} + vals = append(vals, parts[2:stop]...) + tl.Key = inputStrOrErr(vals, false) + } } + tl.ShowBoosts = tfs[0] + tl.ShowReplies = tfs[1] tls = append(tls, tl) } if len(tls) == 0 { tls = append(tls, Timeline{ - FeedType: feed.TimelineHome, - Name: "", + FeedType: TimelineHome, + Name: "", + ShowBoosts: true, + ShowReplies: true, }, ) tls = append(tls, Timeline{ - FeedType: feed.Notification, - Name: "[N]otifications", - Key: inputStrOrErr([]string{"", "'n'", "'N'"}, false), + FeedType: Notifications, + Name: "[N]otifications", + Key: inputStrOrErr([]string{"", "'n'", "'N'"}, false), + ShowBoosts: true, + ShowReplies: true, }, ) } diff --git a/config/default_config.go b/config/default_config.go index f59e641..eb82c7e 100644 --- a/config/default_config.go +++ b/config/default_config.go @@ -21,18 +21,22 @@ mouse-support=false # Tag is special as you need to add the tag after, see the example below. # # The syntax is: -# timelines=feed,[name],[keys...] +# timelines=feed,[name],[keys...],[showBoosts],[showReplies] # # Tha values in brackets are optional. You can see the syntax for keys under the # [input] section. # +# showBoosts and showReplies must be formated as bools. So either true or false. +# They always defaults to true. +# # Some examples: # # home timeline with the name Home # timelines=home,Home # -# local timeline with the name Local and it gets focus when you press 2 -# timelines=local,Local,'2' +# local timeline with the name Local and it gets focus when you press 2. It will +# also hide boosts in the timeline, but show toots that are replies. +# timelines=local,Local,'2',false,true # # notification timeline with the name [N]otifications and it gets focus when you # press n or N @@ -121,6 +125,11 @@ show-filter-phrase=true # default=true show-help=true +# If you always want tut to jump to the newest post. May ruin your reading +# experience. +# default=false +stick-to-top=false + # 0 = No terminal title # 1 = Show title in terminal and top bar # 2 = Only show terminal title, and no top bar in tut. @@ -253,7 +262,7 @@ link-viewer=xdg-open link-terminal=false [open-custom] -# This sections allows you to set up to five custom programs to upen URLs with. +# This sections allows you to set up to five custom programs to open URLs with. # If the url points to an image, you can set c1-name to img and c1-use to imv. # If the program runs in a terminal and you want to run it in the same terminal # as tut. Set cX-terminal to true. The name will show up in the UI, so keep it @@ -366,7 +375,7 @@ background= # default= text= -# The color to display sublte elements or subtle text. Like lines and help text. +# The color to display subtle elements or subtle text. Like lines and help text. # default= subtle= @@ -406,6 +415,10 @@ status-bar-view-background= # default= status-bar-view-text= +# The color of the text in the command bar at the bottom. +# default= +command-text= + # Background of selected list items. # default= list-selected-background= @@ -490,7 +503,7 @@ timeline-name-text= # with single quotation marks or double ones. # # The single ones are for single chars like 'a', 'b', 'c' and double marks are -# for special keys like "Enter". Remember that they are case sensetive. +# for special keys like "Enter". Remember that they are case sensitive. # # To find the names of special keys you have to go to the following site and # look for "var KeyNames = map[Key]string{" diff --git a/config/themes/default.ini b/config/themes/default.ini index a1ce9b3..668f6f5 100644 --- a/config/themes/default.ini +++ b/config/themes/default.ini @@ -10,6 +10,7 @@ status-bar-background=#f92672 status-bar-text=#f8f8f2 status-bar-view-background=#ae81ff status-bar-view-text=#f8f8f2 +command-text=#f8f8f2 list-selected-background=#f92672 list-selected-text=#f8f8f2 list-selected-inactive-background=#ae81ff diff --git a/config/themes/papercolor-light.ini b/config/themes/papercolor-light.ini index 83d80ab..93a8fc1 100644 --- a/config/themes/papercolor-light.ini +++ b/config/themes/papercolor-light.ini @@ -17,5 +17,6 @@ status-bar-background=#4271AE status-bar-text=#EEEEEE status-bar-view-background=#718C00 status-bar-view-text=#f5f5f5 +command-text=#4D4D4C list-selected-background=#D7005F list-selected-text=#f5f5f5 diff --git a/feed/feed.go b/feed/feed.go index 056b48b..06ba599 100644 --- a/feed/feed.go +++ b/feed/feed.go @@ -2,7 +2,6 @@ package feed import ( "context" - "errors" "log" "strings" "sync" @@ -10,6 +9,7 @@ import ( "github.com/RasmusLindroth/go-mastodon" "github.com/RasmusLindroth/tut/api" + "github.com/RasmusLindroth/tut/config" ) type apiFunc func(pg *mastodon.Pagination) ([]api.Item, error) @@ -21,36 +21,6 @@ type apiSearchPGFunc func(pg *mastodon.Pagination, search string) ([]api.Item, e type apiThreadFunc func(status *mastodon.Status) ([]api.Item, error) type apiHistoryFunc func(status *mastodon.Status) ([]api.Item, error) -type FeedType uint - -const ( - Favorites FeedType = iota - Favorited - Boosts - Followers - Following - FollowRequests - Blocking - Muting - History - InvalidFeed - Notification - Saved - Tag - Tags - Thread - TimelineFederated - TimelineHome - TimelineLocal - Conversations - User - UserList - Lists - List - ListUsersIn - ListUsersAdd -) - type LoadingLock struct { mux sync.Mutex last time.Time @@ -71,7 +41,8 @@ const ( type Feed struct { accountClient *api.AccountClient - feedType FeedType + config *config.Config + feedType config.FeedType sticky []api.Item items []api.Item itemsMux sync.RWMutex @@ -85,17 +56,36 @@ type Feed struct { streams []*api.Receiver name string close func() + showBoosts bool + showReplies bool } -func (f *Feed) Type() FeedType { +func (f *Feed) Type() config.FeedType { return f.feedType } -func (f *Feed) List() []api.Item { +func (f *Feed) filteredList() []api.Item { f.itemsMux.RLock() defer f.itemsMux.RUnlock() + filtered := []api.Item{} + for _, fd := range f.items { + switch x := fd.Raw().(type) { + case *mastodon.Status: + if x.Reblog != nil && !f.showBoosts { + continue + } + if x.InReplyToID != nil && !f.showReplies { + continue + } + } + filtered = append(filtered, fd) + } r := f.sticky - return append(r, f.items...) + return append(r, filtered...) +} + +func (f *Feed) List() []api.Item { + return f.filteredList() } func (f *Feed) Delete(id uint) { @@ -119,15 +109,18 @@ func (f *Feed) Clear() { } func (f *Feed) Item(index int) (api.Item, error) { - f.itemsMux.RLock() - defer f.itemsMux.RUnlock() - if f.StickyCount() > 0 && index < f.StickyCount() { - return f.sticky[index], nil - } - if index < 0 || index >= len(f.items)+f.StickyCount() { - return nil, errors.New("item out of range") - } - return f.items[index-f.StickyCount()], nil + /* + f.itemsMux.RLock() + defer f.itemsMux.RUnlock() + if f.StickyCount() > 0 && index < f.StickyCount() { + return f.sticky[index], nil + } + if index < 0 || index >= len(f.items)+f.StickyCount() { + return nil, errors.New("item out of range") + } + */ + filtered := f.filteredList() + return filtered[index], nil } func (f *Feed) Updated(nt DesktopNotificationType) { @@ -696,9 +689,10 @@ func (f *Feed) startStreamNotification(rec *api.Receiver, timeline string, err e }() } -func newFeed(ac *api.AccountClient, ft FeedType) *Feed { +func newFeed(ac *api.AccountClient, ft config.FeedType, cnf *config.Config, showBoosts bool, showReplies bool) *Feed { return &Feed{ accountClient: ac, + config: cnf, sticky: make([]api.Item, 0), items: make([]api.Item, 0), feedType: ft, @@ -708,11 +702,13 @@ func newFeed(ac *api.AccountClient, ft FeedType) *Feed { Update: make(chan DesktopNotificationType, 1), loadingNewer: &LoadingLock{}, loadingOlder: &LoadingLock{}, + showBoosts: showBoosts, + showReplies: showReplies, } } -func NewTimelineHome(ac *api.AccountClient) *Feed { - feed := newFeed(ac, TimelineHome) +func NewTimelineHome(ac *api.AccountClient, cnf *config.Config, showBoosts bool, showReplies bool) *Feed { + feed := newFeed(ac, config.TimelineHome, cnf, showBoosts, showReplies) feed.loadNewer = func() { feed.normalNewer(feed.accountClient.GetTimeline) } feed.loadOlder = func() { feed.normalOlder(feed.accountClient.GetTimeline) } feed.startStream(feed.accountClient.NewHomeStream()) @@ -725,8 +721,8 @@ func NewTimelineHome(ac *api.AccountClient) *Feed { return feed } -func NewTimelineFederated(ac *api.AccountClient) *Feed { - feed := newFeed(ac, TimelineFederated) +func NewTimelineFederated(ac *api.AccountClient, cnf *config.Config, showBoosts bool, showReplies bool) *Feed { + feed := newFeed(ac, config.TimelineFederated, cnf, showBoosts, showReplies) feed.loadNewer = func() { feed.normalNewer(feed.accountClient.GetTimelineFederated) } feed.loadOlder = func() { feed.normalOlder(feed.accountClient.GetTimelineFederated) } feed.startStream(feed.accountClient.NewFederatedStream()) @@ -739,8 +735,8 @@ func NewTimelineFederated(ac *api.AccountClient) *Feed { return feed } -func NewTimelineLocal(ac *api.AccountClient) *Feed { - feed := newFeed(ac, TimelineLocal) +func NewTimelineLocal(ac *api.AccountClient, cnf *config.Config, showBoosts bool, showReplies bool) *Feed { + feed := newFeed(ac, config.TimelineLocal, cnf, showBoosts, showReplies) feed.loadNewer = func() { feed.normalNewer(feed.accountClient.GetTimelineLocal) } feed.loadOlder = func() { feed.normalOlder(feed.accountClient.GetTimelineLocal) } feed.startStream(feed.accountClient.NewLocalStream()) @@ -752,8 +748,8 @@ func NewTimelineLocal(ac *api.AccountClient) *Feed { return feed } -func NewConversations(ac *api.AccountClient) *Feed { - feed := newFeed(ac, Conversations) +func NewConversations(ac *api.AccountClient, cnf *config.Config) *Feed { + feed := newFeed(ac, config.Conversations, cnf, true, true) feed.loadNewer = func() { feed.normalNewer(feed.accountClient.GetConversations) } feed.loadOlder = func() { feed.normalOlder(feed.accountClient.GetConversations) } feed.startStream(feed.accountClient.NewDirectStream()) @@ -766,8 +762,8 @@ func NewConversations(ac *api.AccountClient) *Feed { return feed } -func NewNotifications(ac *api.AccountClient) *Feed { - feed := newFeed(ac, Notification) +func NewNotifications(ac *api.AccountClient, cnf *config.Config, showBoosts bool, showReplies bool) *Feed { + feed := newFeed(ac, config.Notifications, cnf, showBoosts, showReplies) feed.loadNewer = func() { feed.normalNewer(feed.accountClient.GetNotifications) } feed.loadOlder = func() { feed.normalOlder(feed.accountClient.GetNotifications) } feed.startStreamNotification(feed.accountClient.NewHomeStream()) @@ -780,32 +776,32 @@ func NewNotifications(ac *api.AccountClient) *Feed { return feed } -func NewFavorites(ac *api.AccountClient) *Feed { - feed := newFeed(ac, Favorited) +func NewFavorites(ac *api.AccountClient, cnf *config.Config) *Feed { + feed := newFeed(ac, config.Favorited, cnf, true, true) feed.loadNewer = func() { feed.linkNewer(feed.accountClient.GetFavorites) } feed.loadOlder = func() { feed.linkOlder(feed.accountClient.GetFavorites) } return feed } -func NewBookmarks(ac *api.AccountClient) *Feed { - feed := newFeed(ac, Saved) +func NewBookmarks(ac *api.AccountClient, cnf *config.Config) *Feed { + feed := newFeed(ac, config.Saved, cnf, true, true) feed.loadNewer = func() { feed.linkNewer(feed.accountClient.GetBookmarks) } feed.loadOlder = func() { feed.linkOlder(feed.accountClient.GetBookmarks) } return feed } -func NewUserSearch(ac *api.AccountClient, search string) *Feed { - feed := newFeed(ac, UserList) +func NewUserSearch(ac *api.AccountClient, cnf *config.Config, search string) *Feed { + feed := newFeed(ac, config.UserList, cnf, true, true) feed.name = search feed.loadNewer = func() { feed.singleNewerSearch(feed.accountClient.GetUsers, search) } return feed } -func NewUserProfile(ac *api.AccountClient, user *api.User) *Feed { - feed := newFeed(ac, User) +func NewUserProfile(ac *api.AccountClient, cnf *config.Config, user *api.User) *Feed { + feed := newFeed(ac, config.User, cnf, true, true) feed.name = user.Data.Acct feed.sticky = append(feed.sticky, api.NewUserItem(user, true)) pinned, err := ac.GetUserPinned(user.Data.ID) @@ -818,8 +814,8 @@ func NewUserProfile(ac *api.AccountClient, user *api.User) *Feed { return feed } -func NewThread(ac *api.AccountClient, status *mastodon.Status) *Feed { - feed := newFeed(ac, Thread) +func NewThread(ac *api.AccountClient, cnf *config.Config, status *mastodon.Status) *Feed { + feed := newFeed(ac, config.Thread, cnf, true, true) once := true feed.loadNewer = func() { if once { @@ -831,8 +827,8 @@ func NewThread(ac *api.AccountClient, status *mastodon.Status) *Feed { return feed } -func NewHistory(ac *api.AccountClient, status *mastodon.Status) *Feed { - feed := newFeed(ac, History) +func NewHistory(ac *api.AccountClient, cnf *config.Config, status *mastodon.Status) *Feed { + feed := newFeed(ac, config.History, cnf, true, true) once := true feed.loadNewer = func() { if once { @@ -843,8 +839,8 @@ func NewHistory(ac *api.AccountClient, status *mastodon.Status) *Feed { return feed } -func NewTag(ac *api.AccountClient, search string) *Feed { - feed := newFeed(ac, Tag) +func NewTag(ac *api.AccountClient, cnf *config.Config, search string, showBoosts bool, showReplies bool) *Feed { + feed := newFeed(ac, config.Tag, cnf, showBoosts, showReplies) parts := strings.Split(search, " ") var tparts []string for _, p := range parts { @@ -869,8 +865,8 @@ func NewTag(ac *api.AccountClient, search string) *Feed { return feed } -func NewTags(ac *api.AccountClient) *Feed { - feed := newFeed(ac, Tags) +func NewTags(ac *api.AccountClient, cnf *config.Config) *Feed { + feed := newFeed(ac, config.Tags, cnf, true, true) once := true feed.loadNewer = func() { if once { @@ -883,8 +879,8 @@ func NewTags(ac *api.AccountClient) *Feed { return feed } -func NewListList(ac *api.AccountClient) *Feed { - feed := newFeed(ac, Lists) +func NewListList(ac *api.AccountClient, cnf *config.Config) *Feed { + feed := newFeed(ac, config.Lists, cnf, true, true) once := true feed.loadNewer = func() { if once { @@ -896,8 +892,8 @@ func NewListList(ac *api.AccountClient) *Feed { return feed } -func NewList(ac *api.AccountClient, list *mastodon.List) *Feed { - feed := newFeed(ac, List) +func NewList(ac *api.AccountClient, cnf *config.Config, list *mastodon.List, showBoosts bool, showReplies bool) *Feed { + feed := newFeed(ac, config.List, cnf, showBoosts, showReplies) feed.name = list.Title feed.loadNewer = func() { feed.normalNewerID(feed.accountClient.GetListStatuses, list.ID) } feed.loadOlder = func() { feed.normalOlderID(feed.accountClient.GetListStatuses, list.ID) } @@ -911,8 +907,8 @@ func NewList(ac *api.AccountClient, list *mastodon.List) *Feed { return feed } -func NewUsersInList(ac *api.AccountClient, list *mastodon.List) *Feed { - feed := newFeed(ac, ListUsersIn) +func NewUsersInList(ac *api.AccountClient, cnf *config.Config, list *mastodon.List) *Feed { + feed := newFeed(ac, config.ListUsersIn, cnf, true, true) feed.name = list.Title once := true feed.loadNewer = func() { @@ -926,8 +922,8 @@ func NewUsersInList(ac *api.AccountClient, list *mastodon.List) *Feed { return feed } -func NewUsersAddList(ac *api.AccountClient, list *mastodon.List) *Feed { - feed := newFeed(ac, ListUsersAdd) +func NewUsersAddList(ac *api.AccountClient, cnf *config.Config, list *mastodon.List) *Feed { + feed := newFeed(ac, config.ListUsersAdd, cnf, true, true) feed.name = list.Title once := true feed.loadNewer = func() { @@ -941,8 +937,8 @@ func NewUsersAddList(ac *api.AccountClient, list *mastodon.List) *Feed { return feed } -func NewFavoritesStatus(ac *api.AccountClient, id mastodon.ID) *Feed { - feed := newFeed(ac, Favorites) +func NewFavoritesStatus(ac *api.AccountClient, cnf *config.Config, id mastodon.ID) *Feed { + feed := newFeed(ac, config.Favorites, cnf, true, true) once := true feed.loadNewer = func() { if once { @@ -954,8 +950,8 @@ func NewFavoritesStatus(ac *api.AccountClient, id mastodon.ID) *Feed { return feed } -func NewBoosts(ac *api.AccountClient, id mastodon.ID) *Feed { - feed := newFeed(ac, Boosts) +func NewBoosts(ac *api.AccountClient, cnf *config.Config, id mastodon.ID) *Feed { + feed := newFeed(ac, config.Boosts, cnf, true, true) once := true feed.loadNewer = func() { if once { @@ -967,8 +963,8 @@ func NewBoosts(ac *api.AccountClient, id mastodon.ID) *Feed { return feed } -func NewFollowers(ac *api.AccountClient, id mastodon.ID) *Feed { - feed := newFeed(ac, Followers) +func NewFollowers(ac *api.AccountClient, cnf *config.Config, id mastodon.ID) *Feed { + feed := newFeed(ac, config.Followers, cnf, true, true) once := true feed.loadNewer = func() { if once { @@ -981,8 +977,8 @@ func NewFollowers(ac *api.AccountClient, id mastodon.ID) *Feed { return feed } -func NewFollowing(ac *api.AccountClient, id mastodon.ID) *Feed { - feed := newFeed(ac, Following) +func NewFollowing(ac *api.AccountClient, cnf *config.Config, id mastodon.ID) *Feed { + feed := newFeed(ac, config.Following, cnf, true, true) once := true feed.loadNewer = func() { if once { @@ -995,8 +991,8 @@ func NewFollowing(ac *api.AccountClient, id mastodon.ID) *Feed { return feed } -func NewBlocking(ac *api.AccountClient) *Feed { - feed := newFeed(ac, Blocking) +func NewBlocking(ac *api.AccountClient, cnf *config.Config) *Feed { + feed := newFeed(ac, config.Blocking, cnf, true, true) once := true feed.loadNewer = func() { if once { @@ -1009,8 +1005,8 @@ func NewBlocking(ac *api.AccountClient) *Feed { return feed } -func NewMuting(ac *api.AccountClient) *Feed { - feed := newFeed(ac, Muting) +func NewMuting(ac *api.AccountClient, cnf *config.Config) *Feed { + feed := newFeed(ac, config.Muting, cnf, true, true) once := true feed.loadNewer = func() { if once { @@ -1023,8 +1019,8 @@ func NewMuting(ac *api.AccountClient) *Feed { return feed } -func NewFollowRequests(ac *api.AccountClient) *Feed { - feed := newFeed(ac, FollowRequests) +func NewFollowRequests(ac *api.AccountClient, cnf *config.Config) *Feed { + feed := newFeed(ac, config.FollowRequests, cnf, true, true) once := true feed.loadNewer = func() { if once { diff --git a/go.mod b/go.mod index a14528a..1594b1d 100644 --- a/go.mod +++ b/go.mod @@ -11,10 +11,11 @@ require ( github.com/icza/gox v0.0.0-20221026131554-a08a8cdc726a github.com/microcosm-cc/bluemonday v1.0.21 github.com/pelletier/go-toml/v2 v2.0.6 - github.com/rivo/tview v0.0.0-20221128165837-db36428c92d9 + github.com/rivo/tview v0.0.0-20221212150847-19d943d59543 github.com/rivo/uniseg v0.4.3 github.com/spf13/pflag v1.0.5 - golang.org/x/net v0.2.0 + golang.org/x/exp v0.0.0-20221212164502-fae10dda9338 + golang.org/x/net v0.4.0 gopkg.in/ini.v1 v1.67.0 ) @@ -30,7 +31,7 @@ require ( github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af // indirect github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 // indirect - golang.org/x/sys v0.2.0 // indirect - golang.org/x/term v0.2.0 // indirect - golang.org/x/text v0.4.0 // indirect + golang.org/x/sys v0.3.0 // indirect + golang.org/x/term v0.3.0 // indirect + golang.org/x/text v0.5.0 // indirect ) diff --git a/go.sum b/go.sum index 42013ec..23930b3 100644 --- a/go.sum +++ b/go.sum @@ -38,10 +38,10 @@ github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvI github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rivo/tview v0.0.0-20221117065207-09f052e6ca98 h1:0nVxhPi+jdqG11c3n4zTcZQbjGy0yi60ym/6B+NITPU= -github.com/rivo/tview v0.0.0-20221117065207-09f052e6ca98/go.mod h1:YX2wUZOcJGOIycErz2s9KvDaP0jnWwRCirQMPLPpQ+Y= github.com/rivo/tview v0.0.0-20221128165837-db36428c92d9 h1:ccTgRxA37ypj3q8zB8G4k3xGPfBbIaMwrf3Yw6k50NY= github.com/rivo/tview v0.0.0-20221128165837-db36428c92d9/go.mod h1:YX2wUZOcJGOIycErz2s9KvDaP0jnWwRCirQMPLPpQ+Y= +github.com/rivo/tview v0.0.0-20221212150847-19d943d59543 h1:qu4/1SXI23subKkH50FN7t6r0tPg7i7jI48M5kZ2qEE= +github.com/rivo/tview v0.0.0-20221212150847-19d943d59543/go.mod h1:YX2wUZOcJGOIycErz2s9KvDaP0jnWwRCirQMPLPpQ+Y= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -58,20 +58,30 @@ github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af h1:6yITBqGTE2lEeTPG0 github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af/go.mod h1:4F09kP5F+am0jAwlQLddpoMDM+iewkxxt6nxUQ5nq5o= github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 h1:nrZ3ySNYwJbSpD6ce9duiP+QkD3JuLCcWkdaehUS/3Y= github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80/go.mod h1:iFyPdL66DjUD96XmzVL3ZntbzcflLnznH0fr99w5VqE= +golang.org/x/exp v0.0.0-20221212164502-fae10dda9338 h1:OvjRkcNHnf6/W5FZXSxODbxwD+X7fspczG7Jn/xQVD4= +golang.org/x/exp v0.0.0-20221212164502-fae10dda9338/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220318055525-2edf467146b5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= diff --git a/main.go b/main.go index b8e0c3d..ecfb35d 100644 --- a/main.go +++ b/main.go @@ -8,7 +8,7 @@ import ( "github.com/rivo/tview" ) -const version = "1.0.24" +const version = "1.0.25" func main() { util.SetTerminalTitle("tut") diff --git a/ui/cmdbar.go b/ui/cmdbar.go index a40c045..aaf5aa9 100644 --- a/ui/cmdbar.go +++ b/ui/cmdbar.go @@ -34,12 +34,12 @@ func (c *CmdBar) ShowError(s string) { } func (c *CmdBar) ShowMsg(s string) { - c.View.SetFieldTextColor(c.tutView.tut.Config.Style.StatusBarText) + c.View.SetFieldTextColor(c.tutView.tut.Config.Style.CommandText) c.View.SetText(s) } func (c *CmdBar) ClearInput() { - c.View.SetFieldTextColor(c.tutView.tut.Config.Style.StatusBarText) + c.View.SetFieldTextColor(c.tutView.tut.Config.Style.CommandText) c.View.SetText("") } diff --git a/ui/commands.go b/ui/commands.go index 8f1b39f..22a88dc 100644 --- a/ui/commands.go +++ b/ui/commands.go @@ -7,7 +7,6 @@ import ( "github.com/RasmusLindroth/go-mastodon" "github.com/RasmusLindroth/tut/api" "github.com/RasmusLindroth/tut/config" - "github.com/RasmusLindroth/tut/feed" "github.com/RasmusLindroth/tut/util" ) @@ -62,13 +61,13 @@ func (tv *TutView) FollowRequestsCommand() { func (tv *TutView) LocalCommand() { tv.Timeline.AddFeed( - NewLocalFeed(tv), + NewLocalFeed(tv, true, true), ) } func (tv *TutView) FederatedCommand() { tv.Timeline.AddFeed( - NewFederatedFeed(tv), + NewFederatedFeed(tv, true, true), ) } @@ -80,13 +79,13 @@ func (tv *TutView) DirectCommand() { func (tv *TutView) HomeCommand() { tv.Timeline.AddFeed( - NewHomeFeed(tv), + NewHomeFeed(tv, true, true), ) } func (tv *TutView) NotificationsCommand() { tv.Timeline.AddFeed( - NewNotificationFeed(tv), + NewNotificationFeed(tv, true, true), ) } @@ -98,7 +97,7 @@ func (tv *TutView) ListsCommand() { func (tv *TutView) TagCommand(tag string) { tv.Timeline.AddFeed( - NewTagFeed(tv, tag), + NewTagFeed(tv, tag, true, true), ) } @@ -260,7 +259,7 @@ func (tv *TutView) ClearNotificationsCommand() { } for _, tl := range tv.Timeline.Feeds { for _, f := range tl.Feeds { - if f.Data.Type() == feed.Notification { + if f.Data.Type() == config.Notifications { f.Data.Clear() } } diff --git a/ui/feed.go b/ui/feed.go index 05775e0..6cfa80b 100644 --- a/ui/feed.go +++ b/ui/feed.go @@ -126,7 +126,12 @@ func (f *Feed) update() { main, symbol := DrawListItem(f.tutView.tut.Config, item) f.List.AddItem(main, symbol, item.ID()) } - f.List.SetByID(curr) + if f.tutView.tut.Config.General.StickToTop { + f.List.SetCurrentItem(f.List.stickyCount) + f.DrawContent() + } else { + f.List.SetByID(curr) + } if lLen == 0 { f.DrawContent() } @@ -134,8 +139,8 @@ func (f *Feed) update() { } } -func NewHomeFeed(tv *TutView) *Feed { - f := feed.NewTimelineHome(tv.tut.Client) +func NewHomeFeed(tv *TutView, showBoosts bool, showReplies bool) *Feed { + f := feed.NewTimelineHome(tv.tut.Client, tv.tut.Config, showBoosts, showReplies) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -148,8 +153,8 @@ func NewHomeFeed(tv *TutView) *Feed { return fd } -func NewFederatedFeed(tv *TutView) *Feed { - f := feed.NewTimelineFederated(tv.tut.Client) +func NewFederatedFeed(tv *TutView, showBoosts bool, showReplies bool) *Feed { + f := feed.NewTimelineFederated(tv.tut.Client, tv.tut.Config, showBoosts, showReplies) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -162,8 +167,8 @@ func NewFederatedFeed(tv *TutView) *Feed { return fd } -func NewLocalFeed(tv *TutView) *Feed { - f := feed.NewTimelineLocal(tv.tut.Client) +func NewLocalFeed(tv *TutView, showBoosts bool, showReplies bool) *Feed { + f := feed.NewTimelineLocal(tv.tut.Client, tv.tut.Config, showBoosts, showReplies) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -176,8 +181,8 @@ func NewLocalFeed(tv *TutView) *Feed { return fd } -func NewNotificationFeed(tv *TutView) *Feed { - f := feed.NewNotifications(tv.tut.Client) +func NewNotificationFeed(tv *TutView, showBoosts bool, showReplies bool) *Feed { + f := feed.NewNotifications(tv.tut.Client, tv.tut.Config, showBoosts, showReplies) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -192,7 +197,7 @@ func NewNotificationFeed(tv *TutView) *Feed { func NewThreadFeed(tv *TutView, item api.Item) *Feed { status := util.StatusOrReblog(item.Raw().(*mastodon.Status)) - f := feed.NewThread(tv.tut.Client, status) + f := feed.NewThread(tv.tut.Client, tv.tut.Config, status) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -214,7 +219,7 @@ func NewThreadFeed(tv *TutView, item api.Item) *Feed { func NewHistoryFeed(tv *TutView, item api.Item) *Feed { status := util.StatusOrReblog(item.Raw().(*mastodon.Status)) - f := feed.NewHistory(tv.tut.Client, status) + f := feed.NewHistory(tv.tut.Client, tv.tut.Config, status) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -233,7 +238,7 @@ func NewHistoryFeed(tv *TutView, item api.Item) *Feed { } func NewConversationsFeed(tv *TutView) *Feed { - f := feed.NewConversations(tv.tut.Client) + f := feed.NewConversations(tv.tut.Client, tv.tut.Config) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -251,7 +256,7 @@ func NewUserFeed(tv *TutView, item api.Item) *Feed { panic("Can't open user. Wrong type.\n") } u := item.Raw().(*api.User) - f := feed.NewUserProfile(tv.tut.Client, u) + f := feed.NewUserProfile(tv.tut.Client, tv.tut.Config, u) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -265,7 +270,7 @@ func NewUserFeed(tv *TutView, item api.Item) *Feed { } func NewUserSearchFeed(tv *TutView, search string) *Feed { - f := feed.NewUserSearch(tv.tut.Client, search) + f := feed.NewUserSearch(tv.tut.Client, tv.tut.Config, search) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -282,8 +287,8 @@ func NewUserSearchFeed(tv *TutView, search string) *Feed { return fd } -func NewTagFeed(tv *TutView, search string) *Feed { - f := feed.NewTag(tv.tut.Client, search) +func NewTagFeed(tv *TutView, search string, showBoosts bool, showReplies bool) *Feed { + f := feed.NewTag(tv.tut.Client, tv.tut.Config, search, showBoosts, showReplies) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -297,7 +302,7 @@ func NewTagFeed(tv *TutView, search string) *Feed { } func NewTagsFeed(tv *TutView) *Feed { - f := feed.NewTags(tv.tut.Client) + f := feed.NewTags(tv.tut.Client, tv.tut.Config) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -311,7 +316,7 @@ func NewTagsFeed(tv *TutView) *Feed { } func NewListsFeed(tv *TutView) *Feed { - f := feed.NewListList(tv.tut.Client) + f := feed.NewListList(tv.tut.Client, tv.tut.Config) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -324,8 +329,8 @@ func NewListsFeed(tv *TutView) *Feed { return fd } -func NewListFeed(tv *TutView, l *mastodon.List) *Feed { - f := feed.NewList(tv.tut.Client, l) +func NewListFeed(tv *TutView, l *mastodon.List, showBoosts bool, showReplies bool) *Feed { + f := feed.NewList(tv.tut.Client, tv.tut.Config, l, showBoosts, showReplies) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -339,7 +344,7 @@ func NewListFeed(tv *TutView, l *mastodon.List) *Feed { } func NewUsersInListFeed(tv *TutView, l *mastodon.List) *Feed { - f := feed.NewUsersInList(tv.tut.Client, l) + f := feed.NewUsersInList(tv.tut.Client, tv.tut.Config, l) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -353,7 +358,7 @@ func NewUsersInListFeed(tv *TutView, l *mastodon.List) *Feed { } func NewUsersAddListFeed(tv *TutView, l *mastodon.List) *Feed { - f := feed.NewUsersAddList(tv.tut.Client, l) + f := feed.NewUsersAddList(tv.tut.Client, tv.tut.Config, l) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -367,7 +372,7 @@ func NewUsersAddListFeed(tv *TutView, l *mastodon.List) *Feed { } func NewFavoritedFeed(tv *TutView) *Feed { - f := feed.NewFavorites(tv.tut.Client) + f := feed.NewFavorites(tv.tut.Client, tv.tut.Config) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -381,7 +386,7 @@ func NewFavoritedFeed(tv *TutView) *Feed { } func NewBookmarksFeed(tv *TutView) *Feed { - f := feed.NewBookmarks(tv.tut.Client) + f := feed.NewBookmarks(tv.tut.Client, tv.tut.Config) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -395,7 +400,7 @@ func NewBookmarksFeed(tv *TutView) *Feed { } func NewFavoritesStatus(tv *TutView, id mastodon.ID) *Feed { - f := feed.NewFavoritesStatus(tv.tut.Client, id) + f := feed.NewFavoritesStatus(tv.tut.Client, tv.tut.Config, id) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -409,7 +414,7 @@ func NewFavoritesStatus(tv *TutView, id mastodon.ID) *Feed { } func NewBoosts(tv *TutView, id mastodon.ID) *Feed { - f := feed.NewBoosts(tv.tut.Client, id) + f := feed.NewBoosts(tv.tut.Client, tv.tut.Config, id) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -423,7 +428,7 @@ func NewBoosts(tv *TutView, id mastodon.ID) *Feed { } func NewFollowers(tv *TutView, id mastodon.ID) *Feed { - f := feed.NewFollowers(tv.tut.Client, id) + f := feed.NewFollowers(tv.tut.Client, tv.tut.Config, id) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -437,7 +442,7 @@ func NewFollowers(tv *TutView, id mastodon.ID) *Feed { } func NewFollowing(tv *TutView, id mastodon.ID) *Feed { - f := feed.NewFollowing(tv.tut.Client, id) + f := feed.NewFollowing(tv.tut.Client, tv.tut.Config, id) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -451,7 +456,7 @@ func NewFollowing(tv *TutView, id mastodon.ID) *Feed { } func NewBlocking(tv *TutView) *Feed { - f := feed.NewBlocking(tv.tut.Client) + f := feed.NewBlocking(tv.tut.Client, tv.tut.Config) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -465,7 +470,7 @@ func NewBlocking(tv *TutView) *Feed { } func NewMuting(tv *TutView) *Feed { - f := feed.NewMuting(tv.tut.Client) + f := feed.NewMuting(tv.tut.Client, tv.tut.Config) f.LoadNewer() fd := &Feed{ tutView: tv, @@ -479,7 +484,7 @@ func NewMuting(tv *TutView) *Feed { } func NewFollowRequests(tv *TutView) *Feed { - f := feed.NewFollowRequests(tv.tut.Client) + f := feed.NewFollowRequests(tv.tut.Client, tv.tut.Config) f.LoadNewer() fd := &Feed{ tutView: tv, diff --git a/ui/input.go b/ui/input.go index f231eb3..17f0746 100644 --- a/ui/input.go +++ b/ui/input.go @@ -10,7 +10,6 @@ import ( "github.com/RasmusLindroth/go-mastodon" "github.com/RasmusLindroth/tut/api" "github.com/RasmusLindroth/tut/config" - "github.com/RasmusLindroth/tut/feed" "github.com/RasmusLindroth/tut/util" "github.com/gdamore/tcell/v2" "github.com/rivo/tview" @@ -309,11 +308,11 @@ func (tv *TutView) InputItem(event *tcell.EventKey) *tcell.EventKey { return tv.InputStatusHistory(event, item, item.Raw().(*mastodon.StatusHistory), nil) case api.UserType, api.ProfileType: switch ft { - case feed.FollowRequests: + case config.FollowRequests: return tv.InputUser(event, item.Raw().(*api.User), InputUserFollowRequest) - case feed.ListUsersAdd: + case config.ListUsersAdd: return tv.InputUser(event, item.Raw().(*api.User), InputUserListAdd) - case feed.ListUsersIn: + case config.ListUsersIn: return tv.InputUser(event, item.Raw().(*api.User), InputUserListDelete) default: return tv.InputUser(event, item.Raw().(*api.User), InputUserNormal) @@ -732,7 +731,7 @@ func (tv *TutView) InputUser(event *tcell.EventKey, user *api.User, ut InputUser func (tv *TutView) InputList(event *tcell.EventKey, list *mastodon.List) *tcell.EventKey { if tv.tut.Config.Input.ListOpenFeed.Match(event.Key(), event.Rune()) || tv.tut.Config.Input.GlobalEnter.Match(event.Key(), event.Rune()) { - tv.Timeline.AddFeed(NewListFeed(tv, list)) + tv.Timeline.AddFeed(NewListFeed(tv, list, true, true)) return nil } if tv.tut.Config.Input.ListUserList.Match(event.Key(), event.Rune()) { @@ -749,7 +748,7 @@ func (tv *TutView) InputList(event *tcell.EventKey, list *mastodon.List) *tcell. func (tv *TutView) InputTag(event *tcell.EventKey, tag *mastodon.Tag) *tcell.EventKey { if tv.tut.Config.Input.TagOpenFeed.Match(event.Key(), event.Rune()) || tv.tut.Config.Input.GlobalEnter.Match(event.Key(), event.Rune()) { - tv.Timeline.AddFeed(NewTagFeed(tv, tag.Name)) + tv.Timeline.AddFeed(NewTagFeed(tv, tag.Name, true, true)) return nil } if tv.tut.Config.Input.TagFollow.Match(event.Key(), event.Rune()) { diff --git a/ui/item.go b/ui/item.go index b8083f2..8051d1a 100644 --- a/ui/item.go +++ b/ui/item.go @@ -8,7 +8,6 @@ import ( "github.com/RasmusLindroth/go-mastodon" "github.com/RasmusLindroth/tut/api" "github.com/RasmusLindroth/tut/config" - "github.com/RasmusLindroth/tut/feed" "github.com/icza/gox/timex" "github.com/rivo/tview" ) @@ -76,7 +75,7 @@ func DrawListItem(cfg *config.Config, item api.Item) (string, string) { } } -func DrawItem(tv *TutView, item api.Item, main *tview.TextView, controls *tview.Flex, ft feed.FeedType) { +func DrawItem(tv *TutView, item api.Item, main *tview.TextView, controls *tview.Flex, ft config.FeedType) { switch item.Type() { case api.StatusType: drawStatus(tv, item, item.Raw().(*mastodon.Status), main, controls, false, "") @@ -95,11 +94,11 @@ func DrawItem(tv *TutView, item api.Item, main *tview.TextView, controls *tview. drawStatus(tv, item, &status, main, controls, true, "") case api.UserType, api.ProfileType: switch ft { - case feed.FollowRequests: + case config.FollowRequests: drawUser(tv, item.Raw().(*api.User), main, controls, "", InputUserFollowRequest) - case feed.ListUsersAdd: + case config.ListUsersAdd: drawUser(tv, item.Raw().(*api.User), main, controls, "", InputUserListAdd) - case feed.ListUsersIn: + case config.ListUsersIn: drawUser(tv, item.Raw().(*api.User), main, controls, "", InputUserListDelete) default: drawUser(tv, item.Raw().(*api.User), main, controls, "", InputUserFollowRequest) @@ -113,7 +112,7 @@ func DrawItem(tv *TutView, item api.Item, main *tview.TextView, controls *tview. } } -func DrawItemControls(tv *TutView, item api.Item, controls *tview.Flex, ft feed.FeedType) { +func DrawItemControls(tv *TutView, item api.Item, controls *tview.Flex, ft config.FeedType) { switch item.Type() { case api.StatusType: drawStatus(tv, item, item.Raw().(*mastodon.Status), nil, controls, false, "") @@ -131,7 +130,7 @@ func DrawItemControls(tv *TutView, item api.Item, controls *tview.Flex, ft feed. } drawStatus(tv, item, &status, nil, controls, true, "") case api.UserType, api.ProfileType: - if ft == feed.FollowRequests { + if ft == config.FollowRequests { drawUser(tv, item.Raw().(*api.User), nil, controls, "", InputUserFollowRequest) } else { drawUser(tv, item.Raw().(*api.User), nil, controls, "", InputUserNormal) diff --git a/ui/linkview.go b/ui/linkview.go index 62c2b7b..bcf9cd2 100644 --- a/ui/linkview.go +++ b/ui/linkview.go @@ -122,7 +122,7 @@ func (lv *LinkView) Open() { tIndex := index - len(mentions) - len(urls) if tIndex < len(tags) { lv.tutView.Timeline.AddFeed( - NewTagFeed(lv.tutView, tags[tIndex].Name), + NewTagFeed(lv.tutView, tags[tIndex].Name, true, true), ) lv.tutView.FocusMainNoHistory() return diff --git a/ui/timeline.go b/ui/timeline.go index 4b6c094..a2fee0e 100644 --- a/ui/timeline.go +++ b/ui/timeline.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - "github.com/RasmusLindroth/tut/feed" + "github.com/RasmusLindroth/tut/config" ) type FeedHolder struct { @@ -31,24 +31,24 @@ func NewTimeline(tv *TutView, update chan bool) *Timeline { var nf *Feed for _, f := range tv.tut.Config.General.Timelines { switch f.FeedType { - case feed.TimelineHome: - nf = NewHomeFeed(tv) - case feed.Conversations: + case config.TimelineHome: + nf = NewHomeFeed(tv, f.ShowBoosts, f.ShowReplies) + case config.Conversations: nf = NewConversationsFeed(tv) - case feed.TimelineLocal: - nf = NewLocalFeed(tv) - case feed.TimelineFederated: - nf = NewFederatedFeed(tv) - case feed.Saved: + case config.TimelineLocal: + nf = NewLocalFeed(tv, f.ShowBoosts, f.ShowReplies) + case config.TimelineFederated: + nf = NewFederatedFeed(tv, f.ShowBoosts, f.ShowReplies) + case config.Saved: nf = NewBookmarksFeed(tv) - case feed.Favorited: + case config.Favorited: nf = NewFavoritedFeed(tv) - case feed.Notification: - nf = NewNotificationFeed(tv) - case feed.Lists: + case config.Notifications: + nf = NewNotificationFeed(tv, f.ShowBoosts, f.ShowReplies) + case config.Lists: nf = NewListsFeed(tv) - case feed.Tag: - nf = NewTagFeed(tv, f.Subaction) + case config.Tag: + nf = NewTagFeed(tv, f.Subaction, f.ShowBoosts, f.ShowReplies) default: fmt.Println("Invalid feed") tl.tutView.CleanExit(1) @@ -144,53 +144,53 @@ func (tl *Timeline) GetTitle() string { name := f.Data.Name() ct := "" switch current { - case feed.Favorited: + case config.Favorited: ct = "favorited" - case feed.Notification: + case config.Notifications: ct = "notifications" - case feed.Tag: + case config.Tag: parts := strings.Split(name, " ") for i, p := range parts { parts[i] = fmt.Sprintf("#%s", p) } ct = fmt.Sprintf("tag %s", strings.Join(parts, " ")) - case feed.Thread: + case config.Thread: ct = "thread feed" - case feed.History: + case config.History: ct = "history feed" - case feed.TimelineFederated: + case config.TimelineFederated: ct = "federated" - case feed.TimelineHome: + case config.TimelineHome: ct = "home" - case feed.TimelineLocal: + case config.TimelineLocal: ct = "local" - case feed.Saved: + case config.Saved: ct = "saved/bookmarked toots" - case feed.User: + case config.User: ct = fmt.Sprintf("user %s", name) - case feed.UserList: + case config.UserList: ct = fmt.Sprintf("user search %s", name) - case feed.Conversations: + case config.Conversations: ct = "direct" - case feed.Lists: + case config.Lists: ct = "lists" - case feed.List: + case config.List: ct = fmt.Sprintf("list named %s", name) - case feed.Boosts: + case config.Boosts: ct = "boosts" - case feed.Favorites: + case config.Favorites: ct = "favorites" - case feed.Followers: + case config.Followers: ct = "followers" - case feed.Following: + case config.Following: ct = "following" - case feed.FollowRequests: + case config.FollowRequests: ct = "follow requests" - case feed.Blocking: + case config.Blocking: ct = "blocking" - case feed.ListUsersAdd: + case config.ListUsersAdd: ct = fmt.Sprintf("Add users to %s", name) - case feed.ListUsersIn: + case config.ListUsersIn: ct = fmt.Sprintf("Delete users from %s", name) } return fmt.Sprintf("%s (%d/%d)", ct, index+1, total)