Add support for editing messages
This commit is contained in:
parent
b4e27723d7
commit
d02abd079f
4
go.mod
4
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
|
||||
)
|
||||
|
4
go.sum
4
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=
|
||||
|
@ -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)
|
||||
|
@ -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}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user