aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTulir Asokan <tulir@maunium.net>2020-02-19 01:14:02 +0200
committerTulir Asokan <tulir@maunium.net>2020-02-19 01:14:02 +0200
commitd02abd079fe58bae467672dc7d2a140f9f07bb85 (patch)
tree7972380c8aad12a3571aee7065ba450433c260dc
parentb4e27723d7ad6287d34f4cfc1f5a15b0074b59d1 (diff)
Add support for editing messages
-rw-r--r--go.mod4
-rw-r--r--go.sum4
-rw-r--r--interface/matrix.go2
-rw-r--r--matrix/event/event.go8
-rw-r--r--matrix/matrix.go21
-rw-r--r--ui/messages/base.go5
-rw-r--r--ui/messages/parser.go1
-rw-r--r--ui/room-view.go75
8 files changed, 108 insertions, 12 deletions
diff --git a/go.mod b/go.mod
index da9478b..9c51bcc 100644
--- a/go.mod
+++ b/go.mod
@@ -19,7 +19,7 @@ require (
golang.org/x/net v0.0.0-20200202094626-16171245cfb2
gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2
gopkg.in/yaml.v2 v2.2.8
- maunium.net/go/mautrix v0.1.0-alpha.3.0.20200218191514-cb8e637f1c62
- maunium.net/go/mauview v0.0.0-20200218183549-88ecb1321176
+ maunium.net/go/mautrix v0.1.0-alpha.3.0.20200218231230-3f49fda72ac9
+ maunium.net/go/mauview v0.0.0-20200218231215-04d01c601d5b
maunium.net/go/tcell v1.1.2-0.20200218183045-87c4a25c5b09
)
diff --git a/go.sum b/go.sum
index 4a235af..1a6e7ff 100644
--- a/go.sum
+++ b/go.sum
@@ -72,7 +72,11 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200218183645-fea33ed88d03 h1:0fvOe9KeB/JAkMAzJTmj6mg1P9xGPAgFhJcCSxNe1Rk=
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200218183645-fea33ed88d03/go.mod h1:g10T1fh2Q2HkJWycVs93eBXdWpqD67f1YVQhNxdIDr4=
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200218191514-cb8e637f1c62/go.mod h1:g10T1fh2Q2HkJWycVs93eBXdWpqD67f1YVQhNxdIDr4=
+maunium.net/go/mautrix v0.1.0-alpha.3.0.20200218231230-3f49fda72ac9 h1:emsSg9ZDiSqI2RrxU3+JddoF4rxshpNn71NNHcy3HUI=
+maunium.net/go/mautrix v0.1.0-alpha.3.0.20200218231230-3f49fda72ac9/go.mod h1:g10T1fh2Q2HkJWycVs93eBXdWpqD67f1YVQhNxdIDr4=
maunium.net/go/mauview v0.0.0-20200218183549-88ecb1321176 h1:KoTm7ASEzFIZ1SvPWuWYzpkeA+wiR1fuUu4l7TCHcE0=
maunium.net/go/mauview v0.0.0-20200218183549-88ecb1321176/go.mod h1:jwg3Ow7akzsCX3q38pZAfmEC5gGN8gXwMyyjy/yZVMg=
+maunium.net/go/mauview v0.0.0-20200218231215-04d01c601d5b h1:Bfov5IkJQpkqDexiFioHIZpx4XL7AILDA1GwLVdqtBw=
+maunium.net/go/mauview v0.0.0-20200218231215-04d01c601d5b/go.mod h1:jwg3Ow7akzsCX3q38pZAfmEC5gGN8gXwMyyjy/yZVMg=
maunium.net/go/tcell v1.1.2-0.20200218183045-87c4a25c5b09 h1:hu+R+0nodoZPS19WGyYiw/d63+/NQS/R3Duw3d9HqAU=
maunium.net/go/tcell v1.1.2-0.20200218183045-87c4a25c5b09/go.mod h1:Ru7KmI5AU7xHUx6hGltgJvknrS+8jlGGMKK15pZuc9k=
diff --git a/interface/matrix.go b/interface/matrix.go
index 424273b..af20509 100644
--- a/interface/matrix.go
+++ b/interface/matrix.go
@@ -35,7 +35,7 @@ type MatrixContainer interface {
Logout()
SendPreferencesToMatrix()
- PrepareMarkdownMessage(roomID string, msgtype mautrix.MessageType, message string) *event.Event
+ PrepareMarkdownMessage(roomID string, msgtype mautrix.MessageType, message string, edit *event.Event) *event.Event
SendEvent(evt *event.Event) (string, error)
SendTyping(roomID string, typing bool)
MarkRead(roomID, eventID string)
diff --git a/matrix/event/event.go b/matrix/event/event.go
index 143d35d..8506c9c 100644
--- a/matrix/event/event.go
+++ b/matrix/event/event.go
@@ -25,6 +25,14 @@ type Event struct {
Gomuks GomuksContent `json:"-"`
}
+func (evt *Event) SomewhatDangerousCopy() *Event {
+ base := *evt.Event
+ return &Event{
+ Event: &base,
+ Gomuks: evt.Gomuks,
+ }
+}
+
func Wrap(event *mautrix.Event) *Event {
return &Event{Event: event}
}
diff --git a/matrix/matrix.go b/matrix/matrix.go
index f77a257..c33a749 100644
--- a/matrix/matrix.go
+++ b/matrix/matrix.go
@@ -218,7 +218,7 @@ func (c *Container) SingleSignOn() error {
if err != nil {
return err
}
- err = <- errChan
+ err = <-errChan
return err
}
@@ -690,7 +690,7 @@ func (c *Container) MarkRead(roomID, eventID string) {
var mentionRegex = regexp.MustCompile("\\[(.+?)]\\(https://matrix.to/#/@.+?:.+?\\)")
var roomRegex = regexp.MustCompile("\\[.+?]\\(https://matrix.to/#/(#.+?:[^/]+?)\\)")
-func (c *Container) PrepareMarkdownMessage(roomID string, msgtype mautrix.MessageType, text string) *event.Event {
+func (c *Container) PrepareMarkdownMessage(roomID string, msgtype mautrix.MessageType, text string, edit *event.Event) *event.Event {
content := format.RenderMarkdown(text)
content.MsgType = msgtype
@@ -698,6 +698,19 @@ func (c *Container) PrepareMarkdownMessage(roomID string, msgtype mautrix.Messag
content.Body = mentionRegex.ReplaceAllString(content.Body, "$1")
content.Body = roomRegex.ReplaceAllString(content.Body, "$1")
+ if edit != nil {
+ contentCopy := content
+ content.NewContent = &contentCopy
+ content.Body = "* " + content.Body
+ if len(content.FormattedBody) > 0 {
+ content.FormattedBody = "* " + content.FormattedBody
+ }
+ content.RelatesTo = &mautrix.RelatesTo{
+ Type: mautrix.RelReplace,
+ EventID: edit.ID,
+ }
+ }
+
txnID := c.client.TxnID()
localEcho := event.Wrap(&mautrix.Event{
ID: txnID,
@@ -711,6 +724,10 @@ func (c *Container) PrepareMarkdownMessage(roomID string, msgtype mautrix.Messag
},
})
localEcho.Gomuks.OutgoingState = event.StateLocalEcho
+ if edit != nil {
+ localEcho.ID = edit.ID
+ localEcho.Gomuks.Edits = []*event.Event{localEcho}
+ }
return localEcho
}
diff --git a/ui/messages/base.go b/ui/messages/base.go
index 567e614..b54691e 100644
--- a/ui/messages/base.go
+++ b/ui/messages/base.go
@@ -17,7 +17,6 @@
package messages
import (
- "encoding/json"
"fmt"
"time"
@@ -55,7 +54,7 @@ type UIMessage struct {
IsHighlight bool
IsService bool
Edited bool
- Source json.RawMessage
+ Event *event.Event
ReplyTo *UIMessage
Renderer MessageRenderer
}
@@ -82,7 +81,7 @@ func newUIMessage(evt *event.Event, displayname string, renderer MessageRenderer
IsHighlight: false,
IsService: false,
Edited: len(evt.Gomuks.Edits) > 0,
- Source: evt.Content.VeryRaw,
+ Event: evt,
Renderer: renderer,
}
}
diff --git a/ui/messages/parser.go b/ui/messages/parser.go
index e1c0053..53d30e3 100644
--- a/ui/messages/parser.go
+++ b/ui/messages/parser.go
@@ -128,6 +128,7 @@ func ParseMessage(matrix ifc.MatrixContainer, room *rooms.Room, evt *event.Event
evt.Content.RemoveReplyFallback()
}
if len(evt.Gomuks.Edits) > 0 {
+ evt = evt.SomewhatDangerousCopy()
evt.Content = *evt.Gomuks.Edits[len(evt.Gomuks.Edits)-1].Content.NewContent
}
switch evt.Content.MsgType {
diff --git a/ui/room-view.go b/ui/room-view.go
index 31da3c6..27c42c8 100644
--- a/ui/room-view.go
+++ b/ui/room-view.go
@@ -67,6 +67,9 @@ type RoomView struct {
typing []string
+ editing *event.Event
+ editMoveText string
+
completions struct {
list []string
textCache string
@@ -107,7 +110,9 @@ func NewRoomView(parent *MainView, room *rooms.Room) *RoomView {
SetBackgroundColor(tcell.ColorDefault).
SetPlaceholder("Send a message...").
SetPlaceholderTextColor(tcell.ColorGray).
- SetTabCompleteFunc(view.InputTabComplete)
+ SetTabCompleteFunc(view.InputTabComplete).
+ SetPressKeyUpAtStartFunc(view.EditPrevious).
+ SetPressKeyDownAtEndFunc(view.EditNext)
view.topic.
SetTextColor(tcell.ColorWhite).
@@ -149,8 +154,12 @@ func (view *RoomView) Blur() {
func (view *RoomView) GetStatus() string {
var buf strings.Builder
+ if view.editing != nil {
+ buf.WriteString("Editing message - ")
+ }
+
if len(view.completions.list) > 0 {
- if view.completions.textCache != view.input.GetText() || view.completions.time.Add(10 * time.Second).Before(time.Now()) {
+ if view.completions.textCache != view.input.GetText() || view.completions.time.Add(10*time.Second).Before(time.Now()) {
view.completions.list = []string{}
} else {
buf.WriteString(strings.Join(view.completions.list, ", "))
@@ -354,6 +363,61 @@ func (view *RoomView) autocompleteEmoji(word string) (completions []string) {
return
}
+func (view *RoomView) SetEditing(evt *event.Event) {
+ if evt == nil {
+ view.editing = nil
+ view.SetInputText(view.editMoveText)
+ view.editMoveText = ""
+ } else {
+ if view.editing == nil {
+ view.editMoveText = view.GetInputText()
+ }
+ view.editing = evt
+ view.SetInputText(view.editing.Content.Body)
+ }
+ view.status.SetText(view.GetStatus())
+}
+
+func (view *RoomView) EditNext() {
+ if view.editing == nil {
+ return
+ }
+ var foundEvent *event.Event
+ currentFound := view.editing == nil
+ self := view.parent.matrix.Client().UserID
+ for _, msg := range view.MessageView().messages {
+ if currentFound {
+ if msg.SenderID == self {
+ foundEvent = msg.Event
+ break
+ }
+ } else if msg.EventID == view.editing.ID {
+ currentFound = true
+ }
+ }
+ view.SetEditing(foundEvent)
+}
+
+func (view *RoomView) EditPrevious() {
+ var foundEvent *event.Event
+ currentFound := view.editing == nil
+ self := view.parent.matrix.Client().UserID
+ msgs := view.MessageView().messages
+ for i := len(msgs) - 1; i >= 0; i-- {
+ if currentFound {
+ if msgs[i].SenderID == self {
+ foundEvent = msgs[i].Event
+ break
+ }
+ } else if msgs[i].EventID == view.editing.ID {
+ currentFound = true
+ }
+ }
+ if foundEvent != nil {
+ view.SetEditing(foundEvent)
+ }
+}
+
func (view *RoomView) InputTabComplete(text string, cursorOffset int) {
debug.Print("Tab completing", cursorOffset, text)
str := runewidth.Truncate(text, cursorOffset, "")
@@ -396,11 +460,12 @@ func (view *RoomView) InputTabComplete(text string, cursorOffset int) {
func (view *RoomView) InputSubmit(text string) {
if len(text) == 0 {
return
- } else if cmd := view.parent.cmdProcessor.ParseCommand(view, text); cmd != nil {
+ } else if cmd := view.parent.cmdProcessor.ParseCommand(view, text); view.editing == nil && cmd != nil {
go view.parent.cmdProcessor.HandleCommand(cmd)
} else {
go view.SendMessage(mautrix.MsgText, text)
}
+ view.editMoveText = ""
view.SetInputText("")
}
@@ -410,9 +475,11 @@ func (view *RoomView) SendMessage(msgtype mautrix.MessageType, text string) {
if !view.config.Preferences.DisableEmojis {
text = emoji.Sprint(text)
}
- evt := view.parent.matrix.PrepareMarkdownMessage(view.Room.ID, msgtype, text)
+ evt := view.parent.matrix.PrepareMarkdownMessage(view.Room.ID, msgtype, text, view.editing)
msg := view.parseEvent(evt)
view.content.AddMessage(msg, AppendMessage)
+ view.editing = nil
+ view.status.SetText(view.GetStatus())
eventID, err := view.parent.matrix.SendEvent(evt)
if err != nil {
msg.State = event.StateSendFail