159 lines
3.4 KiB
Go

package arn
import (
"errors"
"github.com/aerogo/nano"
)
// UserFollows is a list including IDs to users you follow.
type UserFollows struct {
UserID UserID `json:"userId" primary:"true"`
Items []string `json:"items"`
}
// NewUserFollows creates a new UserFollows list.
func NewUserFollows(userID UserID) *UserFollows {
return &UserFollows{
UserID: userID,
Items: []string{},
}
}
// Add adds an user to the list if it hasn't been added yet.
func (list *UserFollows) Add(userID UserID) error {
if userID == list.UserID {
return errors.New("You can't follow yourself")
}
if list.Contains(userID) {
return errors.New("User " + userID + " has already been added")
}
list.Items = append(list.Items, userID)
// Send notification
user, err := GetUser(userID)
if err == nil {
if !user.Settings().Notification.NewFollowers {
return nil
}
follower, err := GetUser(list.UserID)
if err == nil {
user.SendNotification(&PushNotification{
Title: "You have a new follower!",
Message: follower.Nick + " started following you.",
Icon: "https:" + follower.AvatarLink("large"),
Link: "https://notify.moe" + follower.Link(),
Type: NotificationTypeFollow,
})
}
}
return nil
}
// Remove removes the user ID from the list.
func (list *UserFollows) Remove(userID UserID) bool {
for index, item := range list.Items {
if item == userID {
list.Items = append(list.Items[:index], list.Items[index+1:]...)
return true
}
}
return false
}
// Contains checks if the list contains the user ID already.
func (list *UserFollows) Contains(userID UserID) bool {
for _, item := range list.Items {
if item == userID {
return true
}
}
return false
}
// Users returns a slice of all the users you are following.
func (list *UserFollows) Users() []*User {
followsObj := DB.GetMany("User", list.Items)
follows := make([]*User, len(followsObj))
for i, obj := range followsObj {
follows[i] = obj.(*User)
}
return follows
}
// UsersWhoFollowBack returns a slice of all the users you are following that also follow you.
func (list *UserFollows) UsersWhoFollowBack() []*User {
followsObj := DB.GetMany("User", list.Items)
friends := make([]*User, 0, len(followsObj))
for _, obj := range followsObj {
friend := obj.(*User)
if Contains(friend.Follows().Items, list.UserID) {
friends = append(friends, friend)
}
}
return friends
}
// UserFollowerCountMap returns a map of user ID keys and their corresping number of followers as the value.
func UserFollowerCountMap() map[string]int {
followCount := map[string]int{}
for list := range StreamUserFollows() {
for _, followUserID := range list.Items {
followCount[followUserID]++
}
}
return followCount
}
// GetUserFollows ...
func GetUserFollows(id UserID) (*UserFollows, error) {
obj, err := DB.Get("UserFollows", id)
if err != nil {
return nil, err
}
return obj.(*UserFollows), nil
}
// StreamUserFollows returns a stream of all user follows.
func StreamUserFollows() <-chan *UserFollows {
channel := make(chan *UserFollows, nano.ChannelBufferSize)
go func() {
for obj := range DB.All("UserFollows") {
channel <- obj.(*UserFollows)
}
close(channel)
}()
return channel
}
// AllUserFollows returns a slice of all user follows.
func AllUserFollows() ([]*UserFollows, error) {
all := make([]*UserFollows, 0, DB.Collection("UserFollows").Count())
for obj := range StreamUserFollows() {
all = append(all, obj)
}
return all, nil
}