Noah Petherbridge
96e5b1abfa
Implement block lists. They work like friend lists but are unidirectional, but take effect in both directions (blocker and blockee can not see one another on the site -- except admin users can always see all users). * Profile page says 404 * User gallery says 404 * User search page filters out blocked users * Compose endpoint blocks sending messages to blocked users (except admin) * Site Gallery filters photos by blocked (and uncertified) users * Inbox page hides chat list for blocked users (can still read the chat history if you have a link to the old thread)
109 lines
2.6 KiB
Go
109 lines
2.6 KiB
Go
package models
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// Message table.
|
|
type Message struct {
|
|
ID uint64 `gorm:"primaryKey"`
|
|
SourceUserID uint64 `gorm:"index"`
|
|
TargetUserID uint64 `gorm:"index"`
|
|
Read bool `gorm:"index"`
|
|
Message string
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
}
|
|
|
|
// GetMessage by ID.
|
|
func GetMessage(id uint64) (*Message, error) {
|
|
m := &Message{}
|
|
result := DB.First(&m, id)
|
|
return m, result.Error
|
|
}
|
|
|
|
// GetMessages for a user.
|
|
func GetMessages(userID uint64, sent bool, pager *Pagination) ([]*Message, error) {
|
|
var (
|
|
m = []*Message{}
|
|
blockedUserIDs = BlockedUserIDs(userID)
|
|
where = []string{}
|
|
placeholders = []interface{}{}
|
|
)
|
|
|
|
if sent {
|
|
where = append(where, "source_user_id = ?")
|
|
placeholders = append(placeholders, userID)
|
|
|
|
if len(blockedUserIDs) > 0 {
|
|
where = append(where, "target_user_id NOT IN ?")
|
|
placeholders = append(placeholders, blockedUserIDs)
|
|
}
|
|
} else {
|
|
where = append(where, "target_user_id = ?")
|
|
placeholders = append(placeholders, userID)
|
|
|
|
if len(blockedUserIDs) > 0 {
|
|
where = append(where, "source_user_id NOT IN ?")
|
|
placeholders = append(placeholders, blockedUserIDs)
|
|
}
|
|
}
|
|
|
|
query := DB.Where(
|
|
strings.Join(where, " AND "),
|
|
placeholders...,
|
|
).Order(pager.Sort)
|
|
|
|
query.Model(&Message{}).Count(&pager.Total)
|
|
result := query.Offset(pager.GetOffset()).Limit(pager.PerPage).Find(&m)
|
|
return m, result.Error
|
|
}
|
|
|
|
// GetMessageThread returns paginated message history between two people.
|
|
func GetMessageThread(sourceUserID, targetUserID uint64, pager *Pagination) ([]*Message, error) {
|
|
var m = []*Message{}
|
|
|
|
query := DB.Where(
|
|
"(source_user_id = ? AND target_user_id = ?) OR (source_user_id = ? AND target_user_id = ?)",
|
|
sourceUserID, targetUserID,
|
|
targetUserID, sourceUserID,
|
|
).Order(pager.Sort)
|
|
|
|
query.Model(&Message{}).Count(&pager.Total)
|
|
result := query.Offset(pager.GetOffset()).Limit(pager.PerPage).Find(&m)
|
|
return m, result.Error
|
|
}
|
|
|
|
// CountUnreadMessages gets the count of unread messages for a user.
|
|
func CountUnreadMessages(userID uint64) (int64, error) {
|
|
query := DB.Where(
|
|
"target_user_id = ? AND read = ?",
|
|
userID,
|
|
false,
|
|
)
|
|
|
|
var count int64
|
|
result := query.Model(&Message{}).Count(&count)
|
|
return count, result.Error
|
|
}
|
|
|
|
// SendMessage from a source to a target user.
|
|
func SendMessage(sourceUserID, targetUserID uint64, message string) (*Message, error) {
|
|
m := &Message{
|
|
SourceUserID: sourceUserID,
|
|
TargetUserID: targetUserID,
|
|
Message: message,
|
|
Read: false,
|
|
}
|
|
|
|
result := DB.Create(m)
|
|
return m, result.Error
|
|
}
|
|
|
|
// Save message.
|
|
func (m *Message) Save() error {
|
|
result := DB.Save(m)
|
|
return result.Error
|
|
}
|