Browse Source

1.0.29 (#232)

* bump version

* add mentions timeline

* add switch and close

* make name optional for timelines

* add move window
pull/234/head
Rasmus Lindroth 3 years ago committed by GitHub
parent
commit
1cd5d5a356
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      README.md
  2. 20
      api/item.go
  3. 25
      config.example.ini
  4. 59
      config/config.go
  5. 25
      config/default_config.go
  6. 13
      config/help.tmpl
  7. 43
      feed/feed.go
  8. 2
      main.go
  9. 37
      ui/cmdbar.go
  10. 121
      ui/commands.go
  11. 276
      ui/feed.go
  12. 14
      ui/input.go
  13. 2
      ui/item_status.go
  14. 141
      ui/timeline.go

7
README.md

@ -40,12 +40,13 @@ You can find Linux binaries under [releases](https://github.com/RasmusLindroth/t
## Currently supported commands
* `:q` `:quit` exit
* `:timeline` home, local, federated, direct, notifications, favorited, special-all, special-boosts, special-replies
* `:tl` h, l, f, d, n, fav, sa, sb, sr (shorter form)
* `:timeline` home, local, federated, direct, notifications, mentions favorited, special-all, special-boosts, special-replies
* `:tl` h, l, f, d, n, m, fav, sa, sb, sr (shorter form)
* `:blocking` lists users that you have blocked
* `:boosts` lists users that boosted the toot
* `:bookmarks` lists all your bookmarks
* `:clear-notifications` clear all notifications
* `:close-window` closes the current window
* `:compose` compose a new toot
* `:edit` edit one of your toots
* `:favorited` lists toots you've favorited
@ -58,6 +59,8 @@ You can find Linux binaries under [releases](https://github.com/RasmusLindroth/t
* `:lists` show a list of your lists
* `:list-placement` top, right, bottom, left
* `:list-split` row, column
* `:move-window` left, right, up, down, home, end
* `:mv` l, r, u, d, h, e
* `:muting` lists users that you have muted
* `:newer` force load newer toots in current timeline
* `:preferences` update your profile and some other settings

20
api/item.go

@ -149,8 +149,8 @@ func (s *StatusItem) Filtered(tl config.FeedType) (bool, string, string, bool) {
used := false
for _, w := range f.Where {
switch w {
case "home", "special":
if tl == config.TimelineHome || tl == config.List {
case "home":
if tl == config.TimelineHome || tl == config.List || tl == config.TimelineHomeSpecial {
used = true
}
case "thread":
@ -158,28 +158,20 @@ func (s *StatusItem) Filtered(tl config.FeedType) (bool, string, string, bool) {
used = true
}
case "notifications":
if tl == config.Notifications {
if tl == config.Notifications || tl == config.Mentions {
used = true
}
case "account":
if tl == config.User {
used = true
}
case "public":
where := []config.FeedType{
config.Favorites,
config.Favorited,
config.Boosts,
config.TimelineFederated,
config.TimelineLocal,
config.Tag,
config.Notifications,
config.TimelineHome,
config.TimelineHomeSpecial,
config.Conversations,
config.User,
config.List,
}
if !slices.Contains(where, tl) {
if slices.Contains(where, tl) {
used = true
}
}

25
config.example.ini

@ -14,7 +14,7 @@ mouse-support=false
# they should show and the key to activate them.
#
# Available timelines: home, direct, local, federated, special, bookmarks,
# saved, favorited, notifications, lists, tag
# saved, favorited, notifications, lists, mentions, tag
#
# The one named special are the home timeline with only boosts and/or replies.
#
@ -171,11 +171,13 @@ leader-timeout=1000
# of two parts first the action then the shortcut. And they're separated by a
# comma.
#
# Available commands: home, direct, local, federated, special-all,
# special-boosts, special-replies, clear-notifications, compose, edit, history,
# blocking, bookmarks, refetch, saved, favorited, boosts, favorites, following,
# followers, muting, newer, preferences, profile, notifications, lists,
# stick-to-top, tag, tags, window, list-placement, list-split, proportions
# Available commands: blocking, bookmarks, boosts, clear-notifications,
# close-window, compose, direct, edit, favorited, favorites, federated,
# followers, following, history, home, list-placement, list-split, lists, local,
# mentions, move-window-left, move-window-right, move-window-up,
# move-window-down, move-window-home, move-window-end, muting, newer,
# notifications, preferences, profile, proportions, refetch, saved, special-all,
# special-boosts, special-replies, stick-to-top, switch, tag, tags, window
#
# The ones named special-* are the home timeline with only boosts and/or
# replies. All contains both, -boosts only boosts and -replies only replies.
@ -194,6 +196,9 @@ leader-timeout=1000
# proportions takes the arguments [int] [int], where the first integer is the
# list and the other content, e.g. proportions 1 3. See list-proportion above
# for more information.
# switch let's you go to a timeline if it already exists, if it doesn't it will
# open the timeline in a new window. The syntax is almost the same as in
# timelines= and is displayed under the examples.
#
# Some examples:
# leader-action=local,lo
@ -207,6 +212,14 @@ leader-timeout=1000
# leader-action=list-split column,c
# leader-action=proportions 1 3,3
#
# Syntax for switch:
# leader-action=switch feed,shortcut,[name],[showBoosts],[showReplies]
# showBoosts can be either true or false and they are both optional. Here are
# some examples:
#
# leader-action=switch home,false,true,h
# leader-action=switch tag tut,tt
#
[media]

59
config/config.go

@ -76,6 +76,7 @@ const (
LeaderProfile
LeaderProportions
LeaderNotifications
LeaderMentions
LeaderLists
LeaderRefetch
LeaderTag
@ -83,8 +84,14 @@ const (
LeaderStickToTop
LeaderHistory
LeaderUser
LeaderWindow
LeaderLoadNewer
LeaderWindow
LeaderCloseWindow
LeaderSwitch
LeaderMoveWindowLeft
LeaderMoveWindowRight
LeaderMoveWindowHome
LeaderMoveWindowEnd
)
type FeedType uint
@ -109,6 +116,7 @@ const (
TimelineHome
TimelineHomeSpecial
TimelineLocal
Mentions
Conversations
User
UserList
@ -897,8 +905,8 @@ func parseGeneral(cfg *ini.File) General {
var las []LeaderAction
for _, l := range lactions {
parts := strings.Split(l, ",")
if len(parts) != 2 {
fmt.Printf("leader-action must consist of two parts separated by a comma. Your value is: %s\n", strings.Join(parts, ","))
if len(parts) < 2 {
fmt.Printf("leader-action must consist of atleast two parts separated by a comma. Your value is: %s\n", strings.Join(parts, ","))
os.Exit(1)
}
for i, p := range parts {
@ -959,6 +967,8 @@ func parseGeneral(cfg *ini.File) General {
la.Command = LeaderProfile
case "notifications":
la.Command = LeaderNotifications
case "mentions":
la.Command = LeaderMentions
case "lists":
la.Command = LeaderLists
case "stick-to-top":
@ -982,6 +992,27 @@ func parseGeneral(cfg *ini.File) General {
case "window":
la.Command = LeaderWindow
la.Subaction = subaction
case "close-window":
la.Command = LeaderCloseWindow
case "move-window-left", "move-window-up":
la.Command = LeaderMoveWindowLeft
case "move-window-right", "move-window-down":
la.Command = LeaderMoveWindowRight
case "move-window-home":
la.Command = LeaderMoveWindowHome
case "move-window-end":
la.Command = LeaderMoveWindowEnd
case "switch":
la.Command = LeaderSwitch
sa := ""
if len(parts) > 2 {
sa = strings.Join(parts[2:], ",")
}
if len(sa) > 0 {
la.Subaction = fmt.Sprintf("%s,%s", subaction, sa)
} else {
la.Subaction = subaction
}
case "newer":
la.Command = LeaderLoadNewer
default:
@ -1036,6 +1067,8 @@ func parseGeneral(cfg *ini.File) General {
tl.FeedType = Favorited
case "notifications":
tl.FeedType = Notifications
case "mentions":
tl.FeedType = Mentions
case "lists":
tl.FeedType = Lists
case "tag":
@ -1045,25 +1078,33 @@ func parseGeneral(cfg *ini.File) General {
fmt.Printf("timeline %s is invalid\n", parts[0])
os.Exit(1)
}
tfStr := []string{"true", "false"}
tl.Name = parts[1]
if slices.Contains(tfStr, tl.Name) || (strings.HasPrefix(parts[1], "\"") && strings.HasSuffix(parts[1], "\"")) ||
(strings.HasPrefix(parts[1], "'") && strings.HasSuffix(parts[1], "'")) {
tl.Name = ""
}
tfs := []bool{true, true}
tfStr := []string{"true", "false"}
stop := len(parts)
if len(parts) > 2 {
if slices.Contains(tfStr, parts[len(parts)-2]) &&
if len(parts) > 1 {
if len(parts) > 2 && slices.Contains(tfStr, parts[len(parts)-2]) &&
slices.Contains(tfStr, parts[len(parts)-1]) &&
len(parts)-2 > 1 {
len(parts)-2 > 0 {
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 {
len(parts)-1 > 0 {
tfs[0] = parts[len(parts)-1] == "true"
stop = len(parts) - 1
}
if stop > 2 {
vals := []string{""}
vals = append(vals, parts[2:stop]...)
start := 2
if tl.Name == "" {
start = 1
}
vals = append(vals, parts[start:stop]...)
tl.Key = inputStrOrErr(vals, false)
}
}

25
config/default_config.go

@ -16,7 +16,7 @@ mouse-support=false
# they should show and the key to activate them.
#
# Available timelines: home, direct, local, federated, special, bookmarks,
# saved, favorited, notifications, lists, tag
# saved, favorited, notifications, lists, mentions, tag
#
# The one named special are the home timeline with only boosts and/or replies.
#
@ -173,11 +173,13 @@ leader-timeout=1000
# of two parts first the action then the shortcut. And they're separated by a
# comma.
#
# Available commands: home, direct, local, federated, special-all,
# special-boosts, special-replies, clear-notifications, compose, edit, history,
# blocking, bookmarks, refetch, saved, favorited, boosts, favorites, following,
# followers, muting, newer, preferences, profile, notifications, lists,
# stick-to-top, tag, tags, window, list-placement, list-split, proportions
# Available commands: blocking, bookmarks, boosts, clear-notifications,
# close-window, compose, direct, edit, favorited, favorites, federated,
# followers, following, history, home, list-placement, list-split, lists, local,
# mentions, move-window-left, move-window-right, move-window-up,
# move-window-down, move-window-home, move-window-end, muting, newer,
# notifications, preferences, profile, proportions, refetch, saved, special-all,
# special-boosts, special-replies, stick-to-top, switch, tag, tags, window
#
# The ones named special-* are the home timeline with only boosts and/or
# replies. All contains both, -boosts only boosts and -replies only replies.
@ -196,6 +198,9 @@ leader-timeout=1000
# proportions takes the arguments [int] [int], where the first integer is the
# list and the other content, e.g. proportions 1 3. See list-proportion above
# for more information.
# switch let's you go to a timeline if it already exists, if it doesn't it will
# open the timeline in a new window. The syntax is almost the same as in
# timelines= and is displayed under the examples.
#
# Some examples:
# leader-action=local,lo
@ -209,6 +214,14 @@ leader-timeout=1000
# leader-action=list-split column,c
# leader-action=proportions 1 3,3
#
# Syntax for switch:
# leader-action=switch feed,shortcut,[name],[showBoosts],[showReplies]
# showBoosts can be either true or false and they are both optional. Here are
# some examples:
#
# leader-action=switch home,false,true,h
# leader-action=switch tag tut,tt
#
[media]

13
config/help.tmpl

@ -30,10 +30,10 @@ Here's a list of supported commands.
{{- Color .Style.TextSpecial2 }}{{ Flags "b" }} :quit{{ Flags "-" }}{{ Color .Style.Text }}
Exit the program
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:timeline{{ Flags "-" }}{{ Color .Style.Text }} home|local|federated|direct|notifications|favorited|special-all|special-boosts|special-replies
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:timeline{{ Flags "-" }}{{ Color .Style.Text }} home|local|federated|direct|notifications|mentions|favorited|special-all|special-boosts|special-replies
Open selected timeline
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:tl{{ Flags "-" }}{{ Color .Style.Text }} h|l|f|d|n|fav|sa|sb|sr
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:tl{{ Flags "-" }}{{ Color .Style.Text }} h|l|f|d|n|m|fav|sa|sb|sr
Shorter form of the former command *:timeline*
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:blocking{{ Flags "-" }}{{ Color .Style.Text }}
@ -48,6 +48,9 @@ Here's a list of supported commands.
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:clear-notifications{{ Flags "-" }}{{ Color .Style.Text }}
Clear all notifications
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:close-window{{ Flags "-" }}{{ Color .Style.Text }}
Closes the current window
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:compose{{ Flags "-" }}{{ Color .Style.Text }}
Compose a new toot
@ -85,6 +88,12 @@ Here's a list of supported commands.
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:list-split{{ Flags "-" }}{{ Color .Style.Text }} row|column
Split lists as rows or columns
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:move-window{{ Flags "-" }}{{ Color .Style.Text }} left|right|up|down|home|end
Moves window in selected direction
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:mv{{ Flags "-" }}{{ Color .Style.Text }} l|r|u|d|h|e
Shorter form of the former command *:move-window*
{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:muting{{ Flags "-" }}{{ Color .Style.Text }}
Lists users that you have muted

43
feed/feed.go

@ -2,6 +2,7 @@ package feed
import (
"context"
"errors"
"log"
"strings"
"sync"
@ -134,6 +135,9 @@ func (f *Feed) Item(index int) (api.Item, error) {
}
*/
filtered := f.filteredList()
if len(filtered) == 0 {
return nil, errors.New("item out of range")
}
return filtered[index], nil
}
@ -718,7 +722,7 @@ func (f *Feed) startStream(rec *api.Receiver, timeline string, err error) {
}()
}
func (f *Feed) startStreamNotification(rec *api.Receiver, timeline string, err error) {
func (f *Feed) startStreamNotification(rec *api.Receiver, timeline string, err error, mentions bool) {
if err != nil {
log.Fatalln("Couldn't open stream")
}
@ -729,35 +733,35 @@ func (f *Feed) startStreamNotification(rec *api.Receiver, timeline string, err e
case *mastodon.NotificationEvent:
switch t.Notification.Type {
case "follow":
if slices.Contains(f.config.General.NotificationsToHide, config.HideFollow) {
if slices.Contains(f.config.General.NotificationsToHide, config.HideFollow) || mentions {
continue
}
case "follow_request":
if slices.Contains(f.config.General.NotificationsToHide, config.HideFollowRequest) {
if slices.Contains(f.config.General.NotificationsToHide, config.HideFollowRequest) || mentions {
continue
}
case "favourite":
if slices.Contains(f.config.General.NotificationsToHide, config.HideFavorite) {
if slices.Contains(f.config.General.NotificationsToHide, config.HideFavorite) || mentions {
continue
}
case "reblog":
if slices.Contains(f.config.General.NotificationsToHide, config.HideBoost) {
if slices.Contains(f.config.General.NotificationsToHide, config.HideBoost) || mentions {
continue
}
case "mention":
if slices.Contains(f.config.General.NotificationsToHide, config.HideMention) {
if slices.Contains(f.config.General.NotificationsToHide, config.HideMention) && !mentions {
continue
}
case "update":
if slices.Contains(f.config.General.NotificationsToHide, config.HideEdited) {
if slices.Contains(f.config.General.NotificationsToHide, config.HideEdited) || mentions {
continue
}
case "status":
if slices.Contains(f.config.General.NotificationsToHide, config.HideStatus) {
if slices.Contains(f.config.General.NotificationsToHide, config.HideStatus) || mentions {
continue
}
case "poll":
if slices.Contains(f.config.General.NotificationsToHide, config.HidePoll) {
if slices.Contains(f.config.General.NotificationsToHide, config.HidePoll) || mentions {
continue
}
}
@ -901,13 +905,32 @@ func NewNotifications(ac *api.AccountClient, cnf *config.Config, showBoosts bool
feed.loadOlder = func() {
feed.normalOlderNotification(feed.accountClient.GetNotifications, cnf.General.NotificationsToHide)
}
feed.startStreamNotification(feed.accountClient.NewHomeStream())
rec, tl, err := feed.accountClient.NewHomeStream()
feed.startStreamNotification(rec, tl, err, false)
feed.close = func() {
for _, s := range feed.streams {
feed.accountClient.RemoveHomeReceiver(s)
}
}
return feed
}
func NewNotificationsMentions(ac *api.AccountClient, cnf *config.Config) *Feed {
feed := newFeed(ac, config.Notifications, cnf, true, true)
hide := []config.NotificationToHide{config.HideStatus, config.HideBoost, config.HideFollow, config.HideFollowRequest, config.HideFavorite, config.HidePoll, config.HideEdited}
feed.loadNewer = func() {
feed.normalNewerNotification(feed.accountClient.GetNotifications, hide)
}
feed.loadOlder = func() {
feed.normalOlderNotification(feed.accountClient.GetNotifications, hide)
}
rec, tl, err := feed.accountClient.NewHomeStream()
feed.startStreamNotification(rec, tl, err, true)
feed.close = func() {
for _, s := range feed.streams {
feed.accountClient.RemoveHomeReceiver(s)
}
}
return feed
}

2
main.go

@ -8,7 +8,7 @@ import (
"github.com/rivo/tview"
)
const version = "1.0.28"
const version = "1.0.29"
func main() {
util.SetTerminalTitle("tut")

37
ui/cmdbar.go

@ -102,6 +102,27 @@ func (c *CmdBar) DoneFunc(key tcell.Key) {
case ":clear-notifications":
c.tutView.ClearNotificationsCommand()
c.Back()
case ":close-window":
c.tutView.CloseWindowCommand()
c.Back()
case ":move-window", ":mv":
if len(parts) < 2 {
break
}
switch parts[1] {
case "left", "up", "l", "u":
c.tutView.MoveWindowLeft()
c.Back()
case "right", "down", "r", "d":
c.tutView.MoveWindowRight()
c.Back()
case "home", "h":
c.tutView.MoveWindowHome()
c.Back()
case "end", "e":
c.tutView.MoveWindowEnd()
c.Back()
}
case ":list-placement":
if len(parts) < 2 {
break
@ -180,6 +201,9 @@ func (c *CmdBar) DoneFunc(key tcell.Key) {
case "notifications", "n":
c.tutView.NotificationsCommand()
c.Back()
case "mentions", "m":
c.tutView.MentionsCommand()
c.Back()
case "favorited", "fav":
c.tutView.FavoritedCommand()
c.Back()
@ -254,16 +278,16 @@ func (c *CmdBar) DoneFunc(key tcell.Key) {
func (c *CmdBar) Autocomplete(curr string) []string {
var entries []string
words := strings.Split(":blocking,:boosts,:bookmarks,:clear-notifications,:compose,:favorites,:favorited,:follow-tag,:followers,:following,:help,:h,:history,:lists,:list-placement,:list-split,:muting,:newer,:preferences,:profile,:proportions,:refetch,:requests,:saved,:stick-to-top,:tag,:timeline,:tl,:unfollow-tag,:user,:window,:quit,:q", ",")
words := strings.Split(":blocking,:boosts,:bookmarks,:clear-notifications,:compose,:favorites,:favorited,:follow-tag,:followers,:following,:help,:h,:history,:move-window,:lists,:list-placement,:list-split,:muting,:newer,:preferences,:profile,:proportions,:refetch,:requests,:saved,:stick-to-top,:tag,:timeline,:tl,:unfollow-tag,:user,:window,:quit,:q", ",")
if curr == "" {
return entries
}
if len(curr) > 2 && curr[:3] == ":tl" {
words = strings.Split(":tl home,:tl notifications,:tl local,:tl federated,:tl direct,:tl favorited,:tl special-all,:tl special-boosts,:tl-special-replies", ",")
words = strings.Split(":tl home,:tl notifications,:tl local,:tl federated,:tl direct,:tl mentions,:tl favorited,:tl special-all,:tl special-boosts,:tl-special-replies", ",")
}
if len(curr) > 8 && curr[:9] == ":timeline" {
words = strings.Split(":timeline home,:timeline notifications,:timeline local,:timeline federated,:timeline direct,:timeline favorited,:timeline special-all,:timeline special-boosts,:timeline special-replies", ",")
words = strings.Split(":timeline home,:timeline notifications,:timeline local,:timeline federated,:timeline direct,:timeline mentions,:timeline favorited,:timeline special-all,:timeline special-boosts,:timeline special-replies", ",")
}
if len(curr) > 14 && curr[:15] == ":list-placement" {
words = strings.Split(":list-placement top,:list-placement right,:list-placement bottom,:list-placement left", ",")
@ -272,6 +296,13 @@ func (c *CmdBar) Autocomplete(curr string) []string {
words = strings.Split(":list-split row,:list-split column", ",")
}
if len(curr) > 11 && curr[:12] == ":move-window" {
words = strings.Split(":move-window left,:move-window right,:move-window up,:move-window down,:move-window home,:move-window end", ",")
}
if len(curr) > 2 && curr[:3] == ":mv" {
words = strings.Split(":mv left,:mv right,:mv up,:mv down,:mv home,:mv end", ",")
}
for _, word := range words {
if strings.HasPrefix(strings.ToLower(word), strings.ToLower(curr)) {
entries = append(entries, word)

121
ui/commands.go

@ -2,12 +2,15 @@ package ui
import (
"fmt"
"os"
"strconv"
"strings"
"github.com/RasmusLindroth/go-mastodon"
"github.com/RasmusLindroth/tut/api"
"github.com/RasmusLindroth/tut/config"
"github.com/RasmusLindroth/tut/util"
"golang.org/x/exp/slices"
)
func (tv *TutView) ComposeCommand() {
@ -95,6 +98,12 @@ func (tv *TutView) NotificationsCommand() {
)
}
func (tv *TutView) MentionsCommand() {
tv.Timeline.AddFeed(
NewNotificatioMentionsFeed(tv, true, true),
)
}
func (tv *TutView) ListsCommand() {
tv.Timeline.AddFeed(
NewListsFeed(tv),
@ -140,6 +149,118 @@ func (tv *TutView) WindowCommand(index string) {
tv.FocusFeed(i)
}
func (tv *TutView) MoveWindowLeft() {
tv.Timeline.MoveCurrentWindowLeft()
}
func (tv *TutView) MoveWindowRight() {
tv.Timeline.MoveCurrentWindowRight()
}
func (tv *TutView) MoveWindowHome() {
tv.Timeline.MoveCurrentWindowHome()
}
func (tv *TutView) MoveWindowEnd() {
tv.Timeline.MoveCurrentWindowEnd()
}
func (tv *TutView) SwitchCommand(s string) {
ft := config.InvalidFeed
parts := strings.Split(s, ",")
for i, p := range parts {
parts[i] = strings.TrimSpace(p)
}
cmd := parts[0]
var subaction string
if strings.Contains(parts[0], " ") {
p := strings.Split(cmd, " ")
cmd = p[0]
subaction = strings.Join(p[1:], " ")
}
showBoosts := true
showReplies := true
name := ""
if len(parts) > 1 {
tfStr := []string{"true", "false"}
name = parts[1]
if slices.Contains(tfStr, name) {
name = ""
}
if len(parts) > 2 && slices.Contains(tfStr, parts[len(parts)-2]) &&
slices.Contains(tfStr, parts[len(parts)-1]) {
showBoosts = parts[len(parts)-2] == "true"
showReplies = parts[len(parts)-1] == "true"
} else if len(parts) > 1 && slices.Contains(tfStr, parts[len(parts)-1]) {
showBoosts = parts[len(parts)-1] == "true"
} else {
fmt.Printf("switch is invalid . Check this for errors: switch %s\n", s)
os.Exit(1)
}
}
var data string
switch cmd {
case "home":
ft = config.TimelineHome
case "direct":
ft = config.Conversations
case "local":
ft = config.TimelineLocal
case "federated":
ft = config.TimelineFederated
case "special":
ft = config.TimelineHomeSpecial
case "special-all":
ft = config.TimelineHomeSpecial
showBoosts = true
showReplies = true
case "special-boosts":
ft = config.TimelineHomeSpecial
showBoosts = true
showReplies = false
case "special-replies":
ft = config.TimelineHomeSpecial
showBoosts = false
showReplies = true
case "bookmarks", "saved":
ft = config.Saved
case "favorited":
ft = config.Favorited
case "notifications":
ft = config.Notifications
case "lists":
ft = config.Lists
case "tag":
ft = config.Tag
data = subaction
case "blocking":
ft = config.Blocking
case "muting":
ft = config.Muting
case "tags":
ft = config.Tags
case "mentions":
ft = config.Mentions
}
found := tv.Timeline.FindAndGoTo(ft, data, showBoosts, showReplies)
if found {
return
}
nf := CreateFeed(tv, ft, data, showBoosts, showReplies)
tv.Timeline.Feeds = append(tv.Timeline.Feeds, &FeedHolder{
Feeds: []*Feed{nf},
Name: name,
})
tv.FocusFeed(len(tv.Timeline.Feeds) - 1)
tv.Shared.Top.SetText(tv.Timeline.GetTitle())
tv.Timeline.update <- true
}
func (tv *TutView) CloseWindowCommand() {
tv.Timeline.CloseCurrentWindow()
}
func (tv *TutView) BoostsCommand() {
item, itemErr := tv.GetCurrentItem()
if itemErr != nil {

276
ui/feed.go

@ -45,10 +45,12 @@ func outFocus(l *tview.List, style config.Style) {
}
type Feed struct {
tutView *TutView
Data *feed.Feed
List *FeedList
Content *FeedContent
tutView *TutView
Data *feed.Feed
List *FeedList
Content *FeedContent
ShowBoosts bool
ShowReplies bool
}
func (f *Feed) ListInFocus() {
@ -143,10 +145,12 @@ 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,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: showBoosts,
ShowReplies: showReplies,
}
go fd.update()
@ -157,10 +161,12 @@ func NewHomeSpecialFeed(tv *TutView, showBoosts bool, showReplies bool) *Feed {
f := feed.NewTimelineHomeSpecial(tv.tut.Client, tv.tut.Config, showBoosts, showReplies)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: showBoosts,
ShowReplies: showReplies,
}
go fd.update()
@ -171,10 +177,12 @@ 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,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: showBoosts,
ShowReplies: showReplies,
}
go fd.update()
@ -185,10 +193,12 @@ 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,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: showBoosts,
ShowReplies: showReplies,
}
go fd.update()
@ -199,10 +209,28 @@ 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,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: showBoosts,
ShowReplies: showReplies,
}
go fd.update()
return fd
}
func NewNotificatioMentionsFeed(tv *TutView, showBoosts bool, showReplies bool) *Feed {
f := feed.NewNotificationsMentions(tv.tut.Client, tv.tut.Config)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: showBoosts,
ShowReplies: showReplies,
}
go fd.update()
@ -214,10 +242,12 @@ func NewThreadFeed(tv *TutView, item api.Item) *Feed {
f := feed.NewThread(tv.tut.Client, tv.tut.Config, status)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: true,
ShowReplies: true,
}
for i, s := range f.List() {
main, symbol := DrawListItem(tv.tut.Config, s)
@ -236,10 +266,12 @@ func NewHistoryFeed(tv *TutView, item api.Item) *Feed {
f := feed.NewHistory(tv.tut.Client, tv.tut.Config, status)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: true,
ShowReplies: true,
}
for _, s := range f.List() {
main, symbol := DrawListItem(tv.tut.Config, s)
@ -255,10 +287,12 @@ func NewConversationsFeed(tv *TutView) *Feed {
f := feed.NewConversations(tv.tut.Client, tv.tut.Config)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: true,
ShowReplies: true,
}
go fd.update()
@ -273,10 +307,12 @@ func NewUserFeed(tv *TutView, item api.Item) *Feed {
f := feed.NewUserProfile(tv.tut.Client, tv.tut.Config, u)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: true,
ShowReplies: true,
}
go fd.update()
@ -287,10 +323,12 @@ func NewUserSearchFeed(tv *TutView, search string) *Feed {
f := feed.NewUserSearch(tv.tut.Client, tv.tut.Config, search)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: true,
ShowReplies: true,
}
for _, s := range f.List() {
main, symbol := DrawListItem(tv.tut.Config, s)
@ -305,10 +343,12 @@ func NewTagFeed(tv *TutView, search string, showBoosts bool, showReplies bool) *
f := feed.NewTag(tv.tut.Client, tv.tut.Config, search, showBoosts, showReplies)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: showBoosts,
ShowReplies: showReplies,
}
go fd.update()
@ -319,10 +359,12 @@ func NewTagsFeed(tv *TutView) *Feed {
f := feed.NewTags(tv.tut.Client, tv.tut.Config)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: true,
ShowReplies: true,
}
go fd.update()
@ -333,10 +375,12 @@ func NewListsFeed(tv *TutView) *Feed {
f := feed.NewListList(tv.tut.Client, tv.tut.Config)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: true,
ShowReplies: true,
}
go fd.update()
@ -347,10 +391,12 @@ func NewListFeed(tv *TutView, l *mastodon.List, showBoosts bool, showReplies boo
f := feed.NewList(tv.tut.Client, tv.tut.Config, l, showBoosts, showReplies)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: showBoosts,
ShowReplies: showReplies,
}
go fd.update()
@ -361,10 +407,12 @@ func NewUsersInListFeed(tv *TutView, l *mastodon.List) *Feed {
f := feed.NewUsersInList(tv.tut.Client, tv.tut.Config, l)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: true,
ShowReplies: true,
}
go fd.update()
@ -375,10 +423,12 @@ func NewUsersAddListFeed(tv *TutView, l *mastodon.List) *Feed {
f := feed.NewUsersAddList(tv.tut.Client, tv.tut.Config, l)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: true,
ShowReplies: true,
}
go fd.update()
@ -389,10 +439,12 @@ func NewFavoritedFeed(tv *TutView) *Feed {
f := feed.NewFavorites(tv.tut.Client, tv.tut.Config)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: true,
ShowReplies: true,
}
go fd.update()
@ -403,10 +455,12 @@ func NewBookmarksFeed(tv *TutView) *Feed {
f := feed.NewBookmarks(tv.tut.Client, tv.tut.Config)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: true,
ShowReplies: true,
}
go fd.update()
@ -417,10 +471,12 @@ func NewFavoritesStatus(tv *TutView, id mastodon.ID) *Feed {
f := feed.NewFavoritesStatus(tv.tut.Client, tv.tut.Config, id)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: true,
ShowReplies: true,
}
go fd.update()
@ -431,10 +487,12 @@ func NewBoosts(tv *TutView, id mastodon.ID) *Feed {
f := feed.NewBoosts(tv.tut.Client, tv.tut.Config, id)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: true,
ShowReplies: true,
}
go fd.update()
@ -445,10 +503,12 @@ func NewFollowers(tv *TutView, id mastodon.ID) *Feed {
f := feed.NewFollowers(tv.tut.Client, tv.tut.Config, id)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: true,
ShowReplies: true,
}
go fd.update()
@ -459,10 +519,12 @@ func NewFollowing(tv *TutView, id mastodon.ID) *Feed {
f := feed.NewFollowing(tv.tut.Client, tv.tut.Config, id)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: true,
ShowReplies: true,
}
go fd.update()
@ -473,10 +535,12 @@ func NewBlocking(tv *TutView) *Feed {
f := feed.NewBlocking(tv.tut.Client, tv.tut.Config)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: true,
ShowReplies: true,
}
go fd.update()
@ -487,10 +551,12 @@ func NewMuting(tv *TutView) *Feed {
f := feed.NewMuting(tv.tut.Client, tv.tut.Config)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: true,
ShowReplies: true,
}
go fd.update()
@ -501,10 +567,12 @@ func NewFollowRequests(tv *TutView) *Feed {
f := feed.NewFollowRequests(tv.tut.Client, tv.tut.Config)
f.LoadNewer()
fd := &Feed{
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
tutView: tv,
Data: f,
List: NewFeedList(tv.tut, f.StickyCount()),
Content: NewFeedContent(tv.tut),
ShowBoosts: true,
ShowReplies: true,
}
go fd.update()

14
ui/input.go

@ -150,6 +150,8 @@ func (tv *TutView) InputLeaderKey(event *tcell.EventKey) *tcell.EventKey {
tv.ProfileCommand()
case config.LeaderNotifications:
tv.NotificationsCommand()
case config.LeaderMentions:
tv.MentionsCommand()
case config.LeaderLoadNewer:
tv.LoadNewerCommand()
case config.LeaderLists:
@ -164,6 +166,18 @@ func (tv *TutView) InputLeaderKey(event *tcell.EventKey) *tcell.EventKey {
tv.TagsCommand()
case config.LeaderWindow:
tv.WindowCommand(subaction)
case config.LeaderCloseWindow:
tv.CloseWindowCommand()
case config.LeaderMoveWindowLeft:
tv.MoveWindowLeft()
case config.LeaderMoveWindowRight:
tv.MoveWindowRight()
case config.LeaderMoveWindowHome:
tv.MoveWindowHome()
case config.LeaderMoveWindowEnd:
tv.MoveWindowEnd()
case config.LeaderSwitch:
tv.SwitchCommand(subaction)
case config.LeaderListPlacement:
switch subaction {
case "top":

2
ui/item_status.go

@ -23,6 +23,7 @@ type Toot struct {
Account string
Spoiler bool
CWText string
SpoilerText string
ShowSpoiler bool
CWlabel string
ContentText string
@ -163,6 +164,7 @@ func drawStatus(tv *TutView, item api.Item, status *mastodon.Status, main *tview
}
toot.CWText = strippedSpoiler
toot.SpoilerText = toot.CWText
media := []Media{}
for _, att := range status.MediaAttachments {

141
ui/timeline.go

@ -21,6 +21,38 @@ type Timeline struct {
scrollSleep *scrollSleep
}
func CreateFeed(tv *TutView, ft config.FeedType, data string, showBoosts, showReplies bool) *Feed {
var nf *Feed
switch ft {
case config.TimelineHome:
nf = NewHomeFeed(tv, showBoosts, showReplies)
case config.TimelineHomeSpecial:
nf = NewHomeSpecialFeed(tv, showBoosts, showReplies)
case config.Conversations:
nf = NewConversationsFeed(tv)
case config.TimelineLocal:
nf = NewLocalFeed(tv, showBoosts, showReplies)
case config.TimelineFederated:
nf = NewFederatedFeed(tv, showBoosts, showReplies)
case config.Saved:
nf = NewBookmarksFeed(tv)
case config.Favorited:
nf = NewFavoritedFeed(tv)
case config.Notifications:
nf = NewNotificationFeed(tv, showBoosts, showReplies)
case config.Mentions:
nf = NewNotificatioMentionsFeed(tv, showBoosts, showReplies)
case config.Lists:
nf = NewListsFeed(tv)
case config.Tag:
nf = NewTagFeed(tv, data, showBoosts, showReplies)
default:
fmt.Println("Invalid feed")
tv.CleanExit(1)
}
return nf
}
func NewTimeline(tv *TutView, update chan bool) *Timeline {
tl := &Timeline{
tutView: tv,
@ -28,33 +60,8 @@ func NewTimeline(tv *TutView, update chan bool) *Timeline {
update: update,
}
tl.scrollSleep = NewScrollSleep(tl.NextItemFeed, tl.PrevItemFeed)
var nf *Feed
for _, f := range tv.tut.Config.General.Timelines {
switch f.FeedType {
case config.TimelineHome:
nf = NewHomeFeed(tv, f.ShowBoosts, f.ShowReplies)
case config.TimelineHomeSpecial:
nf = NewHomeSpecialFeed(tv, f.ShowBoosts, f.ShowReplies)
case config.Conversations:
nf = NewConversationsFeed(tv)
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 config.Favorited:
nf = NewFavoritedFeed(tv)
case config.Notifications:
nf = NewNotificationFeed(tv, f.ShowBoosts, f.ShowReplies)
case config.Lists:
nf = NewListsFeed(tv)
case config.Tag:
nf = NewTagFeed(tv, f.Subaction, f.ShowBoosts, f.ShowReplies)
default:
fmt.Println("Invalid feed")
tl.tutView.CleanExit(1)
}
nf := CreateFeed(tv, f.FeedType, f.Subaction, f.ShowBoosts, f.ShowReplies)
tl.Feeds = append(tl.Feeds, &FeedHolder{
Feeds: []*Feed{nf},
Name: f.Name,
@ -99,6 +106,68 @@ func (tl *Timeline) RemoveCurrent(quit bool) bool {
return false
}
func (tl *Timeline) MoveCurrentWindowLeft() {
length := len(tl.Feeds)
if length < 2 {
return
}
ni := tl.FeedFocusIndex - 1
if ni < 0 {
return
}
tl.Feeds[tl.FeedFocusIndex], tl.Feeds[ni] = tl.Feeds[ni], tl.Feeds[tl.FeedFocusIndex]
tl.tutView.FocusFeed(ni)
}
func (tl *Timeline) MoveCurrentWindowRight() {
length := len(tl.Feeds)
if length < 2 {
return
}
ni := tl.FeedFocusIndex + 1
if ni > length-1 {
return
}
tl.Feeds[tl.FeedFocusIndex], tl.Feeds[ni] = tl.Feeds[ni], tl.Feeds[tl.FeedFocusIndex]
tl.tutView.FocusFeed(ni)
}
func (tl *Timeline) MoveCurrentWindowHome() {
length := len(tl.Feeds)
if length < 2 {
return
}
ni := 0
tl.Feeds[tl.FeedFocusIndex], tl.Feeds[ni] = tl.Feeds[ni], tl.Feeds[tl.FeedFocusIndex]
tl.tutView.FocusFeed(ni)
}
func (tl *Timeline) MoveCurrentWindowEnd() {
length := len(tl.Feeds)
if length < 2 {
return
}
ni := len(tl.Feeds) - 1
tl.Feeds[tl.FeedFocusIndex], tl.Feeds[ni] = tl.Feeds[ni], tl.Feeds[tl.FeedFocusIndex]
tl.tutView.FocusFeed(ni)
}
func (tl *Timeline) CloseCurrentWindow() {
if len(tl.Feeds) == 0 {
return
}
feeds := tl.Feeds[tl.FeedFocusIndex]
for _, f := range feeds.Feeds {
f.Data.Close()
}
tl.Feeds = append(tl.Feeds[:tl.FeedFocusIndex], tl.Feeds[tl.FeedFocusIndex+1:]...)
ni := tl.FeedFocusIndex - 1
if ni < 0 {
ni = 0
}
tl.tutView.FocusFeed(ni)
}
func (tl *Timeline) NextFeed() {
f := tl.Feeds[tl.FeedFocusIndex]
l := len(f.Feeds)
@ -122,6 +191,24 @@ func (tl *Timeline) PrevFeed() {
tl.update <- true
}
func (tl *Timeline) FindAndGoTo(ft config.FeedType, data string, showBoosts, showReplies bool) bool {
for i, fh := range tl.Feeds {
for j, f := range fh.Feeds {
if f.Data.Type() == ft && f.ShowBoosts == showBoosts && f.ShowReplies == showReplies {
if ft == config.Tag && f.Data.Name() != data {
continue
}
tl.tutView.FocusFeed(i)
fh.FeedIndex = j
tl.tutView.Shared.Top.SetText(tl.GetTitle())
tl.update <- true
return true
}
}
}
return false
}
func (tl *Timeline) DrawContent() {
fh := tl.Feeds[tl.FeedFocusIndex]
f := fh.Feeds[fh.FeedIndex]
@ -150,6 +237,8 @@ func (tl *Timeline) GetTitle() string {
ct = "favorited"
case config.Notifications:
ct = "notifications"
case config.Mentions:
ct = "mentions"
case config.Tag:
parts := strings.Split(name, " ")
for i, p := range parts {

Loading…
Cancel
Save