Add message scrollback
This commit is contained in:
parent
b5d12954a6
commit
45c61e7596
16 changed files with 313 additions and 136 deletions
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue