126 lines
4.0 KiB
Go
126 lines
4.0 KiB
Go
package services
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"git.solsynth.dev/hydrogen/passport/pkg/internal/database"
|
|
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func ListAllFriend(anyside models.Account) ([]models.AccountFriendship, error) {
|
|
var relationships []models.AccountFriendship
|
|
if err := database.C.
|
|
Where("account_id = ? OR related_id = ?", anyside.ID, anyside.ID).
|
|
Preload("Account").
|
|
Preload("Related").
|
|
Find(&relationships).Error; err != nil {
|
|
return relationships, err
|
|
}
|
|
|
|
return relationships, nil
|
|
}
|
|
|
|
func ListFriend(anyside models.Account, status models.FriendshipStatus) ([]models.AccountFriendship, error) {
|
|
var relationships []models.AccountFriendship
|
|
if err := database.C.
|
|
Where("(account_id = ? OR related_id = ?) AND status = ?", anyside.ID, anyside.ID, status).
|
|
Preload("Account").
|
|
Preload("Related").
|
|
Find(&relationships).Error; err != nil {
|
|
return relationships, err
|
|
}
|
|
|
|
return relationships, nil
|
|
}
|
|
|
|
func GetFriend(anysideId uint) (models.AccountFriendship, error) {
|
|
var relationship models.AccountFriendship
|
|
if err := database.C.
|
|
Where(&models.AccountFriendship{AccountID: anysideId}).
|
|
Or(&models.AccountFriendship{RelatedID: anysideId}).
|
|
Preload("Account").
|
|
Preload("Related").
|
|
First(&relationship).Error; err != nil {
|
|
return relationship, err
|
|
}
|
|
|
|
return relationship, nil
|
|
}
|
|
|
|
func GetFriendWithTwoSides(userId, relatedId uint, noPreload ...bool) (models.AccountFriendship, error) {
|
|
var tx *gorm.DB
|
|
if len(noPreload) > 0 && noPreload[0] {
|
|
tx = database.C
|
|
} else {
|
|
tx = database.C.Preload("Account").Preload("Related")
|
|
}
|
|
|
|
var relationship models.AccountFriendship
|
|
if err := tx.
|
|
Where(&models.AccountFriendship{AccountID: userId, RelatedID: relatedId}).
|
|
Or(&models.AccountFriendship{RelatedID: userId, AccountID: relatedId}).
|
|
First(&relationship).Error; err != nil {
|
|
return relationship, err
|
|
}
|
|
|
|
return relationship, nil
|
|
}
|
|
|
|
func NewFriend(user models.Account, related models.Account, status models.FriendshipStatus) (models.AccountFriendship, error) {
|
|
relationship := models.AccountFriendship{
|
|
AccountID: user.ID,
|
|
RelatedID: related.ID,
|
|
Status: status,
|
|
}
|
|
|
|
if user.ID == related.ID {
|
|
return relationship, fmt.Errorf("you cannot make friendship with yourself")
|
|
} else if _, err := GetFriendWithTwoSides(user.ID, related.ID, true); err == nil || !errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return relationship, fmt.Errorf("you already have a friendship with him or her")
|
|
}
|
|
|
|
if err := database.C.Save(&relationship).Error; err != nil {
|
|
return relationship, err
|
|
} else {
|
|
_ = NewNotification(models.Notification{
|
|
Subject: fmt.Sprintf("New friend request from %s", user.Name),
|
|
Content: fmt.Sprintf("You got a new friend request from %s. Go to your settings and decide how to deal it.", user.Nick),
|
|
RecipientID: related.ID,
|
|
})
|
|
}
|
|
|
|
return relationship, nil
|
|
}
|
|
|
|
func EditFriendWithCheck(relationship models.AccountFriendship, user models.Account, originalStatus models.FriendshipStatus) (models.AccountFriendship, error) {
|
|
if relationship.Status != originalStatus {
|
|
if originalStatus == models.FriendshipBlocked && relationship.BlockedBy != nil && user.ID != *relationship.BlockedBy {
|
|
return relationship, fmt.Errorf("the friendship has been blocked by the otherside, you cannot modify it status")
|
|
}
|
|
if relationship.Status == models.FriendshipPending && relationship.RelatedID != user.ID {
|
|
return relationship, fmt.Errorf("only related person can accept friendship")
|
|
}
|
|
}
|
|
if originalStatus != models.FriendshipBlocked && relationship.Status == models.FriendshipBlocked {
|
|
relationship.BlockedBy = &user.ID
|
|
}
|
|
|
|
return EditFriend(relationship)
|
|
}
|
|
|
|
func EditFriend(relationship models.AccountFriendship) (models.AccountFriendship, error) {
|
|
if err := database.C.Save(&relationship).Error; err != nil {
|
|
return relationship, err
|
|
}
|
|
return relationship, nil
|
|
}
|
|
|
|
func DeleteFriend(relationship models.AccountFriendship) error {
|
|
if err := database.C.Delete(&relationship).Error; err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|