Add message scrollback

This commit is contained in:
Ken-Håvard Lieng 2017-05-02 23:21:25 +02:00
parent b5d12954a6
commit 45c61e7596
16 changed files with 313 additions and 136 deletions

View file

@ -10,7 +10,7 @@ import (
)
type Message struct {
ID string `json:"id" bleve:"-"`
ID string `json:"-" bleve:"-"`
Server string `json:"-" bleve:"server"`
From string `json:"from" bleve:"-"`
To string `json:"-" bleve:"to"`
@ -53,36 +53,13 @@ func (u *User) LogMessage(id, server, from, to, content string) error {
return u.messageIndex.Index(id, message)
}
func (u *User) GetLastMessages(server, channel string, count int) ([]Message, error) {
messages := make([]Message, count)
u.messageLog.View(func(tx *bolt.Tx) error {
b := tx.Bucket(bucketMessages).Bucket([]byte(server + ":" + channel))
if b == nil {
return nil
}
c := b.Cursor()
for _, v := c.Last(); count > 0 && v != nil; _, v = c.Prev() {
count--
messages[count].Unmarshal(v)
}
return nil
})
if count == 0 {
return messages, nil
} else if count < len(messages) {
return messages[count:], nil
}
return nil, nil
func (u *User) GetLastMessages(server, channel string, count int) ([]Message, bool, error) {
return u.GetMessages(server, channel, count, "")
}
func (u *User) GetMessages(server, channel string, count int, fromID string) ([]Message, error) {
func (u *User) GetMessages(server, channel string, count int, fromID string) ([]Message, bool, error) {
messages := make([]Message, count)
hasMore := false
u.messageLog.View(func(tx *bolt.Tx) error {
b := tx.Bucket(bucketMessages).Bucket([]byte(server + ":" + channel))
@ -91,23 +68,35 @@ func (u *User) GetMessages(server, channel string, count int, fromID string) ([]
}
c := b.Cursor()
c.Seek([]byte(fromID))
for k, v := c.Prev(); count > 0 && k != nil; k, v = c.Prev() {
count--
messages[count].Unmarshal(v)
if fromID != "" {
c.Seek([]byte(fromID))
for k, v := c.Prev(); count > 0 && k != nil; k, v = c.Prev() {
count--
messages[count].Unmarshal(v)
}
} else {
for k, v := c.Last(); count > 0 && k != nil; k, v = c.Prev() {
count--
messages[count].Unmarshal(v)
}
}
c.Next()
k, _ := c.Prev()
hasMore = k != nil
return nil
})
if count == 0 {
return messages, nil
return messages, hasMore, nil
} else if count < len(messages) {
return messages[count:], nil
return messages[count:], hasMore, nil
}
return nil, nil
return nil, false, nil
}
func (u *User) SearchMessages(server, channel, q string) ([]Message, error) {

View file

@ -88,12 +88,14 @@ func TestMessages(t *testing.T) {
user, err := NewUser()
assert.Nil(t, err)
messages, err := user.GetMessages("irc.freenode.net", "#go-nuts", 10, "6")
messages, hasMore, err := user.GetMessages("irc.freenode.net", "#go-nuts", 10, "6")
assert.Nil(t, err)
assert.False(t, hasMore)
assert.Len(t, messages, 0)
messages, err = user.GetLastMessages("irc.freenode.net", "#go-nuts", 10)
messages, hasMore, err = user.GetLastMessages("irc.freenode.net", "#go-nuts", 10)
assert.Nil(t, err)
assert.False(t, hasMore)
assert.Len(t, messages, 0)
messages, err = user.SearchMessages("irc.freenode.net", "#go-nuts", "message")
@ -108,35 +110,40 @@ func TestMessages(t *testing.T) {
assert.Nil(t, err)
}
messages, err = user.GetMessages("irc.freenode.net", "#go-nuts", 10, ids[4])
messages, hasMore, err = user.GetMessages("irc.freenode.net", "#go-nuts", 10, ids[4])
assert.Equal(t, "message0", messages[0].Content)
assert.Equal(t, "message3", messages[3].Content)
assert.Nil(t, err)
assert.False(t, hasMore)
assert.Len(t, messages, 4)
messages, err = user.GetMessages("irc.freenode.net", "#go-nuts", 10, betterguid.New())
messages, hasMore, err = user.GetMessages("irc.freenode.net", "#go-nuts", 10, betterguid.New())
assert.Equal(t, "message0", messages[0].Content)
assert.Equal(t, "message4", messages[4].Content)
assert.Nil(t, err)
assert.False(t, hasMore)
assert.Len(t, messages, 5)
messages, err = user.GetMessages("irc.freenode.net", "#go-nuts", 10, ids[2])
messages, hasMore, err = user.GetMessages("irc.freenode.net", "#go-nuts", 10, ids[2])
assert.Equal(t, "message0", messages[0].Content)
assert.Equal(t, "message1", messages[1].Content)
assert.Nil(t, err)
assert.False(t, hasMore)
assert.Len(t, messages, 2)
messages, err = user.GetLastMessages("irc.freenode.net", "#go-nuts", 10)
messages, hasMore, err = user.GetLastMessages("irc.freenode.net", "#go-nuts", 10)
assert.Equal(t, "message0", messages[0].Content)
assert.Equal(t, "message2", messages[2].Content)
assert.Equal(t, "message4", messages[4].Content)
assert.Nil(t, err)
assert.False(t, hasMore)
assert.Len(t, messages, 5)
messages, err = user.GetLastMessages("irc.freenode.net", "#go-nuts", 3)
assert.Equal(t, "message2", messages[0].Content)
assert.Equal(t, "message4", messages[2].Content)
messages, hasMore, err = user.GetLastMessages("irc.freenode.net", "#go-nuts", 4)
assert.Equal(t, "message1", messages[0].Content)
assert.Equal(t, "message4", messages[3].Content)
assert.Nil(t, err)
assert.Len(t, messages, 3)
assert.True(t, hasMore)
assert.Len(t, messages, 4)
messages, err = user.SearchMessages("irc.freenode.net", "#go-nuts", "message")
assert.Nil(t, err)