Noah
030fadcf8d
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
|
|
}
|