xtablo-source/backend/templates/discussion_forms.go
Arthur Belleville d8e52f695b
fix(17): own messages right-aligned; restore .divide-y for SSE compatibility
- Add IsOwn bool to DiscussionMessageView; set via user.ID comparison in
  DiscussionMessagesFromRows and DiscussionMessageFromRow
- Thread currentUserID through loadDiscussionTabData and all call sites
- discussion.templ: branch message-own vs message-other on message.IsOwn
- Restore .divide-y wrapper inside #discussion-messages (discussion-sse.js
  depends on it to locate the message list before appending SSE events)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 10:22:23 +02:00

132 lines
3.1 KiB
Go

package templates
import (
"strconv"
"time"
"backend/internal/db/sqlc"
"github.com/google/uuid"
)
const DiscussionMaxBodyLength = 10000
type DiscussionForm struct {
Body string
}
type DiscussionErrors struct {
Body string
General string
}
type DiscussionMessageView struct {
ID uuid.UUID
AuthorEmail string
Body string
CreatedAt time.Time
IsOwn bool
}
type DiscussionTabData struct {
Messages []DiscussionMessageView
}
type TabloCardView struct {
Tablo sqlc.Tablo
DiscussionUnreadCount int64
}
func DiscussionPostURL(tabloID uuid.UUID) string {
return "/tablos/" + tabloID.String() + "/discussion/messages"
}
func DiscussionMaxBodyLengthString() string {
return strconv.Itoa(DiscussionMaxBodyLength)
}
func DiscussionURL(tabloID uuid.UUID) string {
return "/tablos/" + tabloID.String() + "/discussion"
}
func DiscussionStreamURL(tabloID uuid.UUID) string {
return "/tablos/" + tabloID.String() + "/discussion/stream"
}
func DiscussionMessagesFromRows(rows []sqlc.ListDiscussionMessagesByTabloRow, currentUserID uuid.UUID) []DiscussionMessageView {
messages := make([]DiscussionMessageView, 0, len(rows))
for _, row := range rows {
messages = append(messages, DiscussionMessageView{
ID: row.ID,
AuthorEmail: row.AuthorEmail,
Body: row.Body,
CreatedAt: row.CreatedAt.Time,
IsOwn: row.AuthorUserID == currentUserID,
})
}
return messages
}
func DiscussionMessageFromRow(row sqlc.GetDiscussionMessageWithAuthorRow, isOwn bool) DiscussionMessageView {
return DiscussionMessageView{
ID: row.ID,
AuthorEmail: row.AuthorEmail,
Body: row.Body,
CreatedAt: row.CreatedAt.Time,
IsOwn: isOwn,
}
}
func TabloCardsFromUnreadRows(rows []sqlc.ListTablosByUserWithDiscussionUnreadRow) []TabloCardView {
cards := make([]TabloCardView, 0, len(rows))
for _, row := range rows {
cards = append(cards, TabloCardView{
Tablo: sqlc.Tablo{
ID: row.ID,
UserID: row.UserID,
Title: row.Title,
Description: row.Description,
Color: row.Color,
CreatedAt: row.CreatedAt,
UpdatedAt: row.UpdatedAt,
},
DiscussionUnreadCount: row.DiscussionUnreadCount,
})
}
return cards
}
func TabloCardFromTablo(tablo sqlc.Tablo) TabloCardView {
return TabloCardView{Tablo: tablo}
}
func DiscussionUnreadDisplay(count int64) string {
if count > 99 {
return "99+"
}
return strconv.FormatInt(count, 10)
}
func DiscussionUnreadAriaLabel(count int64) string {
if count == 1 {
return "1 unread discussion message"
}
return strconv.FormatInt(count, 10) + " unread discussion messages"
}
func DiscussionDateLabel(t time.Time) string {
return t.Local().Format("January 2, 2006")
}
func DiscussionTimestampLabel(t time.Time) string {
return t.Local().Format("January 2, 2006 15:04")
}
func DiscussionShowDaySeparator(messages []DiscussionMessageView, index int) bool {
if index == 0 {
return true
}
current := messages[index].CreatedAt.Local()
previous := messages[index-1].CreatedAt.Local()
return current.Year() != previous.Year() || current.YearDay() != previous.YearDay()
}