Save history to disk. Fixes #1

This commit is contained in:
Tulir Asokan
2018-03-22 19:51:20 +02:00
parent 232f7fe1be
commit 702a75a8c0
8 changed files with 147 additions and 25 deletions

View File

@ -28,7 +28,7 @@ type Message struct {
BasicMeta
ID string
Text string
Buffer []string
buffer []string
prevBufferWidth int
}
@ -64,12 +64,12 @@ func (message *Message) CalculateBuffer(width int) {
if width < 2 {
return
}
message.Buffer = []string{}
message.buffer = []string{}
forcedLinebreaks := strings.Split(message.Text, "\n")
newlines := 0
for _, str := range forcedLinebreaks {
if len(str) == 0 && newlines < 1 {
message.Buffer = append(message.Buffer, "")
message.buffer = append(message.buffer, "")
newlines++
} else {
newlines = 0
@ -87,7 +87,7 @@ func (message *Message) CalculateBuffer(width int) {
extract = extract[:matches[len(matches)-1][1]]
}
}
message.Buffer = append(message.Buffer, extract)
message.buffer = append(message.buffer, extract)
str = str[len(extract):]
}
}
@ -97,3 +97,11 @@ func (message *Message) CalculateBuffer(width int) {
func (message *Message) RecalculateBuffer() {
message.CalculateBuffer(message.prevBufferWidth)
}
func (message *Message) Buffer() []string {
return message.buffer
}
func (message *Message) Height() int {
return len(message.buffer)
}

View File

@ -162,7 +162,7 @@ func (view *MainView) HandleCommand(room, command string, args []string) {
case "/quit":
view.gmx.Stop()
case "/clearcache":
view.config.Session.Clear()
view.config.Clear()
view.gmx.Stop()
case "/panic":
panic("This is a test panic.")
@ -239,6 +239,15 @@ func (view *MainView) Focus(delegate func(p tview.Primitive)) {
}
}
func (view *MainView) SaveAllHistory() {
for _, room := range view.rooms {
err := room.SaveHistory(view.config.HistoryDir)
if err != nil {
debug.Printf("Failed to save history of %s: %v", room.Room.GetTitle(), err)
}
}
}
func (view *MainView) addRoom(index int, room string) {
roomStore := view.matrix.GetRoom(room)
@ -254,7 +263,13 @@ func (view *MainView) addRoom(index int, room string) {
view.rooms[room] = roomView
view.roomView.AddPage(room, roomView, true, false)
roomView.UpdateUserList()
go view.LoadInitialHistory(room)
count, err := roomView.LoadHistory(view.config.HistoryDir)
if err != nil {
debug.Printf("Failed to load history of %s: %v", roomView.Room.GetTitle(), err)
} else if count <= 0 {
go view.LoadInitialHistory(room)
}
}
}
@ -377,6 +392,11 @@ func (view *MainView) LoadHistory(room string, initial bool) {
room.AddMessage(message, widget.PrependMessage)
}
}
err = roomView.SaveHistory(view.config.HistoryDir)
if err != nil {
debug.Printf("%Failed to save history of %s: %v", roomView.Room.GetTitle(), err)
}
view.config.Session.Save()
view.parent.Render()
}

View File

@ -17,7 +17,9 @@
package widget
import (
"encoding/gob"
"fmt"
"os"
"time"
"github.com/gdamore/tcell"
@ -79,6 +81,45 @@ func (view *MessageView) NewMessage(id, sender, text string, timestamp time.Time
GetHashColor(sender))
}
func (view *MessageView) SaveHistory(path string) error {
file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0600)
if err != nil {
return err
}
defer file.Close()
enc := gob.NewEncoder(file)
err = enc.Encode(view.messages)
if err != nil {
return err
}
return nil
}
func (view *MessageView) LoadHistory(path string) (int, error) {
file, err := os.OpenFile(path, os.O_RDONLY, 0600)
if err != nil {
if os.IsNotExist(err) {
return 0, nil
}
return -1, err
}
defer file.Close()
dec := gob.NewDecoder(file)
err = dec.Decode(&view.messages)
if err != nil {
return -1, err
}
for _, message := range view.messages {
view.updateWidestSender(message.Sender)
}
return len(view.messages), nil
}
func (view *MessageView) updateWidestSender(sender string) {
if len(sender) > view.widestSender {
view.widestSender = len(sender)
@ -103,8 +144,12 @@ func (view *MessageView) UpdateMessageID(message *types.Message, newID string) {
}
func (view *MessageView) AddMessage(message *types.Message, direction MessageDirection) {
if message == nil {
return
}
msg, messageExists := view.messageIDs[message.ID]
if messageExists {
if msg != nil && messageExists {
message.CopyTo(msg)
direction = IgnoreMessage
}
@ -117,7 +162,7 @@ func (view *MessageView) AddMessage(message *types.Message, direction MessageDir
if direction == AppendMessage {
if view.ScrollOffset > 0 {
view.ScrollOffset += len(message.Buffer)
view.ScrollOffset += message.Height()
}
view.messages = append(view.messages, message)
view.appendBuffer(message)
@ -137,8 +182,8 @@ func (view *MessageView) appendBuffer(message *types.Message) {
}
}
view.textBuffer = append(view.textBuffer, message.Buffer...)
for range message.Buffer {
view.textBuffer = append(view.textBuffer, message.Buffer()...)
for range message.Buffer() {
view.metaBuffer = append(view.metaBuffer, message)
}
view.prevMsgCount++

View File

@ -18,6 +18,7 @@ package widget
import (
"fmt"
"path/filepath"
"strings"
"time"
@ -67,6 +68,18 @@ func NewRoomView(room *rooms.Room) *RoomView {
return view
}
func (view *RoomView) logPath(dir string) string {
return filepath.Join(dir, fmt.Sprintf("%s.gmxlog", view.Room.ID))
}
func (view *RoomView) SaveHistory(dir string) error {
return view.MessageView().SaveHistory(view.logPath(dir))
}
func (view *RoomView) LoadHistory(dir string) (int, error) {
return view.MessageView().LoadHistory(view.logPath(dir))
}
func (view *RoomView) SetTabCompleteFunc(fn func(room *RoomView, text string, cursorOffset int) string) *RoomView {
view.input.SetTabCompleteFunc(func(text string, cursorOffset int) string {
return fn(view, text, cursorOffset)