Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package tut for openSUSE:Factory checked in 
at 2022-11-24 12:24:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/tut (Old)
 and      /work/SRC/openSUSE:Factory/.tut.new.1597 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "tut"

Thu Nov 24 12:24:24 2022 rev:2 rq:1037754 version:1.0.20

Changes:
--------
--- /work/SRC/openSUSE:Factory/tut/tut.changes  2022-11-22 16:10:47.142213476 
+0100
+++ /work/SRC/openSUSE:Factory/.tut.new.1597/tut.changes        2022-11-24 
12:24:26.693761053 +0100
@@ -1,0 +2,25 @@
+Wed Nov 23 18:59:51 UTC 2022 - [email protected]
+
+- Update to version 1.0.20:
+  * 1.0.20 (#183)
+    You can now follow and unfollow tags with :follow-tag tut and
+    :unfollow-tag tut.
+    You can now add and remove users from lists. Run :lists and
+    then you can use the keys that tut displays. This feature only
+    works okay as it doesn't give you any response if the user is
+    added to the list or not. But it works.
+    An error from the terminal programs like lynx shouldn't crash
+    tut.
+    When you are reading a thread tut won't make unnecessary API
+    requests
+  * add history to help
+  * 1.0.19 (#179)
+  * 1.0.18 (#175)
+  * Updating go install command. (#167)
+  * 1.0.17 (#164)
+  * 1.0.16 (#161)
+  * 1.0.15 (#160)
+  * 1.0.14 (#159)
+  * 1.0.13 (#157)
+
+-------------------------------------------------------------------

Old:
----
  tut-1.0.19.tar.gz

New:
----
  tut-1.0.20.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ tut.spec ++++++
--- /var/tmp/diff_new_pack.dnr6H6/_old  2022-11-24 12:24:27.585766721 +0100
+++ /var/tmp/diff_new_pack.dnr6H6/_new  2022-11-24 12:24:27.589766747 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           tut
-Version:        1.0.19
+Version:        1.0.20
 Release:        0
 Summary:        A TUI for Mastodon with vim inspired keys
 License:        MIT
@@ -25,7 +25,6 @@
 URL:            https://tut.anv.nu
 Source0:        %{name}-%{version}.tar.gz
 Source1:        vendor.tar.gz
-BuildRequires:  gcc-c++
 BuildRequires:  golang-packaging
 # some modules require go 1.18+
 BuildRequires:  golang(API) >= 1.18

++++++ _service ++++++
--- /var/tmp/diff_new_pack.dnr6H6/_old  2022-11-24 12:24:27.637767051 +0100
+++ /var/tmp/diff_new_pack.dnr6H6/_new  2022-11-24 12:24:27.653767154 +0100
@@ -2,7 +2,7 @@
   <service mode="disabled" name="obs_scm">
     <param name="url">https://github.com/RasmusLindroth/tut.git</param>
     <param name="scm">git</param>
-    <param name="revision">refs/tags/1.0.19</param>
+    <param name="revision">refs/tags/1.0.20</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="changesgenerate">enable</param>
   </service>

++++++ tut-1.0.19.tar.gz -> tut-1.0.20.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/README.md new/tut-1.0.20/README.md
--- old/tut-1.0.19/README.md    2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/README.md    2022-11-23 19:07:42.000000000 +0100
@@ -45,6 +45,9 @@
 * `:compose` compose a new toot
 * `:favorited` lists toots you've favorited
 * `:favorites` lists users that favorited the toot
+* `:follow-tag` followed by the hashtag to follow e.g. `:follow-tag tut`
+* `:followers` list of people the account are following. It only works on 
profiles.
+* `:following` list of people following the account. It only works on profiles.
 * `:h` `:help` view help 
 * `:history` show edits of a toot 
 * `:lists` show a list of your lists
@@ -58,6 +61,7 @@
 * `:requests` see following requests
 * `:saved` alias for bookmarks
 * `:tag` followed by the hashtag e.g. `:tag linux`
+* `:unfollow-tag` followed by the hashtag to unfollow e.g. `:unfollow-tag tut`
 * `:user` followed by a username e.g. `:user rasmus` to narrow a search 
include 
 * `:window` switch window by index (zero indexed) e.g. `:window 0` for the 
first window.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/api/feed.go new/tut-1.0.20/api/feed.go
--- old/tut-1.0.19/api/feed.go  2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/api/feed.go  2022-11-23 19:07:42.000000000 +0100
@@ -21,7 +21,7 @@
        return items, nil
 }
 
-func (ac *AccountClient) getUserSimilar(fn func() ([]*mastodon.Account, 
error)) ([]Item, error) {
+func (ac *AccountClient) getUserSimilar(fn func() ([]*mastodon.Account, 
error), data interface{}) ([]Item, error) {
        var items []Item
        users, err := fn()
        if err != nil {
@@ -39,8 +39,9 @@
                for _, r := range rel {
                        if u.ID == r.ID {
                                items = append(items, NewUserItem(&User{
-                                       Data:     u,
-                                       Relation: r,
+                                       Data:           u,
+                                       Relation:       r,
+                                       AdditionalData: data,
                                }, false))
                                break
                        }
@@ -185,49 +186,49 @@
        fn := func() ([]*mastodon.Account, error) {
                return ac.Client.GetRebloggedBy(context.Background(), id, pg)
        }
-       return ac.getUserSimilar(fn)
+       return ac.getUserSimilar(fn, nil)
 }
 
 func (ac *AccountClient) GetFavoritesStatus(pg *mastodon.Pagination, id 
mastodon.ID) ([]Item, error) {
        fn := func() ([]*mastodon.Account, error) {
                return ac.Client.GetFavouritedBy(context.Background(), id, pg)
        }
-       return ac.getUserSimilar(fn)
+       return ac.getUserSimilar(fn, nil)
 }
 
 func (ac *AccountClient) GetFollowers(pg *mastodon.Pagination, id mastodon.ID) 
([]Item, error) {
        fn := func() ([]*mastodon.Account, error) {
                return ac.Client.GetAccountFollowers(context.Background(), id, 
pg)
        }
-       return ac.getUserSimilar(fn)
+       return ac.getUserSimilar(fn, nil)
 }
 
 func (ac *AccountClient) GetFollowing(pg *mastodon.Pagination, id mastodon.ID) 
([]Item, error) {
        fn := func() ([]*mastodon.Account, error) {
                return ac.Client.GetAccountFollowing(context.Background(), id, 
pg)
        }
-       return ac.getUserSimilar(fn)
+       return ac.getUserSimilar(fn, nil)
 }
 
 func (ac *AccountClient) GetBlocking(pg *mastodon.Pagination) ([]Item, error) {
        fn := func() ([]*mastodon.Account, error) {
                return ac.Client.GetBlocks(context.Background(), pg)
        }
-       return ac.getUserSimilar(fn)
+       return ac.getUserSimilar(fn, nil)
 }
 
 func (ac *AccountClient) GetMuting(pg *mastodon.Pagination) ([]Item, error) {
        fn := func() ([]*mastodon.Account, error) {
                return ac.Client.GetMutes(context.Background(), pg)
        }
-       return ac.getUserSimilar(fn)
+       return ac.getUserSimilar(fn, nil)
 }
 
 func (ac *AccountClient) GetFollowRequests(pg *mastodon.Pagination) ([]Item, 
error) {
        fn := func() ([]*mastodon.Account, error) {
                return ac.Client.GetFollowRequests(context.Background(), pg)
        }
-       return ac.getUserSimilar(fn)
+       return ac.getUserSimilar(fn, nil)
 }
 
 func (ac *AccountClient) GetUser(pg *mastodon.Pagination, id mastodon.ID) 
([]Item, error) {
@@ -281,6 +282,20 @@
        return items, nil
 }
 
+func (ac *AccountClient) GetFollowingForList(pg *mastodon.Pagination, id 
mastodon.ID, data interface{}) ([]Item, error) {
+       fn := func() ([]*mastodon.Account, error) {
+               return ac.Client.GetAccountFollowing(context.Background(), id, 
pg)
+       }
+       return ac.getUserSimilar(fn, data)
+}
+
+func (ac *AccountClient) GetListUsers(pg *mastodon.Pagination, id mastodon.ID, 
data interface{}) ([]Item, error) {
+       fn := func() ([]*mastodon.Account, error) {
+               return ac.Client.GetListAccounts(context.Background(), id)
+       }
+       return ac.getUserSimilar(fn, data)
+}
+
 func (ac *AccountClient) GetTag(pg *mastodon.Pagination, search string) 
([]Item, error) {
        fn := func() ([]*mastodon.Status, error) {
                return ac.Client.GetTimelineHashtag(context.Background(), 
search, false, pg)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/api/tags.go new/tut-1.0.20/api/tags.go
--- old/tut-1.0.19/api/tags.go  1970-01-01 01:00:00.000000000 +0100
+++ new/tut-1.0.20/api/tags.go  2022-11-23 19:07:42.000000000 +0100
@@ -0,0 +1,35 @@
+package api
+
+import (
+       "context"
+       "errors"
+)
+
+func (ac *AccountClient) FollowTag(tag string) error {
+       t, err := ac.Client.TagFollow(context.Background(), tag)
+       if err != nil {
+               return err
+       }
+       if t.Following == nil {
+               return errors.New("following is set to nil")
+       }
+       if t.Following == false {
+               return errors.New("following is still set to false")
+       }
+       return nil
+}
+
+func (ac *AccountClient) UnfollowTag(tag string) error {
+       t, err := ac.Client.TagUnfollow(context.Background(), tag)
+       if err != nil {
+               return err
+       }
+
+       if t.Following == nil {
+               return errors.New("following is set to nil")
+       }
+       if t.Following == true {
+               return errors.New("following is still set to true")
+       }
+       return nil
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/api/types.go new/tut-1.0.20/api/types.go
--- old/tut-1.0.19/api/types.go 2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/api/types.go 2022-11-23 19:07:42.000000000 +0100
@@ -15,6 +15,7 @@
 }
 
 type User struct {
-       Data     *mastodon.Account
-       Relation *mastodon.Relationship
+       Data           *mastodon.Account
+       Relation       *mastodon.Relationship
+       AdditionalData interface{}
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/api/user.go new/tut-1.0.20/api/user.go
--- old/tut-1.0.19/api/user.go  2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/api/user.go  2022-11-23 19:07:42.000000000 +0100
@@ -87,3 +87,11 @@
        }
        return err
 }
+
+func (ac *AccountClient) AddUserToList(u *mastodon.Account, l *mastodon.List) 
error {
+       return ac.Client.AddToList(context.Background(), l.ID, u.ID)
+}
+
+func (ac *AccountClient) DeleteUserFromList(u *mastodon.Account, l 
*mastodon.List) error {
+       return ac.Client.RemoveFromList(context.Background(), l.ID, u.ID)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/config/config.go 
new/tut-1.0.20/config/config.go
--- old/tut-1.0.19/config/config.go     2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/config/config.go     2022-11-23 19:07:42.000000000 +0100
@@ -380,7 +380,10 @@
        UserViewFocus           Key
        UserYank                Key
 
-       ListOpenFeed Key
+       ListOpenFeed   Key
+       ListUserList   Key
+       ListUserAdd    Key
+       ListUserDelete Key
 
        LinkOpen Key
        LinkYank Key
@@ -1265,7 +1268,10 @@
                UserViewFocus:           inputStrOrErr([]string{"\"[V]iew\"", 
"'v'", "'V'"}, false),
                UserYank:                inputStrOrErr([]string{"\"[Y]ank\"", 
"'y'", "'Y'"}, false),
 
-               ListOpenFeed: inputStrOrErr([]string{"\"[O]pen\"", "'o'", 
"'O'"}, false),
+               ListOpenFeed:   inputStrOrErr([]string{"\"[O]pen\"", "'o'", 
"'O'"}, false),
+               ListUserList:   inputStrOrErr([]string{"\"[U]sers\"", "'u'", 
"'U'"}, false),
+               ListUserAdd:    inputStrOrErr([]string{"\"[A]dd\"", "'a'", 
"'A'"}, false),
+               ListUserDelete: inputStrOrErr([]string{"\"[D]elete\"", "'d'", 
"'D'"}, false),
 
                LinkOpen: inputStrOrErr([]string{"\"[O]pen\"", "'o'", "'O'"}, 
false),
                LinkYank: inputStrOrErr([]string{"\"[Y]ank\"", "'y'", "'Y'"}, 
false),
@@ -1340,6 +1346,9 @@
        ic.UserYank = inputOrErr(cfg, "user-yank", false, ic.UserYank)
 
        ic.ListOpenFeed = inputOrErr(cfg, "list-open-feed", false, 
ic.ListOpenFeed)
+       ic.ListUserList = inputOrErr(cfg, "list-user-list", false, 
ic.ListUserList)
+       ic.ListUserAdd = inputOrErr(cfg, "list-user-add", false, ic.ListUserAdd)
+       ic.ListUserDelete = inputOrErr(cfg, "list-user-delete", false, 
ic.ListUserDelete)
 
        ic.LinkOpen = inputOrErr(cfg, "link-open", false, ic.LinkOpen)
        ic.LinkYank = inputOrErr(cfg, "link-yank", false, ic.LinkYank)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/config/default_config.go 
new/tut-1.0.20/config/default_config.go
--- old/tut-1.0.19/config/default_config.go     2022-11-20 19:44:42.000000000 
+0100
+++ new/tut-1.0.20/config/default_config.go     2022-11-23 19:07:42.000000000 
+0100
@@ -644,6 +644,18 @@
 # default="[O]pen",'o','O'
 list-open-feed="[O]pen",'o','O'
 
+# List all users in a list
+# default="[U]sers",'u','U'
+list-user-list="[U]sers",'u','U'
+
+# Add user to list
+# default="[A]dd",'a','A'
+list-user-add="[A]dd",'a','A'
+
+# Delete user from list
+# default="[D]elete",'d','D'
+list-user-delete="[D]elete",'d','D'
+
 # Open URL
 # default="[O]pen",'o','O'
 link-open="[O]pen",'o','O'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/config/help.tmpl 
new/tut-1.0.20/config/help.tmpl
--- old/tut-1.0.19/config/help.tmpl     2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/config/help.tmpl     2022-11-23 19:07:42.000000000 +0100
@@ -57,6 +57,15 @@
 {{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:favorites{{ Flags "-" }}{{ 
Color .Style.Text }}
        Lists users that favorited the toot
 
+{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:follow-tag{{ Flags "-" }}{{ 
Color .Style.Text }}
+    Followed by the hashtag to follow e.g. :follow-tag tut
+
+{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:followers{{ Flags "-" }}{{ 
Color .Style.Text }}
+    List of people the account are following. It only works on profiles.
+
+{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:following{{ Flags "-" }}{{ 
Color .Style.Text }}
+    List of people following the account. It only works on profiles.
+
 {{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:h{{ Flags "-" }}{{ Color 
.Style.Text }} or
 {{- Color .Style.TextSpecial2 }}{{ Flags "b" }} :help{{ Flags "-" }}{{ Color 
.Style.Text }}
        View this help message
@@ -92,7 +101,10 @@
        Alias for :bookmarks
 
 {{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:tag{{ Flags "-" }}{{ Color 
.Style.Text }} tagname
-       See toots for a tag. E.g. :tag linux
+       See toots for a tag e.g. :tag linux
+
+{{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:unfollow-tag{{ Flags "-" }}{{ 
Color .Style.Text }}
+    Followed by the hashtag to unfollow e.g. :unfollow-tag tut
 
 {{ Color .Style.TextSpecial2 }}{{ Flags "b" }}:user{{ Flags "-" }}{{ Color 
.Style.Text }} username
        Go to profile for <username>. E.g. :user rasmus
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/config.example.ini 
new/tut-1.0.20/config.example.ini
--- old/tut-1.0.19/config.example.ini   2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/config.example.ini   2022-11-23 19:07:42.000000000 +0100
@@ -642,6 +642,18 @@
 # default="[O]pen",'o','O'
 list-open-feed="[O]pen",'o','O'
 
+# List all users in a list
+# default="[U]sers",'u','U'
+list-user-list="[U]sers",'u','U'
+
+# Add user to list
+# default="[A]dd",'a','A'
+list-user-add="[A]dd",'a','A'
+
+# Delete user from list
+# default="[D]elete",'d','D'
+list-user-delete="[D]elete",'d','D'
+
 # Open URL
 # default="[O]pen",'o','O'
 link-open="[O]pen",'o','O'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/feed/feed.go new/tut-1.0.20/feed/feed.go
--- old/tut-1.0.19/feed/feed.go 2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/feed/feed.go 2022-11-23 19:07:42.000000000 +0100
@@ -14,6 +14,7 @@
 type apiFunc func(pg *mastodon.Pagination) ([]api.Item, error)
 type apiEmptyFunc func() ([]api.Item, error)
 type apiIDFunc func(pg *mastodon.Pagination, id mastodon.ID) ([]api.Item, 
error)
+type apiIDFuncData func(pg *mastodon.Pagination, id mastodon.ID, data 
interface{}) ([]api.Item, error)
 type apiSearchFunc func(search string) ([]api.Item, error)
 type apiSearchPGFunc func(pg *mastodon.Pagination, search string) ([]api.Item, 
error)
 type apiThreadFunc func(status *mastodon.Status) ([]api.Item, error)
@@ -44,6 +45,8 @@
        UserList
        Lists
        List
+       ListUsersIn
+       ListUsersAdd
 )
 
 type LoadingLock struct {
@@ -556,6 +559,57 @@
        f.itemsMux.Unlock()
 }
 
+func (f *Feed) linkNewerIDdata(fn apiIDFuncData, id mastodon.ID, data 
interface{}) {
+       f.apiDataMux.Lock()
+       pg := &mastodon.Pagination{}
+       pg.MinID = f.apiData.MinID
+       maxTmp := f.apiData.MaxID
+
+       items, err := fn(pg, id, data)
+       if err != nil {
+               f.apiDataMux.Unlock()
+               return
+       }
+       f.apiData.MinID = pg.MinID
+       if pg.MaxID == "" {
+               f.apiData.MaxID = maxTmp
+       } else {
+               f.apiData.MaxID = pg.MaxID
+       }
+       f.apiDataMux.Unlock()
+       f.itemsMux.Lock()
+       if len(items) > 0 {
+               f.items = append(items, f.items...)
+               f.Updated(DeskstopNotificationNone)
+       }
+       f.itemsMux.Unlock()
+}
+
+func (f *Feed) linkOlderIDdata(fn apiIDFuncData, id mastodon.ID, data 
interface{}) {
+       f.apiDataMux.Lock()
+       pg := &mastodon.Pagination{}
+       pg.MaxID = f.apiData.MaxID
+       if pg.MaxID == "" {
+               f.apiDataMux.Unlock()
+               return
+       }
+
+       items, err := fn(pg, id, data)
+       if err != nil {
+               f.apiDataMux.Unlock()
+               return
+       }
+       f.apiData.MaxID = pg.MaxID
+       f.apiDataMux.Unlock()
+
+       f.itemsMux.Lock()
+       if len(items) > 0 {
+               f.items = append(f.items, items...)
+               f.Updated(DeskstopNotificationNone)
+       }
+       f.itemsMux.Unlock()
+}
+
 func (f *Feed) startStream(rec *api.Receiver, timeline string, err error) {
        if err != nil {
                log.Fatalln("Couldn't open stream")
@@ -731,7 +785,13 @@
 
 func NewThread(ac *api.AccountClient, status *mastodon.Status) *Feed {
        feed := newFeed(ac, Thread)
-       feed.loadNewer = func() { 
feed.singleThread(feed.accountClient.GetThread, status) }
+       once := true
+       feed.loadNewer = func() {
+               if once {
+                       feed.singleThread(feed.accountClient.GetThread, status)
+                       once = false
+               }
+       }
 
        return feed
 }
@@ -782,6 +842,36 @@
 
        return feed
 }
+
+func NewUsersInList(ac *api.AccountClient, list *mastodon.List) *Feed {
+       feed := newFeed(ac, ListUsersIn)
+       feed.name = list.Title
+       once := true
+       feed.loadNewer = func() {
+               if once {
+                       feed.linkNewerIDdata(feed.accountClient.GetListUsers, 
list.ID, list)
+               }
+               once = false
+       }
+       feed.loadOlder = func() { 
feed.linkOlderIDdata(feed.accountClient.GetListUsers, list.ID, list) }
+
+       return feed
+}
+
+func NewUsersAddList(ac *api.AccountClient, list *mastodon.List) *Feed {
+       feed := newFeed(ac, ListUsersAdd)
+       feed.name = list.Title
+       once := true
+       feed.loadNewer = func() {
+               if once {
+                       
feed.linkNewerIDdata(feed.accountClient.GetFollowingForList, ac.Me.ID, list)
+               }
+               once = false
+       }
+       feed.loadOlder = func() { 
feed.linkOlderIDdata(feed.accountClient.GetFollowingForList, ac.Me.ID, list) }
+
+       return feed
+}
 
 func NewFavoritesStatus(ac *api.AccountClient, id mastodon.ID) *Feed {
        feed := newFeed(ac, Favorites)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/go.mod new/tut-1.0.20/go.mod
--- old/tut-1.0.19/go.mod       2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/go.mod       2022-11-23 19:07:42.000000000 +0100
@@ -3,7 +3,7 @@
 go 1.18
 
 require (
-       github.com/RasmusLindroth/go-mastodon v0.0.10
+       github.com/RasmusLindroth/go-mastodon v0.0.11
        github.com/atotto/clipboard v0.1.4
        github.com/gdamore/tcell/v2 v2.5.3
        github.com/gen2brain/beeep v0.0.0-20220909211152-5a9ec94374f6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/go.sum new/tut-1.0.20/go.sum
--- old/tut-1.0.19/go.sum       2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/go.sum       2022-11-23 19:07:42.000000000 +0100
@@ -1,5 +1,7 @@
 github.com/RasmusLindroth/go-mastodon v0.0.10 
h1:huGNcPn5SASfJDhBL4drKL0PFJ29+hqjCroIrkf2R0E=
 github.com/RasmusLindroth/go-mastodon v0.0.10/go.mod 
h1:Lr6n8V1U2b+9P89YZKsICkNc+oNeJXkygY7raei9SXE=
+github.com/RasmusLindroth/go-mastodon v0.0.11 
h1:Qcad+urrDVrboo13ayoHG3DcwsGK/07qR6IfOPPMilY=
+github.com/RasmusLindroth/go-mastodon v0.0.11/go.mod 
h1:Lr6n8V1U2b+9P89YZKsICkNc+oNeJXkygY7raei9SXE=
 github.com/atotto/clipboard v0.1.4 
h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
 github.com/atotto/clipboard v0.1.4/go.mod 
h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
 github.com/aymerick/douceur v0.2.0 
h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/main.go new/tut-1.0.20/main.go
--- old/tut-1.0.19/main.go      2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/main.go      2022-11-23 19:07:42.000000000 +0100
@@ -8,7 +8,7 @@
        "github.com/rivo/tview"
 )
 
-const version = "1.0.19"
+const version = "1.0.20"
 
 func main() {
        util.SetTerminalTitle("tut")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/ui/cmdbar.go new/tut-1.0.20/ui/cmdbar.go
--- old/tut-1.0.19/ui/cmdbar.go 2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/ui/cmdbar.go 2022-11-23 19:07:42.000000000 +0100
@@ -198,6 +198,26 @@
                        NewUserSearchFeed(c.tutView, user),
                )
                c.Back()
+       case ":follow-tag":
+               if len(parts) < 2 {
+                       break
+               }
+               tag := strings.TrimSpace(parts[1])
+               if len(tag) == 0 {
+                       break
+               }
+               c.tutView.TagFollowCommand(parts[1])
+               c.Back()
+       case ":unfollow-tag":
+               if len(parts) < 2 {
+                       break
+               }
+               tag := strings.TrimSpace(parts[1])
+               if len(tag) == 0 {
+                       break
+               }
+               c.tutView.TagUnfollowCommand(parts[1])
+               c.Back()
        case ":lists":
                c.tutView.ListsCommand()
                c.Back()
@@ -211,7 +231,7 @@
 
 func (c *CmdBar) Autocomplete(curr string) []string {
        var entries []string
-       words := 
strings.Split(":blocking,:boosts,:bookmarks,:clear-notifications,:compose,:favorites,:favorited,:followers,:following,:help,:h,:history,:lists,:list-placement,:list-split,:muting,:newer,:preferences,:profile,:proportions,:requests,:saved,:tag,:timeline,:tl,:user,:window,:quit,:q",
 ",")
+       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,:requests,:saved,:tag,:timeline,:tl,:unfollow-tag,:user,:window,:quit,:q",
 ",")
        if curr == "" {
                return entries
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/ui/commands.go 
new/tut-1.0.20/ui/commands.go
--- old/tut-1.0.19/ui/commands.go       2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/ui/commands.go       2022-11-23 19:07:42.000000000 +0100
@@ -86,6 +86,22 @@
        )
 }
 
+func (tv *TutView) TagFollowCommand(tag string) {
+       err := tv.tut.Client.FollowTag(tag)
+       if err != nil {
+               tv.ShowError(fmt.Sprintf("Couldn't follow tag. Error: %v\n", 
err))
+               return
+       }
+}
+
+func (tv *TutView) TagUnfollowCommand(tag string) {
+       err := tv.tut.Client.UnfollowTag(tag)
+       if err != nil {
+               tv.ShowError(fmt.Sprintf("Couldn't unfollow tag. Error: %v\n", 
err))
+               return
+       }
+}
+
 func (tv *TutView) WindowCommand(index string) {
        i, err := strconv.Atoi(index)
        if err != nil {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/ui/feed.go new/tut-1.0.20/ui/feed.go
--- old/tut-1.0.19/ui/feed.go   2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/ui/feed.go   2022-11-23 19:07:42.000000000 +0100
@@ -336,6 +336,36 @@
        return fd
 }
 
+func NewUsersInListFeed(tv *TutView, l *mastodon.List) *Feed {
+       f := feed.NewUsersInList(tv.tut.Client, l)
+       f.LoadNewer()
+       fd := &Feed{
+               tutView:   tv,
+               Data:      f,
+               ListIndex: 0,
+               List:      NewFeedList(tv.tut, f.StickyCount()),
+               Content:   NewFeedContent(tv.tut),
+       }
+       go fd.update()
+
+       return fd
+}
+
+func NewUsersAddListFeed(tv *TutView, l *mastodon.List) *Feed {
+       f := feed.NewUsersAddList(tv.tut.Client, l)
+       f.LoadNewer()
+       fd := &Feed{
+               tutView:   tv,
+               Data:      f,
+               ListIndex: 0,
+               List:      NewFeedList(tv.tut, f.StickyCount()),
+               Content:   NewFeedContent(tv.tut),
+       }
+       go fd.update()
+
+       return fd
+}
+
 func NewFavoritedFeed(tv *TutView) *Feed {
        f := feed.NewFavorites(tv.tut.Client)
        f.LoadNewer()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/ui/input.go new/tut-1.0.20/ui/input.go
--- old/tut-1.0.19/ui/input.go  2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/ui/input.go  2022-11-23 19:07:42.000000000 +0100
@@ -304,16 +304,21 @@
        case api.StatusHistoryType:
                return tv.InputStatusHistory(event, item, 
item.Raw().(*mastodon.StatusHistory), nil)
        case api.UserType, api.ProfileType:
-               if ft == feed.FollowRequests {
-                       return tv.InputUser(event, item.Raw().(*api.User), true)
-               } else {
-                       return tv.InputUser(event, item.Raw().(*api.User), 
false)
+               switch ft {
+               case feed.FollowRequests:
+                       return tv.InputUser(event, item.Raw().(*api.User), 
InputUserFollowRequest)
+               case feed.ListUsersAdd:
+                       return tv.InputUser(event, item.Raw().(*api.User), 
InputUserListAdd)
+               case feed.ListUsersIn:
+                       return tv.InputUser(event, item.Raw().(*api.User), 
InputUserListDelete)
+               default:
+                       return tv.InputUser(event, item.Raw().(*api.User), 
InputUserNormal)
                }
        case api.NotificationType:
                nd := item.Raw().(*api.NotificationData)
                switch nd.Item.Type {
                case "follow":
-                       return tv.InputUser(event, nd.User.Raw().(*api.User), 
false)
+                       return tv.InputUser(event, nd.User.Raw().(*api.User), 
InputUserNormal)
                case "favourite":
                        user := nd.User.Raw().(*api.User)
                        return tv.InputStatus(event, nd.Status, 
nd.Status.Raw().(*mastodon.Status), user.Data)
@@ -329,7 +334,7 @@
                case "poll":
                        return tv.InputStatus(event, nd.Status, 
nd.Status.Raw().(*mastodon.Status), nil)
                case "follow_request":
-                       return tv.InputUser(event, nd.User.Raw().(*api.User), 
true)
+                       return tv.InputUser(event, nd.User.Raw().(*api.User), 
InputUserFollowRequest)
                }
        case api.ListsType:
                ld := item.Raw().(*mastodon.List)
@@ -548,12 +553,60 @@
        return event
 }
 
-func (tv *TutView) InputUser(event *tcell.EventKey, user *api.User, fr bool) 
*tcell.EventKey {
+type InputUserType uint
+
+const (
+       InputUserNormal = iota
+       InputUserFollowRequest
+       InputUserListAdd
+       InputUserListDelete
+)
+
+func (tv *TutView) InputUser(event *tcell.EventKey, user *api.User, ut 
InputUserType) *tcell.EventKey {
        blocking := user.Relation.Blocking
        muting := user.Relation.Muting
        following := user.Relation.Following
 
-       if tv.tut.Config.Input.UserFollowRequestDecide.Match(event.Key(), 
event.Rune()) {
+       if ut == InputUserListAdd {
+               if tv.tut.Config.Input.GlobalEnter.Match(event.Key(), 
event.Rune()) ||
+                       tv.tut.Config.Input.ListUserAdd.Match(event.Key(), 
event.Rune()) {
+                       ad := user.AdditionalData
+                       switch ad.(type) {
+                       case *mastodon.List:
+                               l := user.AdditionalData.(*mastodon.List)
+                               err := tv.tut.Client.AddUserToList(user.Data, l)
+                               if err != nil {
+                                       tv.ShowError(fmt.Sprintf("Couldn't add 
user to list. Error: %v", err))
+                               }
+                               return nil
+                       default:
+                               return event
+                       }
+
+               }
+               return event
+       }
+
+       if ut == InputUserListDelete {
+               if tv.tut.Config.Input.GlobalEnter.Match(event.Key(), 
event.Rune()) ||
+                       tv.tut.Config.Input.ListUserDelete.Match(event.Key(), 
event.Rune()) {
+                       ad := user.AdditionalData
+                       switch ad.(type) {
+                       case *mastodon.List:
+                               l := user.AdditionalData.(*mastodon.List)
+                               err := 
tv.tut.Client.DeleteUserFromList(user.Data, l)
+                               if err != nil {
+                                       tv.ShowError(fmt.Sprintf("Couldn't 
remove user from list. Error: %v", err))
+                               }
+                               return nil
+                       default:
+                               return event
+                       }
+               }
+               return event
+       }
+
+       if ut == InputUserFollowRequest && 
tv.tut.Config.Input.UserFollowRequestDecide.Match(event.Key(), event.Rune()) {
                tv.ModalView.RunDecide("Do you want accept the follow request?",
                        func() {
                                err := 
tv.tut.Client.FollowRequestAccept(user.Data)
@@ -671,6 +724,14 @@
                tv.Timeline.AddFeed(NewListFeed(tv, list))
                return nil
        }
+       if tv.tut.Config.Input.ListUserList.Match(event.Key(), event.Rune()) {
+               tv.Timeline.AddFeed(NewUsersInListFeed(tv, list))
+               return nil
+       }
+       if tv.tut.Config.Input.ListUserAdd.Match(event.Key(), event.Rune()) {
+               tv.Timeline.AddFeed(NewUsersAddListFeed(tv, list))
+               return nil
+       }
        return event
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/ui/item.go new/tut-1.0.20/ui/item.go
--- old/tut-1.0.19/ui/item.go   2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/ui/item.go   2022-11-23 19:07:42.000000000 +0100
@@ -91,10 +91,15 @@
                }
                drawStatus(tv, item, &status, main, controls, true, "")
        case api.UserType, api.ProfileType:
-               if ft == feed.FollowRequests {
-                       drawUser(tv, item.Raw().(*api.User), main, controls, 
"", true)
-               } else {
-                       drawUser(tv, item.Raw().(*api.User), main, controls, 
"", false)
+               switch ft {
+               case feed.FollowRequests:
+                       drawUser(tv, item.Raw().(*api.User), main, controls, 
"", InputUserFollowRequest)
+               case feed.ListUsersAdd:
+                       drawUser(tv, item.Raw().(*api.User), main, controls, 
"", InputUserListAdd)
+               case feed.ListUsersIn:
+                       drawUser(tv, item.Raw().(*api.User), main, controls, 
"", InputUserListDelete)
+               default:
+                       drawUser(tv, item.Raw().(*api.User), main, controls, 
"", InputUserFollowRequest)
                }
        case api.NotificationType:
                drawNotification(tv, item, item.Raw().(*api.NotificationData), 
main, controls)
@@ -122,9 +127,9 @@
                drawStatus(tv, item, &status, nil, controls, true, "")
        case api.UserType, api.ProfileType:
                if ft == feed.FollowRequests {
-                       drawUser(tv, item.Raw().(*api.User), nil, controls, "", 
true)
+                       drawUser(tv, item.Raw().(*api.User), nil, controls, "", 
InputUserFollowRequest)
                } else {
-                       drawUser(tv, item.Raw().(*api.User), nil, controls, "", 
false)
+                       drawUser(tv, item.Raw().(*api.User), nil, controls, "", 
InputUserNormal)
                }
        case api.NotificationType:
                drawNotification(tv, item, item.Raw().(*api.NotificationData), 
nil, controls)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/ui/item_list.go 
new/tut-1.0.20/ui/item_list.go
--- old/tut-1.0.19/ui/item_list.go      2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/ui/item_list.go      2022-11-23 19:07:42.000000000 +0100
@@ -11,9 +11,19 @@
 }
 
 func drawList(tv *TutView, data *mastodon.List, main *tview.TextView, controls 
*tview.Flex) {
-       btn := NewControl(tv.tut.Config, tv.tut.Config.Input.ListOpenFeed, true)
        controls.Clear()
-       controls.AddItem(NewControlButton(tv, btn), btn.Len, 0, false)
+       var items []Control
+       items = append(items, NewControl(tv.tut.Config, 
tv.tut.Config.Input.ListOpenFeed, true))
+       items = append(items, NewControl(tv.tut.Config, 
tv.tut.Config.Input.ListUserList, true))
+       items = append(items, NewControl(tv.tut.Config, 
tv.tut.Config.Input.ListUserAdd, true))
+       controls.Clear()
+       for i, item := range items {
+               if i < len(items)-1 {
+                       controls.AddItem(NewControlButton(tv, item), 
item.Len+1, 0, false)
+               } else {
+                       controls.AddItem(NewControlButton(tv, item), item.Len, 
0, false)
+               }
+       }
 
        main.SetText(fmt.Sprintf("List %s", tview.Escape(data.Title)))
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/ui/item_notification.go 
new/tut-1.0.20/ui/item_notification.go
--- old/tut-1.0.19/ui/item_notification.go      2022-11-20 19:44:42.000000000 
+0100
+++ new/tut-1.0.20/ui/item_notification.go      2022-11-23 19:07:42.000000000 
+0100
@@ -13,7 +13,7 @@
        switch notification.Item.Type {
        case "follow":
                drawUser(tv, notification.User.Raw().(*api.User), main, 
controls,
-                       fmt.Sprintf("%s started following you", 
util.FormatUsername(notification.Item.Account)), false,
+                       fmt.Sprintf("%s started following you", 
util.FormatUsername(notification.Item.Account)), InputUserNormal,
                )
        case "favourite":
                drawStatus(tv, notification.Status, notification.Item.Status, 
main, controls, false,
@@ -42,7 +42,7 @@
        case "follow_request":
                drawUser(tv, notification.User.Raw().(*api.User), main, 
controls,
                        fmt.Sprintf("%s  wants to follow you.", 
util.FormatUsername(notification.Item.Account)),
-                       true,
+                       InputUserFollowRequest,
                )
        default:
                controls.Clear()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/ui/item_user.go 
new/tut-1.0.20/ui/item_user.go
--- old/tut-1.0.19/ui/item_user.go      2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/ui/item_user.go      2022-11-23 19:07:42.000000000 +0100
@@ -43,7 +43,7 @@
        Style config.Style
 }
 
-func drawUser(tv *TutView, data *api.User, main *tview.TextView, controls 
*tview.Flex, additional string, fr bool) {
+func drawUser(tv *TutView, data *api.User, main *tview.TextView, controls 
*tview.Flex, additional string, ut InputUserType) {
        user := data.Data
        relation := data.Relation
        showUserControl := true
@@ -79,7 +79,7 @@
        u.Fields = fields
 
        var controlItems []Control
-       if fr {
+       if ut == InputUserFollowRequest {
                controlItems = append(controlItems, NewControl(tv.tut.Config, 
tv.tut.Config.Input.UserFollowRequestDecide, false))
        }
        if tv.tut.Client.Me.ID != user.ID {
@@ -108,6 +108,13 @@
        controlItems = append(controlItems, NewControl(tv.tut.Config, 
tv.tut.Config.Input.UserAvatar, true))
        controlItems = append(controlItems, NewControl(tv.tut.Config, 
tv.tut.Config.Input.UserYank, true))
 
+       // Clear controls and only have add and delete for lists.
+       if ut == InputUserListAdd {
+               controlItems = []Control{NewControl(tv.tut.Config, 
tv.tut.Config.Input.ListUserAdd, true)}
+       } else if ut == InputUserListDelete {
+               controlItems = []Control{NewControl(tv.tut.Config, 
tv.tut.Config.Input.ListUserDelete, true)}
+       }
+
        controls.Clear()
        for i, item := range controlItems {
                if i < len(controlItems)-1 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/ui/open.go new/tut-1.0.20/ui/open.go
--- old/tut-1.0.19/ui/open.go   2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/ui/open.go   2022-11-23 19:07:42.000000000 +0100
@@ -1,7 +1,7 @@
 package ui
 
 import (
-       "log"
+       "fmt"
        "os"
        "os/exec"
        "strings"
@@ -36,11 +36,11 @@
        var err error
        tv.tut.App.Suspend(func() {
                err = cmd.Run()
-               if err != nil {
-                       log.Fatalln(err)
-               }
        })
-       return err
+       if err != nil {
+               tv.ShowError(fmt.Sprintf("Eroror while opening: %v", err))
+       }
+       return nil
 }
 
 func openCustom(tv *TutView, program string, args []string, terminal bool, url 
string) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tut-1.0.19/ui/timeline.go 
new/tut-1.0.20/ui/timeline.go
--- old/tut-1.0.19/ui/timeline.go       2022-11-20 19:44:42.000000000 +0100
+++ new/tut-1.0.20/ui/timeline.go       2022-11-23 19:07:42.000000000 +0100
@@ -183,8 +183,10 @@
                ct = "follow requests"
        case feed.Blocking:
                ct = "blocking"
-       case feed.Muting:
-               ct = "muting"
+       case feed.ListUsersAdd:
+               ct = fmt.Sprintf("Add users to %s", name)
+       case feed.ListUsersIn:
+               ct = fmt.Sprintf("Delete users from %s", name)
        }
        return fmt.Sprintf("%s (%d/%d)", ct, index+1, total)
 }

++++++ vendor.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/vendor/github.com/RasmusLindroth/go-mastodon/lists.go 
new/vendor/github.com/RasmusLindroth/go-mastodon/lists.go
--- old/vendor/github.com/RasmusLindroth/go-mastodon/lists.go   2022-11-21 
12:47:23.000000000 +0100
+++ new/vendor/github.com/RasmusLindroth/go-mastodon/lists.go   2022-11-23 
20:03:29.000000000 +0100
@@ -90,7 +90,7 @@
 func (c *Client) AddToList(ctx context.Context, list ID, accounts ...ID) error 
{
        params := url.Values{}
        for _, acct := range accounts {
-               params.Add("account_ids", string(acct))
+               params.Add("account_ids[]", string(acct))
        }
 
        return c.doAPI(ctx, http.MethodPost, 
fmt.Sprintf("/api/v1/lists/%s/accounts", url.PathEscape(string(list))), params, 
nil, nil)
@@ -100,7 +100,7 @@
 func (c *Client) RemoveFromList(ctx context.Context, list ID, accounts ...ID) 
error {
        params := url.Values{}
        for _, acct := range accounts {
-               params.Add("account_ids", string(acct))
+               params.Add("account_ids[]", string(acct))
        }
 
        return c.doAPI(ctx, http.MethodDelete, 
fmt.Sprintf("/api/v1/lists/%s/accounts", url.PathEscape(string(list))), params, 
nil, nil)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/vendor/github.com/RasmusLindroth/go-mastodon/mastodon.go 
new/vendor/github.com/RasmusLindroth/go-mastodon/mastodon.go
--- old/vendor/github.com/RasmusLindroth/go-mastodon/mastodon.go        
2022-11-21 12:47:23.000000000 +0100
+++ new/vendor/github.com/RasmusLindroth/go-mastodon/mastodon.go        
2022-11-23 20:03:29.000000000 +0100
@@ -251,13 +251,6 @@
        ID       ID     `json:"id"`
 }
 
-// Tag hold information for tag.
-type Tag struct {
-       Name    string    `json:"name"`
-       URL     string    `json:"url"`
-       History []History `json:"history"`
-}
-
 // History hold information for history.
 type History struct {
        Day      string `json:"day"`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/RasmusLindroth/go-mastodon/tags.go 
new/vendor/github.com/RasmusLindroth/go-mastodon/tags.go
--- old/vendor/github.com/RasmusLindroth/go-mastodon/tags.go    1970-01-01 
01:00:00.000000000 +0100
+++ new/vendor/github.com/RasmusLindroth/go-mastodon/tags.go    2022-11-23 
20:03:29.000000000 +0100
@@ -0,0 +1,46 @@
+package mastodon
+
+import (
+       "context"
+       "fmt"
+       "net/http"
+       "net/url"
+)
+
+// Tag hold information for tag.
+type Tag struct {
+       Name      string      `json:"name"`
+       URL       string      `json:"url"`
+       History   []History   `json:"history"`
+       Following interface{} `json:"following"`
+}
+
+// TagInfo gets statistics and information about a tag
+func (c *Client) TagInfo(ctx context.Context, tag string) (*Tag, error) {
+       var hashtag Tag
+       err := c.doAPI(ctx, http.MethodGet, fmt.Sprintf("/api/v1/tags/%s", 
url.PathEscape(string(tag))), nil, &hashtag, nil)
+       if err != nil {
+               return nil, err
+       }
+       return &hashtag, nil
+}
+
+// TagFollow lets you follow a hashtag
+func (c *Client) TagFollow(ctx context.Context, tag string) (*Tag, error) {
+       var hashtag Tag
+       err := c.doAPI(ctx, http.MethodPost, 
fmt.Sprintf("/api/v1/tags/%s/follow", url.PathEscape(string(tag))), nil, 
&hashtag, nil)
+       if err != nil {
+               return nil, err
+       }
+       return &hashtag, nil
+}
+
+// TagUnfollow lets you unfollow a hashtag
+func (c *Client) TagUnfollow(ctx context.Context, tag string) (*Tag, error) {
+       var hashtag Tag
+       err := c.doAPI(ctx, http.MethodPost, 
fmt.Sprintf("/api/v1/tags/%s/unfollow", url.PathEscape(string(tag))), nil, 
&hashtag, nil)
+       if err != nil {
+               return nil, err
+       }
+       return &hashtag, nil
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/modules.txt new/vendor/modules.txt
--- old/vendor/modules.txt      2022-11-21 12:47:23.000000000 +0100
+++ new/vendor/modules.txt      2022-11-23 20:03:29.000000000 +0100
@@ -1,4 +1,4 @@
-# github.com/RasmusLindroth/go-mastodon v0.0.10
+# github.com/RasmusLindroth/go-mastodon v0.0.11
 ## explicit; go 1.16
 github.com/RasmusLindroth/go-mastodon
 # github.com/atotto/clipboard v0.1.4

Reply via email to