diff --git a/README.md b/README.md index cb23631..4e34144 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,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 -* `:muting` lists users that you have muted +* `:muting` lists users that you have muted +* `:newer` force load newer toots in current timeline * `:preferences` update your profile and some other settings * `:profile` go to your profile * `:proportions` [int] [int], where the first integer is the list and the other content, e.g. `:proportions 1 3` diff --git a/config.example.ini b/config.example.ini index caa1fcb..316dbe9 100644 --- a/config.example.ini +++ b/config.example.ini @@ -141,8 +141,8 @@ leader-timeout=1000 # # Available commands: home, direct, local, federated, compose, blocking, # bookmarks, saved, favorited, boosts, favorites, following, followers, muting, -# preferences, profile, notifications, lists, tag, window, list-placement, -# list-split, proportions +# newer, preferences, profile, notifications, lists, tag, window, +# list-placement, list-split, proportions # # The shortcuts are up to you, but keep them quite short and make sure they # don't collide. If you have one shortcut that is "f" and an other one that is @@ -326,14 +326,17 @@ posts=false # default=guess xrdb-prefix=guess -# You can use some themes that comes bundled with tut check out the themes +# You can use some themes that comes bundled with tut. Check out the themes # available on the URL below. If a theme is named "nord.ini" you just write # theme=nord # # https://github.com/RasmusLindroth/tut/tree/master/config/themes # -# If you want to use your own theme set theme to none then you can create your -# own theme below +# You can also create a theme file in your config directory e.g. +# ~/.config/tut/themes/foo.ini and then set theme=foo. +# +# If you want to use your own theme but don't want to create a new file, set +# theme=none and then you can create your own theme below. # default=default theme=default diff --git a/config/config.go b/config/config.go index be46639..62dd8e1 100644 --- a/config/config.go +++ b/config/config.go @@ -4,6 +4,7 @@ import ( "embed" "errors" "fmt" + "io" "io/ioutil" "log" "os" @@ -75,6 +76,7 @@ const ( LeaderTag LeaderUser LeaderWindow + LeaderLoadNewer ) type Timeline struct { @@ -431,21 +433,31 @@ func parseStyle(cfg *ini.File) Style { style := Style{} theme := cfg.Section("style").Key("theme").String() if theme != "none" && theme != "" { - themes, err := getThemes() + bundled, local, err := getThemes() if err != nil { log.Fatalf("Couldn't load themes. Error: %s\n", err) } found := false - for _, t := range themes { + isLocal := false + for _, t := range local { if filepath.Base(t) == fmt.Sprintf("%s.ini", theme) { found = true + isLocal = true break } } + if !found { + for _, t := range bundled { + if filepath.Base(t) == fmt.Sprintf("%s.ini", theme) { + found = true + break + } + } + } if !found { log.Fatalf("Couldn't find theme %s\n", theme) } - tcfg, err := getTheme(theme) + tcfg, err := getTheme(theme, isLocal) if err != nil { log.Fatalf("Couldn't load theme. Error: %s\n", err) } @@ -696,6 +708,8 @@ func parseGeneral(cfg *ini.File) General { case "window": la.Command = LeaderWindow la.Subaction = subaction + case "newer": + la.Command = LeaderLoadNewer default: fmt.Printf("leader-action %s is invalid\n", parts[0]) os.Exit(1) @@ -1183,7 +1197,7 @@ func parseConfig(filepath string) (Config, error) { func createConfigDir() error { cd, err := os.UserConfigDir() if err != nil { - log.Fatalf("couldn't find $HOME. Err %v", err) + log.Fatalf("couldn't find config dir. Err %v", err) } path := cd + "/tut" return os.MkdirAll(path, os.ModePerm) @@ -1192,7 +1206,7 @@ func createConfigDir() error { func checkConfig(filename string) (path string, exists bool, err error) { cd, err := os.UserConfigDir() if err != nil { - log.Fatalf("couldn't find $HOME. Err %v", err) + log.Fatalf("couldn't find config dir. Err %v", err) } dir := cd + "/tut/" path = dir + filename @@ -1218,24 +1232,58 @@ func CreateDefaultConfig(filepath string) error { return nil } -func getThemes() ([]string, error) { +func getThemes() (bundled []string, local []string, err error) { entries, err := themesFS.ReadDir("themes") - files := []string{} if err != nil { - return []string{}, err + return bundled, local, err } for _, entry := range entries { if entry.IsDir() { continue } fp := filepath.Join("themes/", entry.Name()) - files = append(files, fp) + bundled = append(bundled, fp) + } + _, exists, err := checkConfig("themes") + if err != nil { + return bundled, local, err + } + if !exists { + return bundled, local, err + } + cd, err := os.UserConfigDir() + if err != nil { + log.Fatalf("couldn't find config dir. Err %v", err) } - return files, nil + dir := cd + "/tut/themes" + entries, err = os.ReadDir(dir) + if err != nil { + return bundled, local, err + } + for _, entry := range entries { + if entry.IsDir() { + continue + } + fp := filepath.Join(dir, entry.Name()) + local = append(local, fp) + } + return bundled, local, nil } -func getTheme(fname string) (*ini.File, error) { - f, err := themesFS.Open(fmt.Sprintf("themes/%s.ini", strings.TrimSpace(fname))) +func getTheme(fname string, isLocal bool) (*ini.File, error) { + var f io.Reader + var err error + if isLocal { + var cd string + cd, err = os.UserConfigDir() + if err != nil { + log.Fatalf("couldn't find config dir. Err %v", err) + } + dir := cd + "/tut/themes" + f, err = os.Open(fmt.Sprintf("%s/%s.ini", dir, strings.TrimSpace(fname))) + } else { + f, err = themesFS.Open(fmt.Sprintf("themes/%s.ini", strings.TrimSpace(fname))) + } if err != nil { return nil, err } diff --git a/config/default_config.go b/config/default_config.go index 644209d..b3fdb51 100644 --- a/config/default_config.go +++ b/config/default_config.go @@ -143,8 +143,8 @@ leader-timeout=1000 # # Available commands: home, direct, local, federated, compose, blocking, # bookmarks, saved, favorited, boosts, favorites, following, followers, muting, -# preferences, profile, notifications, lists, tag, window, list-placement, -# list-split, proportions +# newer, preferences, profile, notifications, lists, tag, window, +# list-placement, list-split, proportions # # The shortcuts are up to you, but keep them quite short and make sure they # don't collide. If you have one shortcut that is "f" and an other one that is @@ -328,14 +328,17 @@ posts=false # default=guess xrdb-prefix=guess -# You can use some themes that comes bundled with tut check out the themes +# You can use some themes that comes bundled with tut. Check out the themes # available on the URL below. If a theme is named "nord.ini" you just write # theme=nord # # https://github.com/RasmusLindroth/tut/tree/master/config/themes # -# If you want to use your own theme set theme to none then you can create your -# own theme below +# You can also create a theme file in your config directory e.g. +# ~/.config/tut/themes/foo.ini and then set theme=foo. +# +# If you want to use your own theme but don't want to create a new file, set +# theme=none and then you can create your own theme below. # default=default theme=default diff --git a/feed/feed.go b/feed/feed.go index d2a7669..6f5c513 100644 --- a/feed/feed.go +++ b/feed/feed.go @@ -543,6 +543,7 @@ func (f *Feed) startStream(rec *api.Receiver, timeline string, err error) { f.itemsMux.Lock() f.items = append([]api.Item{s}, f.items...) f.Updated(DesktopNotificationPost) + f.apiData.MinID = t.Status.ID f.itemsMux.Unlock() } } diff --git a/go.mod b/go.mod index 6995410..e24b68a 100644 --- a/go.mod +++ b/go.mod @@ -9,11 +9,11 @@ require ( github.com/gen2brain/beeep v0.0.0-20220518085355-d7852edf42fc github.com/gobwas/glob v0.2.3 github.com/icza/gox v0.0.0-20220321141217-e2d488ab2fbc - github.com/microcosm-cc/bluemonday v1.0.18 - github.com/pelletier/go-toml/v2 v2.0.1 - github.com/rivo/tview v0.0.0-20220307222120-9994674d60a8 + github.com/microcosm-cc/bluemonday v1.0.19 + github.com/pelletier/go-toml/v2 v2.0.2 + github.com/rivo/tview v0.0.0-20220709181631-73bf2902b59a github.com/rivo/uniseg v0.2.0 - golang.org/x/net v0.0.0-20220531201128-c960675eff93 + golang.org/x/net v0.0.0-20220708220712-1185a9018129 gopkg.in/ini.v1 v1.66.6 ) @@ -29,7 +29,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.0.0-20220520151302-bc2c85ada10a // indirect + golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 // indirect golang.org/x/text v0.3.7 // indirect ) diff --git a/go.sum b/go.sum index 3e6acc1..689f791 100644 --- a/go.sum +++ b/go.sum @@ -31,19 +31,27 @@ github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4 github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/microcosm-cc/bluemonday v1.0.18 h1:6HcxvXDAi3ARt3slx6nTesbvorIc3QeTzBNRvWktHBo= github.com/microcosm-cc/bluemonday v1.0.18/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM= +github.com/microcosm-cc/bluemonday v1.0.19 h1:OI7hoF5FY4pFz2VA//RN8TfM0YJ2dJcl4P4APrCWy6c= +github.com/microcosm-cc/bluemonday v1.0.19/go.mod h1:QNzV2UbLK2/53oIIwTOyLUSABMkjZ4tqiyC1g/DyqxE= github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d h1:VhgPp6v9qf9Agr/56bj7Y/xa04UccTW04VP0Qed4vnQ= github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U= github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw= +github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI= 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-20220307222120-9994674d60a8 h1:xe+mmCnDN82KhC010l3NfYlA8ZbOuzbXAzSYBa6wbMc= github.com/rivo/tview v0.0.0-20220307222120-9994674d60a8/go.mod h1:WIfMkQNY+oq/mWwtsjOYHIZBuwthioY2srOmljJkTnk= +github.com/rivo/tview v0.0.0-20220709181631-73bf2902b59a h1:ZjJ1XcvsZkNVO+Rq/vQTOXtN3cmuAgpCp8m4fKG5CkY= +github.com/rivo/tview v0.0.0-20220709181631-73bf2902b59a/go.mod h1:WIfMkQNY+oq/mWwtsjOYHIZBuwthioY2srOmljJkTnk= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af h1:6yITBqGTE2lEeTPG04SN9W+iWHCRyHqlVYILiSXziwk= 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= @@ -51,6 +59,8 @@ github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80/go.mod h1:iFy golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220531201128-c960675eff93 h1:MYimHLfoXEpOhqd/zgoA/uoXzHB86AEky4LAx5ij9xA= golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220708220712-1185a9018129 h1:vucSRfWwTsoXro7P+3Cjlr6flUMtzCwzlvkxEQtHHB0= +golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -59,6 +69,8 @@ golang.org/x/sys v0.0.0-20220318055525-2edf467146b5/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -75,3 +87,4 @@ gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 74f09b9..28fb792 100644 --- a/main.go +++ b/main.go @@ -8,7 +8,7 @@ import ( "github.com/rivo/tview" ) -const version = "1.0.11" +const version = "1.0.12" func main() { util.MakeDirs() diff --git a/ui/cmdbar.go b/ui/cmdbar.go index f7553f5..9cb752e 100644 --- a/ui/cmdbar.go +++ b/ui/cmdbar.go @@ -88,6 +88,9 @@ func (c *CmdBar) DoneFunc(key tcell.Key) { case ":followers": c.tutView.FollowersCommand() c.Back() + case ":newer": + c.tutView.LoadNewerCommand() + c.Back() case ":list-placement": if len(parts) < 2 { break @@ -202,7 +205,7 @@ func (c *CmdBar) DoneFunc(key tcell.Key) { func (c *CmdBar) Autocomplete(curr string) []string { var entries []string - words := strings.Split(":blocking,:boosts,:bookmarks,:compose,:favorites,:favorited,:followers,:following,:help,:h,:lists,:list-placement,:list-split,:muting,:preferences,:profile,:proportions,:requests,:saved,:tag,:timeline,:tl,:user,:window,:quit,:q", ",") + words := strings.Split(":blocking,:boosts,:bookmarks,:compose,:favorites,:favorited,:followers,:following,:help,:h,:lists,:list-placement,:list-split,:muting,:newer,:preferences,:profile,:proportions,:requests,:saved,:tag,:timeline,:tl,:user,:window,:quit,:q", ",") if curr == "" { return entries } diff --git a/ui/commands.go b/ui/commands.go index f4619f9..84bb285 100644 --- a/ui/commands.go +++ b/ui/commands.go @@ -194,3 +194,8 @@ func (tv *TutView) ProportionsCommand(lp string, cp string) { tv.tut.Config.General.ContentProportion = cpi tv.MainView.ForceUpdate() } + +func (tv *TutView) LoadNewerCommand() { + f := tv.GetCurrentFeed() + f.LoadNewer(true) +} diff --git a/ui/feed.go b/ui/feed.go index 5260251..689c5af 100644 --- a/ui/feed.go +++ b/ui/feed.go @@ -63,8 +63,8 @@ func (f *Feed) LoadOlder() { f.Data.LoadOlder() } -func (f *Feed) LoadNewer() { - if f.Data.HasStream() { +func (f *Feed) LoadNewer(force bool) { + if f.Data.HasStream() && !force { return } f.Data.LoadNewer() diff --git a/ui/input.go b/ui/input.go index aff1b19..f223eb6 100644 --- a/ui/input.go +++ b/ui/input.go @@ -136,6 +136,8 @@ func (tv *TutView) InputLeaderKey(event *tcell.EventKey) *tcell.EventKey { tv.ProfileCommand() case config.LeaderNotifications: tv.NotificationsCommand() + case config.LeaderLoadNewer: + tv.LoadNewerCommand() case config.LeaderLists: tv.ListsCommand() case config.LeaderTag: diff --git a/ui/timeline.go b/ui/timeline.go index 4ce4360..05c713e 100644 --- a/ui/timeline.go +++ b/ui/timeline.go @@ -216,7 +216,7 @@ func (tl *Timeline) PrevItemFeed() { f := fh.Feeds[fh.FeedIndex] loadMore := f.List.Prev() if loadMore { - f.LoadNewer() + f.LoadNewer(false) } tl.DrawContent() } @@ -225,7 +225,7 @@ func (tl *Timeline) HomeItemFeed() { fh := tl.Feeds[tl.FeedFocusIndex] f := fh.Feeds[fh.FeedIndex] f.List.SetCurrentItem(0) - f.LoadNewer() + f.LoadNewer(false) tl.DrawContent() }