Browse Source

1.0.25 (#214)

* bump version

* stick to the top

* add support for filtering boosts and replies

* Add CommandText for cmdbar personalization (#210)

* Config typos (#213)

* update modules

Co-authored-by: ryspace <102413892+ryspace@users.noreply.github.com>
Co-authored-by: Kir Axanov <33198973+ioplker@users.noreply.github.com>
pull/224/head 1.0.25
Rasmus Lindroth 3 years ago committed by GitHub
parent
commit
d81279d0bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 25
      config.example.ini
  2. 127
      config/config.go
  3. 25
      config/default_config.go
  4. 1
      config/themes/default.ini
  5. 1
      config/themes/papercolor-light.ini
  6. 182
      feed/feed.go
  7. 11
      go.mod
  8. 14
      go.sum
  9. 2
      main.go
  10. 4
      ui/cmdbar.go
  11. 13
      ui/commands.go
  12. 67
      ui/feed.go
  13. 11
      ui/input.go
  14. 13
      ui/item.go
  15. 2
      ui/linkview.go
  16. 74
      ui/timeline.go

25
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{"

127
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,
},
)
}

25
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{"

1
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

1
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

182
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 {

11
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
)

14
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=

2
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")

4
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("")
}

13
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()
}
}

67
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,

11
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()) {

13
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)

2
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

74
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)

Loading…
Cancel
Save