feat: like and unlike statuses #22
7 changed files with 136 additions and 27 deletions
|
@ -68,8 +68,7 @@ func (g *Client) GetBookmarks(limit int) (model.StatusList, error) {
|
||||||
url := g.Authentication.Instance + path
|
url := g.Authentication.Instance + path
|
||||||
|
|
||||||
bookmarks := model.StatusList{
|
bookmarks := model.StatusList{
|
||||||
Type: model.StatusListBookMarks,
|
Name: "Your Bookmarks",
|
||||||
Name: "BOOKMARKS",
|
|
||||||
Statuses: nil,
|
Statuses: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,3 +109,47 @@ func (g *Client) RemoveStatusFromBookmarks(statusID string) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *Client) LikeStatus(statusID string) error {
|
||||||
|
url := g.Authentication.Instance + "/api/v1/statuses/" + statusID + "/favourite"
|
||||||
|
|
||||||
|
if err := g.sendRequest(http.MethodPost, url, nil, nil); err != nil {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"received an error after sending the request to like the status: %w",
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Client) UnlikeStatus(statusID string) error {
|
||||||
|
url := g.Authentication.Instance + "/api/v1/statuses/" + statusID + "/unfavourite"
|
||||||
|
|
||||||
|
if err := g.sendRequest(http.MethodPost, url, nil, nil); err != nil {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"received an error after sending the request to unlike the status: %w",
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Client) GetLikedStatuses(limit int, resourceName string) (model.StatusList, error) {
|
||||||
|
url := g.Authentication.Instance + fmt.Sprintf("/api/v1/favourites?limit=%d", limit)
|
||||||
|
|
||||||
|
liked := model.StatusList{
|
||||||
|
Name: "Your " + resourceName + " statuses",
|
||||||
|
Statuses: nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := g.sendRequest(http.MethodGet, url, nil, &liked.Statuses); err != nil {
|
||||||
|
return model.StatusList{}, fmt.Errorf(
|
||||||
|
"received an error after sending the request to get the list of statuses: %w",
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return liked, nil
|
||||||
|
}
|
||||||
|
|
|
@ -15,8 +15,7 @@ func (g *Client) GetHomeTimeline(limit int) (model.StatusList, error) {
|
||||||
path := fmt.Sprintf("/api/v1/timelines/home?limit=%d", limit)
|
path := fmt.Sprintf("/api/v1/timelines/home?limit=%d", limit)
|
||||||
|
|
||||||
timeline := model.StatusList{
|
timeline := model.StatusList{
|
||||||
Type: model.StatusListTimeline,
|
Name: "Timeline: Home",
|
||||||
Name: "HOME",
|
|
||||||
Statuses: nil,
|
Statuses: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,8 +26,7 @@ func (g *Client) GetPublicTimeline(limit int) (model.StatusList, error) {
|
||||||
path := fmt.Sprintf("/api/v1/timelines/public?limit=%d", limit)
|
path := fmt.Sprintf("/api/v1/timelines/public?limit=%d", limit)
|
||||||
|
|
||||||
timeline := model.StatusList{
|
timeline := model.StatusList{
|
||||||
Type: model.StatusListTimeline,
|
Name: "Timeline: Public",
|
||||||
Name: "PUBLIC",
|
|
||||||
Statuses: nil,
|
Statuses: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,8 +37,7 @@ func (g *Client) GetListTimeline(listID, title string, limit int) (model.StatusL
|
||||||
path := fmt.Sprintf("/api/v1/timelines/list/%s?limit=%d", listID, limit)
|
path := fmt.Sprintf("/api/v1/timelines/list/%s?limit=%d", listID, limit)
|
||||||
|
|
||||||
timeline := model.StatusList{
|
timeline := model.StatusList{
|
||||||
Type: model.StatusListTimeline,
|
Name: "Timeline: List (" + title + ")",
|
||||||
Name: "LIST (" + title + ")",
|
|
||||||
Statuses: nil,
|
Statuses: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,8 +48,7 @@ func (g *Client) GetTagTimeline(tag string, limit int) (model.StatusList, error)
|
||||||
path := fmt.Sprintf("/api/v1/timelines/tag/%s?limit=%d", tag, limit)
|
path := fmt.Sprintf("/api/v1/timelines/tag/%s?limit=%d", tag, limit)
|
||||||
|
|
||||||
timeline := model.StatusList{
|
timeline := model.StatusList{
|
||||||
Type: model.StatusListTimeline,
|
Name: "Timeline: Tag (" + tag + ")",
|
||||||
Name: "TAG (" + tag + ")",
|
|
||||||
Statuses: nil,
|
Statuses: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ func (a *AddExecutor) Execute() error {
|
||||||
resourceList: a.addToList,
|
resourceList: a.addToList,
|
||||||
resourceAccount: a.addToAccount,
|
resourceAccount: a.addToAccount,
|
||||||
resourceBookmarks: a.addToBookmarks,
|
resourceBookmarks: a.addToBookmarks,
|
||||||
|
resourceStatus: a.addToStatus,
|
||||||
}
|
}
|
||||||
|
|
||||||
doFunc, ok := funcMap[a.toResourceType]
|
doFunc, ok := funcMap[a.toResourceType]
|
||||||
|
@ -184,3 +185,34 @@ func (a *AddExecutor) addStatusToBookmarks(gtsClient *client.Client) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *AddExecutor) addToStatus(gtsClient *client.Client) error {
|
||||||
|
funcMap := map[string]func(*client.Client) error{
|
||||||
|
resourceStar: a.addStarToStatus,
|
||||||
|
resourceLike: a.addStarToStatus,
|
||||||
|
}
|
||||||
|
|
||||||
|
doFunc, ok := funcMap[a.resourceType]
|
||||||
|
if !ok {
|
||||||
|
return UnsupportedAddOperationError{
|
||||||
|
ResourceType: a.resourceType,
|
||||||
|
AddToResourceType: a.toResourceType,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return doFunc(gtsClient)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AddExecutor) addStarToStatus(gtsClient *client.Client) error {
|
||||||
|
if a.statusID == "" {
|
||||||
|
return FlagNotSetError{flagText: flagStatusID}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gtsClient.LikeStatus(a.statusID); err != nil {
|
||||||
|
return fmt.Errorf("unable to add the %s to the status: %w", a.resourceType, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Successfully added a %s to the status.\n", a.resourceType)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -37,12 +37,16 @@ const (
|
||||||
|
|
||||||
resourceAccount = "account"
|
resourceAccount = "account"
|
||||||
resourceBlocked = "blocked"
|
resourceBlocked = "blocked"
|
||||||
|
resourceBookmarks = "bookmarks"
|
||||||
resourceFollowers = "followers"
|
resourceFollowers = "followers"
|
||||||
resourceFollowing = "following"
|
resourceFollowing = "following"
|
||||||
resourceInstance = "instance"
|
resourceInstance = "instance"
|
||||||
|
resourceLike = "like"
|
||||||
|
resourceLiked = "liked"
|
||||||
resourceList = "list"
|
resourceList = "list"
|
||||||
resourceNote = "note"
|
resourceNote = "note"
|
||||||
resourceStatus = "status"
|
resourceStatus = "status"
|
||||||
|
resourceStar = "star"
|
||||||
|
resourceStarred = "starred"
|
||||||
resourceTimeline = "timeline"
|
resourceTimeline = "timeline"
|
||||||
resourceBookmarks = "bookmarks"
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -51,6 +51,7 @@ func (r *RemoveExecutor) Execute() error {
|
||||||
resourceList: r.removeFromList,
|
resourceList: r.removeFromList,
|
||||||
resourceAccount: r.removeFromAccount,
|
resourceAccount: r.removeFromAccount,
|
||||||
resourceBookmarks: r.removeFromBookmarks,
|
resourceBookmarks: r.removeFromBookmarks,
|
||||||
|
resourceStatus: r.removeFromStatus,
|
||||||
}
|
}
|
||||||
|
|
||||||
doFunc, ok := funcMap[r.fromResourceType]
|
doFunc, ok := funcMap[r.fromResourceType]
|
||||||
|
@ -175,3 +176,34 @@ func (r *RemoveExecutor) removeStatusFromBookmarks(gtsClient *client.Client) err
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *RemoveExecutor) removeFromStatus(gtsClient *client.Client) error {
|
||||||
|
funcMap := map[string]func(*client.Client) error{
|
||||||
|
resourceStar: r.removeStarFromStatus,
|
||||||
|
resourceLike: r.removeStarFromStatus,
|
||||||
|
}
|
||||||
|
|
||||||
|
doFunc, ok := funcMap[r.resourceType]
|
||||||
|
if !ok {
|
||||||
|
return UnsupportedRemoveOperationError{
|
||||||
|
ResourceType: r.resourceType,
|
||||||
|
RemoveFromResourceType: r.fromResourceType,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return doFunc(gtsClient)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RemoveExecutor) removeStarFromStatus(gtsClient *client.Client) error {
|
||||||
|
if r.statusID == "" {
|
||||||
|
return FlagNotSetError{flagText: flagStatusID}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gtsClient.UnlikeStatus(r.statusID); err != nil {
|
||||||
|
return fmt.Errorf("unable to remove the %s from the status: %w", r.resourceType, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Successfully removed the %s from the status.\n", r.resourceType)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -67,6 +67,8 @@ func (s *ShowExecutor) Execute() error {
|
||||||
resourceFollowing: s.showFollowing,
|
resourceFollowing: s.showFollowing,
|
||||||
resourceBlocked: s.showBlocked,
|
resourceBlocked: s.showBlocked,
|
||||||
resourceBookmarks: s.showBookmarks,
|
resourceBookmarks: s.showBookmarks,
|
||||||
|
resourceLiked: s.showLiked,
|
||||||
|
resourceStarred: s.showLiked,
|
||||||
}
|
}
|
||||||
|
|
||||||
doFunc, ok := funcMap[s.resourceType]
|
doFunc, ok := funcMap[s.resourceType]
|
||||||
|
@ -329,3 +331,18 @@ func (s *ShowExecutor) showBookmarks(gtsClient *client.Client) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *ShowExecutor) showLiked(gtsClient *client.Client) error {
|
||||||
|
liked, err := gtsClient.GetLikedStatuses(s.limit, s.resourceType)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to retrieve the list of your %s statuses: %w", s.resourceType, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(liked.Statuses) > 0 {
|
||||||
|
utilities.Display(liked, *s.topLevelFlags.NoColor)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("You have no %s statuses.\n", s.resourceType)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -201,32 +201,17 @@ func (s Status) Display(noColor bool) string {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
type StatusListType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
StatusListTimeline StatusListType = iota
|
|
||||||
StatusListBookMarks
|
|
||||||
)
|
|
||||||
|
|
||||||
type StatusList struct {
|
type StatusList struct {
|
||||||
Type StatusListType
|
|
||||||
Name string
|
Name string
|
||||||
Statuses []Status
|
Statuses []Status
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StatusList) Display(noColor bool) string {
|
func (s StatusList) Display(noColor bool) string {
|
||||||
var builder strings.Builder
|
var builder strings.Builder
|
||||||
var name string
|
|
||||||
|
|
||||||
separator := "────────────────────────────────────────────────────────────────────────────────"
|
separator := "────────────────────────────────────────────────────────────────────────────────"
|
||||||
|
|
||||||
if s.Type == StatusListTimeline {
|
builder.WriteString(utilities.HeaderFormat(noColor, s.Name) + "\n")
|
||||||
name = "TIMELINE: " + s.Name
|
|
||||||
} else {
|
|
||||||
name = s.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.WriteString(utilities.HeaderFormat(noColor, name) + "\n")
|
|
||||||
|
|
||||||
for _, status := range s.Statuses {
|
for _, status := range s.Statuses {
|
||||||
builder.WriteString("\n" + utilities.DisplayNameFormat(noColor, status.Account.DisplayName) + " (@" + status.Account.Acct + ")\n")
|
builder.WriteString("\n" + utilities.DisplayNameFormat(noColor, status.Account.DisplayName) + " (@" + status.Account.Acct + ")\n")
|
||||||
|
|
Loading…
Reference in a new issue