threadr.lostcave.ddnss.de/models/chat.go

110 lines
2.9 KiB
Go

package models
import (
"database/sql"
"regexp"
"time"
)
type ChatMessage struct {
ID int `json:"id"`
UserID int `json:"userId"`
Content string `json:"content"`
ReplyTo int `json:"replyTo"`
Timestamp time.Time `json:"timestamp"`
Username string `json:"username"`
PfpFileID sql.NullInt64 `json:"pfpFileId"`
Mentions []string `json:"mentions"`
}
func CreateChatMessage(db *sql.DB, msg ChatMessage) error {
query := "INSERT INTO chat_messages (user_id, content, reply_to, timestamp) VALUES (?, ?, ?, NOW())"
_, err := db.Exec(query, msg.UserID, msg.Content, msg.ReplyTo)
return err
}
func GetRecentChatMessages(db *sql.DB, limit int) ([]ChatMessage, error) {
query := `
SELECT cm.id, cm.user_id, cm.content, cm.reply_to, cm.timestamp, u.username, u.pfp_file_id
FROM chat_messages cm
JOIN users u ON cm.user_id = u.id
ORDER BY cm.timestamp DESC
LIMIT ?`
rows, err := db.Query(query, limit)
if err != nil {
return nil, err
}
defer rows.Close()
var messages []ChatMessage
for rows.Next() {
var msg ChatMessage
var timestampStr string
err := rows.Scan(&msg.ID, &msg.UserID, &msg.Content, &msg.ReplyTo, &timestampStr, &msg.Username, &msg.PfpFileID)
if err != nil {
return nil, err
}
msg.Timestamp, err = time.Parse("2006-01-02 15:04:05", timestampStr)
if err != nil {
msg.Timestamp = time.Time{}
}
msg.Mentions = extractMentions(msg.Content)
messages = append(messages, msg)
}
return messages, nil
}
func GetChatMessageByID(db *sql.DB, id int) (*ChatMessage, error) {
query := `
SELECT cm.id, cm.user_id, cm.content, cm.reply_to, cm.timestamp, u.username, u.pfp_file_id
FROM chat_messages cm
JOIN users u ON cm.user_id = u.id
WHERE cm.id = ?`
row := db.QueryRow(query, id)
var msg ChatMessage
var timestampStr string
err := row.Scan(&msg.ID, &msg.UserID, &msg.Content, &msg.ReplyTo, &timestampStr, &msg.Username, &msg.PfpFileID)
if err == sql.ErrNoRows {
return nil, nil
}
if err != nil {
return nil, err
}
msg.Timestamp, err = time.Parse("2006-01-02 15:04:05", timestampStr)
if err != nil {
msg.Timestamp = time.Time{}
}
msg.Mentions = extractMentions(msg.Content)
return &msg, nil
}
func GetUsernamesMatching(db *sql.DB, prefix string) ([]string, error) {
query := "SELECT username FROM users WHERE username LIKE ? LIMIT 10"
rows, err := db.Query(query, prefix+"%")
if err != nil {
return nil, err
}
defer rows.Close()
var usernames []string
for rows.Next() {
var username string
if err := rows.Scan(&username); err != nil {
return nil, err
}
usernames = append(usernames, username)
}
return usernames, nil
}
// Simple utility to extract mentions from content
func extractMentions(content string) []string {
re := regexp.MustCompile(`@(\w+)`)
matches := re.FindAllStringSubmatch(content, -1)
mentions := make([]string, len(matches))
for i, match := range matches {
mentions[i] = match[1]
}
return mentions
}