132 lines
3.4 KiB
Go
132 lines
3.4 KiB
Go
package models
|
|
|
|
import (
|
|
"database/sql"
|
|
"time"
|
|
)
|
|
|
|
type ChatMessage struct {
|
|
ID int
|
|
UserID int
|
|
Content string
|
|
ReplyTo int // -1 if not a reply
|
|
Timestamp time.Time
|
|
Username string // For display, fetched from user
|
|
PfpURL string // For display, fetched from user
|
|
Mentions []string // List of mentioned usernames
|
|
}
|
|
|
|
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_url
|
|
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
|
|
var pfpURL sql.NullString
|
|
err := rows.Scan(&msg.ID, &msg.UserID, &msg.Content, &msg.ReplyTo, ×tampStr, &msg.Username, &pfpURL)
|
|
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{}
|
|
}
|
|
if pfpURL.Valid {
|
|
msg.PfpURL = pfpURL.String
|
|
}
|
|
// Parse mentions from content (simple @username detection)
|
|
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_url
|
|
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
|
|
var pfpURL sql.NullString
|
|
err := row.Scan(&msg.ID, &msg.UserID, &msg.Content, &msg.ReplyTo, ×tampStr, &msg.Username, &pfpURL)
|
|
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{}
|
|
}
|
|
if pfpURL.Valid {
|
|
msg.PfpURL = pfpURL.String
|
|
}
|
|
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 {
|
|
var mentions []string
|
|
var currentMention string
|
|
inMention := false
|
|
|
|
for _, char := range content {
|
|
if char == '@' {
|
|
inMention = true
|
|
currentMention = "@"
|
|
} else if inMention && (char == ' ' || char == '\n' || char == '\t') {
|
|
if len(currentMention) > 1 {
|
|
mentions = append(mentions, currentMention)
|
|
}
|
|
inMention = false
|
|
currentMention = ""
|
|
} else if inMention {
|
|
currentMention += string(char)
|
|
}
|
|
}
|
|
if inMention && len(currentMention) > 1 {
|
|
mentions = append(mentions, currentMention)
|
|
}
|
|
return mentions
|
|
} |