Private
Public Access
1
0

Add LastMessageAt field to conversation

Replaced `LatestConversationMessages` with `LoadConversationList`, which
utilizes `LastMessageAt` for much faster conversation loading in the
conversation listing TUI and `lmcli list` command.
This commit is contained in:
2024-10-21 15:33:20 +00:00
parent 0384c7cb66
commit 07c96082e7
5 changed files with 88 additions and 78 deletions

View File

@@ -17,6 +17,7 @@ type Conversation struct {
SelectedRootID *uint
SelectedRoot *Message `gorm:"foreignKey:SelectedRootID"`
RootMessages []Message `gorm:"-:all"`
LastMessageAt time.Time
}
type MessageMeta struct {

View File

@@ -15,8 +15,7 @@ import (
// Repo exposes low-level message and conversation management. See
// Service for high-level helpers
type Repo interface {
// LatestConversationMessages returns a slice of all conversations ordered by when they were last updated (newest to oldest)
LatestConversationMessages() ([]Message, error)
LoadConversationList() (ConversationList, error)
FindConversationByShortName(shortName string) (*Conversation, error)
ConversationShortNameCompletions(search string) []string
@@ -72,25 +71,40 @@ func NewRepo(db *gorm.DB) (Repo, error) {
return &repo{db, _sqids}, nil
}
func (s *repo) LatestConversationMessages() ([]Message, error) {
var latestMessages []Message
type conversationListItem struct {
ID uint
ShortName string
Title string
LastMessageAt time.Time
}
subQuery := s.db.Model(&Message{}).
Select("MAX(created_at) as max_created_at, conversation_id").
Group("conversation_id")
type ConversationList struct {
Total int
Items []conversationListItem
}
err := s.db.Model(&Message{}).
Joins("JOIN (?) as sub on messages.conversation_id = sub.conversation_id AND messages.created_at = sub.max_created_at", subQuery).
Group("messages.conversation_id").
Order("created_at DESC").
Preload("Conversation.SelectedRoot").
Find(&latestMessages).Error
// LoadConversationList loads existing conversations, ordered by the date
// of their latest message, from most recent to oldest.
func (s *repo) LoadConversationList() (ConversationList, error) {
list := ConversationList{}
var convos []Conversation
err := s.db.Order("last_message_at DESC").Find(&convos).Error
if err != nil {
return nil, err
return list, err
}
return latestMessages, nil
for _, c := range convos {
list.Items = append(list.Items, conversationListItem{
ID: c.ID,
ShortName: c.ShortName.String,
Title: c.Title,
LastMessageAt: c.LastMessageAt,
})
}
list.Total = len(list.Items)
return list, nil
}
func (s *repo) FindConversationByShortName(shortName string) (*Conversation, error) {
@@ -220,6 +234,9 @@ func (s *repo) Reply(to *Message, messages ...Message) ([]Message, error) {
savedMessages = append(savedMessages, message)
currentParent = &message
}
to.Conversation.LastMessageAt = savedMessages[len(savedMessages)-1].CreatedAt
s.UpdateConversation(to.Conversation)
return nil
})
@@ -427,10 +444,7 @@ func (s *repo) StartConversation(messages ...Message) (*Conversation, []Message,
// Update conversation's selected root message
conversation.RootMessages = []Message{messages[0]}
conversation.SelectedRoot = &messages[0]
err = s.UpdateConversation(conversation)
if err != nil {
return nil, nil, err
}
conversation.LastMessageAt = messages[0].CreatedAt
// Add additional replies to conversation
if len(messages) > 1 {
@@ -439,10 +453,12 @@ func (s *repo) StartConversation(messages ...Message) (*Conversation, []Message,
return nil, nil, err
}
messages = append([]Message{messages[0]}, newMessages...)
conversation.LastMessageAt = messages[len(messages)-1].CreatedAt
}
return conversation, messages, nil
}
err = s.UpdateConversation(conversation)
return conversation, messages, err
}
// CloneConversation clones the given conversation and all of its meesages
func (s *repo) CloneConversation(toClone Conversation) (*Conversation, uint, error) {