Merge pull request #18 from tulir/ui-refactor

Refactor UI to use interfaces and add advanced message rendering
This commit is contained in:
Tulir Asokan
2018-04-14 18:09:02 +03:00
committed by GitHub
51 changed files with 3027 additions and 975 deletions

View File

@ -17,18 +17,26 @@
package matrix
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"os"
"path"
"path/filepath"
"regexp"
"strings"
"time"
"maunium.net/go/gomatrix"
"maunium.net/go/gomuks/config"
"maunium.net/go/gomuks/debug"
"maunium.net/go/gomuks/interface"
"maunium.net/go/gomuks/matrix/pushrules"
"maunium.net/go/gomuks/matrix/rooms"
"maunium.net/go/gomuks/ui/debug"
"maunium.net/go/gomuks/ui/widget"
)
// Container is a wrapper for a gomatrix Client and some other stuff.
@ -221,13 +229,13 @@ func (c *Container) HandleMessage(evt *gomatrix.Event) {
return
}
message := mainView.ProcessMessageEvent(roomView, evt)
message := mainView.ParseEvent(roomView, evt)
if message != nil {
if c.syncer.FirstSyncDone {
pushRules := c.PushRules().GetActions(roomView.Room, evt).Should()
mainView.NotifyMessage(roomView.Room, message, pushRules)
pushRules := c.PushRules().GetActions(roomView.MxRoom(), evt).Should()
mainView.NotifyMessage(roomView.MxRoom(), message, pushRules)
}
roomView.AddMessage(message, widget.AppendMessage)
roomView.AddMessage(message, ifc.AppendMessage)
c.ui.Render()
}
}
@ -255,8 +263,7 @@ func (c *Container) processOwnMembershipChange(evt *gomatrix.Event) {
if evt.Unsigned.PrevContent != nil {
prevMembership, _ = evt.Unsigned.PrevContent["membership"].(string)
}
const Hour = 1 * 60 * 60 * 1000
if membership == prevMembership || evt.Unsigned.Age > Hour {
if membership == prevMembership {
return
}
switch membership {
@ -279,18 +286,18 @@ func (c *Container) HandleMembership(evt *gomatrix.Event) {
return
}
message := mainView.ProcessMembershipEvent(roomView, evt)
message := mainView.ParseEvent(roomView, evt)
if message != nil {
// TODO this shouldn't be necessary
roomView.Room.UpdateState(evt)
roomView.MxRoom().UpdateState(evt)
// TODO This should probably also be in a different place
roomView.UpdateUserList()
if c.syncer.FirstSyncDone {
pushRules := c.PushRules().GetActions(roomView.Room, evt).Should()
mainView.NotifyMessage(roomView.Room, message, pushRules)
pushRules := c.PushRules().GetActions(roomView.MxRoom(), evt).Should()
mainView.NotifyMessage(roomView.MxRoom(), message, pushRules)
}
roomView.AddMessage(message, widget.AppendMessage)
roomView.AddMessage(message, ifc.AppendMessage)
c.ui.Render()
}
}
@ -403,3 +410,55 @@ func (c *Container) GetRoom(roomID string) *rooms.Room {
}
return room
}
var mxcRegex = regexp.MustCompile("mxc://(.+)/(.+)")
func (c *Container) Download(mxcURL string) (data []byte, hs, id string, err error) {
parts := mxcRegex.FindStringSubmatch(mxcURL)
if parts == nil || len(parts) != 3 {
err = fmt.Errorf("invalid matrix content URL")
return
}
hs = parts[1]
id = parts[2]
cacheFile := c.GetCachePath(hs, id)
if _, err = os.Stat(cacheFile); err != nil {
data, err = ioutil.ReadFile(cacheFile)
if err == nil {
return
}
}
dlURL, _ := url.Parse(c.client.HomeserverURL.String())
dlURL.Path = path.Join(dlURL.Path, "/_matrix/media/v1/download", hs, id)
var resp *http.Response
resp, err = c.client.Client.Get(dlURL.String())
if err != nil {
return
}
defer resp.Body.Close()
var buf bytes.Buffer
_, err = io.Copy(&buf, resp.Body)
if err != nil {
return
}
data = buf.Bytes()
err = ioutil.WriteFile(cacheFile, data, 0600)
return
}
func (c *Container) GetCachePath(homeserver, fileID string) string {
dir := filepath.Join(c.config.MediaDir, homeserver)
err := os.MkdirAll(dir, 0700)
if err != nil {
return ""
}
return filepath.Join(dir, fileID)
}

View File

@ -94,11 +94,7 @@ func (room *Room) UpdateState(event *gomatrix.Event) {
room.memberCache = nil
room.firstMemberCache = ""
fallthrough
case "m.room.name":
fallthrough
case "m.room.canonical_alias":
fallthrough
case "m.room.alias":
case "m.room.name", "m.room.canonical_alias", "m.room.alias":
room.nameCache = ""
case "m.room.topic":
room.topicCache = ""