package models import ( "time" "gorm.io/gorm" ) // Block table. type Block struct { ID uint64 `gorm:"primaryKey"` SourceUserID uint64 `gorm:"index"` TargetUserID uint64 `gorm:"index"` CreatedAt time.Time UpdatedAt time.Time } // AddBlock is sourceUserId adding targetUserId to their block list. func AddBlock(sourceUserID, targetUserID uint64) error { // Unfriend in the process. RemoveFriend(sourceUserID, targetUserID) // Did we already block this user? var b *Block forward := DB.Where( "source_user_id = ? AND target_user_id = ?", sourceUserID, targetUserID, ).First(&b).Error // Update existing. if forward == nil { return nil } // Create the block. b = &Block{ SourceUserID: sourceUserID, TargetUserID: targetUserID, } return DB.Create(b).Error } // IsBlocking quickly sees if either user blocks the other. func IsBlocking(sourceUserID, targetUserID uint64) bool { b := &Block{} result := DB.Where( "(source_user_id = ? AND target_user_id = ?) OR "+ "(target_user_id = ? AND source_user_id = ?)", sourceUserID, targetUserID, sourceUserID, targetUserID, ).First(&b) return result.Error == nil } // IsBlocked quickly checks if sourceUserID currently blocks targetUserID. func IsBlocked(sourceUserID, targetUserID uint64) bool { b := &Block{} result := DB.Where( "source_user_id = ? AND target_user_id = ?", sourceUserID, targetUserID, ).First(&b) return result.Error == nil } // PaginateBlockList views a user's blocklist. func PaginateBlockList(user *User, pager *Pagination) ([]*User, error) { // We paginate over the Block table. var ( bs = []*Block{} userIDs = []uint64{} query *gorm.DB ) query = DB.Where( "source_user_id = ?", user.ID, ) query = query.Order(pager.Sort) query.Model(&Block{}).Count(&pager.Total) result := query.Offset(pager.GetOffset()).Limit(pager.PerPage).Find(&bs) if result.Error != nil { return nil, result.Error } // Now of these friends get their User objects. for _, b := range bs { userIDs = append(userIDs, b.TargetUserID) } return GetUsers(user, userIDs) } // BlockedUserIDs returns all user IDs blocked by the user. func BlockedUserIDs(userId uint64) []uint64 { var ( bs = []*Block{} userIDs = []uint64{} ) DB.Where("source_user_id = ? OR target_user_id = ?", userId, userId).Find(&bs) for _, row := range bs { for _, uid := range []uint64{row.TargetUserID, row.SourceUserID} { if uid != userId { userIDs = append(userIDs, uid) } } } return userIDs } // UnblockUser removes targetUserID from your blocklist. func UnblockUser(sourceUserID, targetUserID uint64) error { result := DB.Where( "source_user_id = ? AND target_user_id = ?", sourceUserID, targetUserID, ).Delete(&Block{}) return result.Error } // Save photo. func (b *Block) Save() error { result := DB.Save(b) return result.Error }