Add support for replying and reacting to messages
This commit is contained in:
parent
699d0ea4e0
commit
9d132d328b
@ -71,6 +71,9 @@ func Foo() {
|
|||||||
* `/notice <text>` - Send a notice (generally used for bot messages).
|
* `/notice <text>` - Send a notice (generally used for bot messages).
|
||||||
* `/rainbow <text>` - Send rainbow text (markdown not supported).
|
* `/rainbow <text>` - Send rainbow text (markdown not supported).
|
||||||
* `/rainbowme <text>` - Send rainbow text in an emote.
|
* `/rainbowme <text>` - Send rainbow text in an emote.
|
||||||
|
* `/reply [text]` - Reply to the selected message. If text is not specified, the next message will be used.
|
||||||
|
* `/react <reaction>` - React to the selected message.
|
||||||
|
* `/redact` - Redact the selected message.
|
||||||
|
|
||||||
#### Rooms
|
#### Rooms
|
||||||
##### Creating
|
##### Creating
|
||||||
|
2
go.mod
2
go.mod
@ -19,7 +19,7 @@ require (
|
|||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2
|
golang.org/x/net v0.0.0-20200202094626-16171245cfb2
|
||||||
gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2
|
gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2
|
||||||
gopkg.in/yaml.v2 v2.2.8
|
gopkg.in/yaml.v2 v2.2.8
|
||||||
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200221234248-8a868bce2854
|
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200229222711-57beb97fdccb
|
||||||
maunium.net/go/mauview v0.0.0-20200220222850-39f1414676d9
|
maunium.net/go/mauview v0.0.0-20200220222850-39f1414676d9
|
||||||
maunium.net/go/tcell v1.1.2-0.20200218183045-87c4a25c5b09
|
maunium.net/go/tcell v1.1.2-0.20200218183045-87c4a25c5b09
|
||||||
)
|
)
|
||||||
|
2
go.sum
2
go.sum
@ -86,6 +86,8 @@ maunium.net/go/mautrix v0.1.0-alpha.3.0.20200221220303-b441ba9359cf h1:ojEsISqRL
|
|||||||
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200221220303-b441ba9359cf/go.mod h1:g10T1fh2Q2HkJWycVs93eBXdWpqD67f1YVQhNxdIDr4=
|
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200221220303-b441ba9359cf/go.mod h1:g10T1fh2Q2HkJWycVs93eBXdWpqD67f1YVQhNxdIDr4=
|
||||||
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200221234248-8a868bce2854 h1:NKj52IqLkfscNMSbSVepaXHM6M/x3iNe/iWSAcmAilo=
|
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200221234248-8a868bce2854 h1:NKj52IqLkfscNMSbSVepaXHM6M/x3iNe/iWSAcmAilo=
|
||||||
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200221234248-8a868bce2854/go.mod h1:g10T1fh2Q2HkJWycVs93eBXdWpqD67f1YVQhNxdIDr4=
|
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200221234248-8a868bce2854/go.mod h1:g10T1fh2Q2HkJWycVs93eBXdWpqD67f1YVQhNxdIDr4=
|
||||||
|
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200229222711-57beb97fdccb h1:b9cMiQ85HtNhV/gItnjdEFC7nQTWmvnALiHQiYqrJAU=
|
||||||
|
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200229222711-57beb97fdccb/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 h1:KoTm7ASEzFIZ1SvPWuWYzpkeA+wiR1fuUu4l7TCHcE0=
|
||||||
maunium.net/go/mauview v0.0.0-20200218183549-88ecb1321176/go.mod h1:jwg3Ow7akzsCX3q38pZAfmEC5gGN8gXwMyyjy/yZVMg=
|
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 h1:Bfov5IkJQpkqDexiFioHIZpx4XL7AILDA1GwLVdqtBw=
|
||||||
|
@ -23,6 +23,11 @@ import (
|
|||||||
"maunium.net/go/gomuks/matrix/rooms"
|
"maunium.net/go/gomuks/matrix/rooms"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Relation struct {
|
||||||
|
Type mautrix.RelationType
|
||||||
|
Event *event.Event
|
||||||
|
}
|
||||||
|
|
||||||
type MatrixContainer interface {
|
type MatrixContainer interface {
|
||||||
Client() *mautrix.Client
|
Client() *mautrix.Client
|
||||||
InitClient() error
|
InitClient() error
|
||||||
@ -35,7 +40,7 @@ type MatrixContainer interface {
|
|||||||
Logout()
|
Logout()
|
||||||
|
|
||||||
SendPreferencesToMatrix()
|
SendPreferencesToMatrix()
|
||||||
PrepareMarkdownMessage(roomID string, msgtype mautrix.MessageType, message string, edit *event.Event) *event.Event
|
PrepareMarkdownMessage(roomID string, msgtype mautrix.MessageType, message string, relation *Relation) *event.Event
|
||||||
SendEvent(evt *event.Event) (string, error)
|
SendEvent(evt *event.Event) (string, error)
|
||||||
SendTyping(roomID string, typing bool)
|
SendTyping(roomID string, typing bool)
|
||||||
MarkRead(roomID, eventID string)
|
MarkRead(roomID, eventID string)
|
||||||
|
@ -732,7 +732,7 @@ func (c *Container) MarkRead(roomID, eventID string) {
|
|||||||
var mentionRegex = regexp.MustCompile("\\[(.+?)]\\(https://matrix.to/#/@.+?:.+?\\)")
|
var mentionRegex = regexp.MustCompile("\\[(.+?)]\\(https://matrix.to/#/@.+?:.+?\\)")
|
||||||
var roomRegex = regexp.MustCompile("\\[.+?]\\(https://matrix.to/#/(#.+?:[^/]+?)\\)")
|
var roomRegex = regexp.MustCompile("\\[.+?]\\(https://matrix.to/#/(#.+?:[^/]+?)\\)")
|
||||||
|
|
||||||
func (c *Container) PrepareMarkdownMessage(roomID string, msgtype mautrix.MessageType, text string, edit *event.Event) *event.Event {
|
func (c *Container) PrepareMarkdownMessage(roomID string, msgtype mautrix.MessageType, text string, rel *ifc.Relation) *event.Event {
|
||||||
content := format.RenderMarkdown(text)
|
content := format.RenderMarkdown(text)
|
||||||
content.MsgType = msgtype
|
content.MsgType = msgtype
|
||||||
|
|
||||||
@ -740,7 +740,7 @@ func (c *Container) PrepareMarkdownMessage(roomID string, msgtype mautrix.Messag
|
|||||||
content.Body = mentionRegex.ReplaceAllString(content.Body, "$1")
|
content.Body = mentionRegex.ReplaceAllString(content.Body, "$1")
|
||||||
content.Body = roomRegex.ReplaceAllString(content.Body, "$1")
|
content.Body = roomRegex.ReplaceAllString(content.Body, "$1")
|
||||||
|
|
||||||
if edit != nil {
|
if rel != nil && rel.Type == mautrix.RelReplace {
|
||||||
contentCopy := content
|
contentCopy := content
|
||||||
content.NewContent = &contentCopy
|
content.NewContent = &contentCopy
|
||||||
content.Body = "* " + content.Body
|
content.Body = "* " + content.Body
|
||||||
@ -749,8 +749,10 @@ func (c *Container) PrepareMarkdownMessage(roomID string, msgtype mautrix.Messag
|
|||||||
}
|
}
|
||||||
content.RelatesTo = &mautrix.RelatesTo{
|
content.RelatesTo = &mautrix.RelatesTo{
|
||||||
Type: mautrix.RelReplace,
|
Type: mautrix.RelReplace,
|
||||||
EventID: edit.ID,
|
EventID: rel.Event.ID,
|
||||||
}
|
}
|
||||||
|
} else if rel != nil && rel.Type == mautrix.RelReference {
|
||||||
|
content.SetReply(rel.Event.Event)
|
||||||
}
|
}
|
||||||
|
|
||||||
txnID := c.client.TxnID()
|
txnID := c.client.TxnID()
|
||||||
@ -766,8 +768,8 @@ func (c *Container) PrepareMarkdownMessage(roomID string, msgtype mautrix.Messag
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
localEcho.Gomuks.OutgoingState = event.StateLocalEcho
|
localEcho.Gomuks.OutgoingState = event.StateLocalEcho
|
||||||
if edit != nil {
|
if rel != nil && rel.Type == mautrix.RelReplace {
|
||||||
localEcho.ID = edit.ID
|
localEcho.ID = rel.Event.ID
|
||||||
localEcho.Gomuks.Edits = []*event.Event{localEcho}
|
localEcho.Gomuks.Edits = []*event.Event{localEcho}
|
||||||
}
|
}
|
||||||
return localEcho
|
return localEcho
|
||||||
|
@ -87,6 +87,11 @@ func NewCommandProcessor(parent *MainView) *CommandProcessor {
|
|||||||
"createroom": {"create"},
|
"createroom": {"create"},
|
||||||
"dm": {"pm"},
|
"dm": {"pm"},
|
||||||
"query": {"pm"},
|
"query": {"pm"},
|
||||||
|
"r": {"reply"},
|
||||||
|
"delete": {"redact"},
|
||||||
|
"remove": {"redact"},
|
||||||
|
"rm": {"redact"},
|
||||||
|
"del": {"redact"},
|
||||||
},
|
},
|
||||||
commands: map[string]CommandHandler{
|
commands: map[string]CommandHandler{
|
||||||
"unknown-command": cmdUnknownCommand,
|
"unknown-command": cmdUnknownCommand,
|
||||||
@ -107,6 +112,9 @@ func NewCommandProcessor(parent *MainView) *CommandProcessor {
|
|||||||
"logout": cmdLogout,
|
"logout": cmdLogout,
|
||||||
"accept": cmdAccept,
|
"accept": cmdAccept,
|
||||||
"reject": cmdReject,
|
"reject": cmdReject,
|
||||||
|
"reply": cmdReply,
|
||||||
|
"redact": cmdRedact,
|
||||||
|
"react": cmdReact,
|
||||||
"sendevent": cmdSendEvent,
|
"sendevent": cmdSendEvent,
|
||||||
"msendevent": cmdMSendEvent,
|
"msendevent": cmdMSendEvent,
|
||||||
"setstate": cmdSetState,
|
"setstate": cmdSetState,
|
||||||
|
@ -41,7 +41,6 @@ import (
|
|||||||
func cmdMe(cmd *Command) {
|
func cmdMe(cmd *Command) {
|
||||||
text := strings.Join(cmd.Args, " ")
|
text := strings.Join(cmd.Args, " ")
|
||||||
go cmd.Room.SendMessage(mautrix.MsgEmote, text)
|
go cmd.Room.SendMessage(mautrix.MsgEmote, text)
|
||||||
cmd.UI.Render()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GradientTable from https://github.com/lucasb-eyer/go-colorful/blob/master/doc/gradientgen/gradientgen.go
|
// GradientTable from https://github.com/lucasb-eyer/go-colorful/blob/master/doc/gradientgen/gradientgen.go
|
||||||
@ -87,10 +86,9 @@ func makeRainbow(cmd *Command, msgtype mautrix.MessageType) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
color := rainbow.GetInterpolatedColorFor(float64(i) / float64(len(text))).Hex()
|
color := rainbow.GetInterpolatedColorFor(float64(i) / float64(len(text))).Hex()
|
||||||
_, _ = fmt.Fprintf(&html, "<font color=\"%s\">%c</font>", color, char)
|
_, _ = fmt.Fprintf(&html, "<font data-mx-color=\"%[1]s\" color=\"%[1]s\">%[2]c</font>", color, char)
|
||||||
}
|
}
|
||||||
go cmd.Room.SendMessage(msgtype, html.String())
|
go cmd.Room.SendMessage(msgtype, html.String())
|
||||||
cmd.UI.Render()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func cmdRainbow(cmd *Command) {
|
func cmdRainbow(cmd *Command) {
|
||||||
@ -103,7 +101,6 @@ func cmdRainbowMe(cmd *Command) {
|
|||||||
|
|
||||||
func cmdNotice(cmd *Command) {
|
func cmdNotice(cmd *Command) {
|
||||||
go cmd.Room.SendMessage(mautrix.MsgNotice, strings.Join(cmd.Args, " "))
|
go cmd.Room.SendMessage(mautrix.MsgNotice, strings.Join(cmd.Args, " "))
|
||||||
cmd.UI.Render()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func cmdAccept(cmd *Command) {
|
func cmdAccept(cmd *Command) {
|
||||||
@ -141,6 +138,42 @@ func cmdID(cmd *Command) {
|
|||||||
cmd.Reply("The internal ID of this room is %s", cmd.Room.MxRoom().ID)
|
cmd.Reply("The internal ID of this room is %s", cmd.Room.MxRoom().ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SelectReason string
|
||||||
|
|
||||||
|
const (
|
||||||
|
SelectReply SelectReason = "reply to"
|
||||||
|
SelectReact = "react to"
|
||||||
|
SelectRedact = "redact"
|
||||||
|
)
|
||||||
|
|
||||||
|
func cmdReply(cmd *Command) {
|
||||||
|
cmd.Room.selecting = true
|
||||||
|
cmd.Room.selectReason = SelectReply
|
||||||
|
cmd.Room.selectContent = strings.Join(cmd.Args, " ")
|
||||||
|
cmd.Room.OnSelect(cmd.Room.MessageView().selected)
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdRedact(cmd *Command) {
|
||||||
|
cmd.Reply("Not yet implemented 3:")
|
||||||
|
|
||||||
|
// This needs to be implemented in RoomView's OnSelect method
|
||||||
|
//cmd.Room.selecting = true
|
||||||
|
//cmd.Room.selectReason = SelectRedact
|
||||||
|
//cmd.Room.OnSelect(cmd.Room.MessageView().selected)
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdReact(cmd *Command) {
|
||||||
|
if len(cmd.Args) == 0 {
|
||||||
|
cmd.Reply("Usage: /react <reaction>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Room.selecting = true
|
||||||
|
cmd.Room.selectReason = SelectReact
|
||||||
|
cmd.Room.selectContent = strings.Join(cmd.Args, " ")
|
||||||
|
cmd.Room.OnSelect(cmd.Room.MessageView().selected)
|
||||||
|
}
|
||||||
|
|
||||||
func cmdTags(cmd *Command) {
|
func cmdTags(cmd *Command) {
|
||||||
tags := cmd.Room.MxRoom().RawTags
|
tags := cmd.Room.MxRoom().RawTags
|
||||||
if len(cmd.Args) > 0 && cmd.Args[0] == "--internal" {
|
if len(cmd.Args) > 0 && cmd.Args[0] == "--internal" {
|
||||||
@ -298,6 +331,9 @@ Things: rooms, users, baremessages, images, typingnotif
|
|||||||
/notice <message> - Send a notice (generally used for bot messages).
|
/notice <message> - Send a notice (generally used for bot messages).
|
||||||
/rainbow <message> - Send rainbow text (markdown not supported).
|
/rainbow <message> - Send rainbow text (markdown not supported).
|
||||||
/rainbowme <message> - Send rainbow text in an emote.
|
/rainbowme <message> - Send rainbow text in an emote.
|
||||||
|
/reply [text] - Reply to the selected message.
|
||||||
|
/react <reaction> - React to the selected message.
|
||||||
|
/redact - Redact the selected message.
|
||||||
|
|
||||||
# Rooms
|
# Rooms
|
||||||
/pm <user id> <...> - Create a private chat with the given user(s).
|
/pm <user id> <...> - Create a private chat with the given user(s).
|
||||||
|
@ -338,7 +338,11 @@ func (view *MessageView) SetSelected(message *messages.UIMessage) {
|
|||||||
if view.selected != nil {
|
if view.selected != nil {
|
||||||
view.selected.IsSelected = false
|
view.selected.IsSelected = false
|
||||||
}
|
}
|
||||||
|
if message != nil && (view.selected == message || message.IsService) {
|
||||||
|
view.selected = nil
|
||||||
|
} else {
|
||||||
view.selected = message
|
view.selected = message
|
||||||
|
}
|
||||||
if view.selected != nil {
|
if view.selected != nil {
|
||||||
view.selected.IsSelected = true
|
view.selected.IsSelected = true
|
||||||
}
|
}
|
||||||
@ -349,11 +353,9 @@ func (view *MessageView) handleMessageClick(message *messages.UIMessage, mod tce
|
|||||||
open.Open(msg.Path())
|
open.Open(msg.Path())
|
||||||
// No need to re-render
|
// No need to re-render
|
||||||
return false
|
return false
|
||||||
} else if message.IsService {
|
|
||||||
// Can't select service messages
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
view.SetSelected(message)
|
view.SetSelected(message)
|
||||||
|
view.parent.OnSelect(view.selected)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +129,6 @@ func ParseMessage(matrix ifc.MatrixContainer, room *rooms.Room, evt *event.Event
|
|||||||
evt.Content.RemoveReplyFallback()
|
evt.Content.RemoveReplyFallback()
|
||||||
}
|
}
|
||||||
if len(evt.Gomuks.Edits) > 0 {
|
if len(evt.Gomuks.Edits) > 0 {
|
||||||
evt = evt.SomewhatDangerousCopy()
|
|
||||||
evt.Content = *evt.Gomuks.Edits[len(evt.Gomuks.Edits)-1].Content.NewContent
|
evt.Content = *evt.Gomuks.Edits[len(evt.Gomuks.Edits)-1].Content.NewContent
|
||||||
}
|
}
|
||||||
switch evt.Content.MsgType {
|
switch evt.Content.MsgType {
|
||||||
|
@ -67,6 +67,12 @@ type RoomView struct {
|
|||||||
|
|
||||||
typing []string
|
typing []string
|
||||||
|
|
||||||
|
selecting bool
|
||||||
|
selectReason SelectReason
|
||||||
|
selectContent string
|
||||||
|
|
||||||
|
replying *event.Event
|
||||||
|
|
||||||
editing *event.Event
|
editing *event.Event
|
||||||
editMoveText string
|
editMoveText string
|
||||||
|
|
||||||
@ -148,14 +154,43 @@ func (view *RoomView) Focus() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (view *RoomView) Blur() {
|
func (view *RoomView) Blur() {
|
||||||
|
view.MessageView().SetSelected(nil)
|
||||||
view.input.Blur()
|
view.input.Blur()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (view *RoomView) OnSelect(message *messages.UIMessage) {
|
||||||
|
if !view.selecting || message == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch view.selectReason {
|
||||||
|
case SelectReply:
|
||||||
|
view.replying = message.Event
|
||||||
|
if len(view.selectContent) > 0 {
|
||||||
|
go view.SendMessage(mautrix.MsgText, view.selectContent)
|
||||||
|
}
|
||||||
|
case SelectReact:
|
||||||
|
go view.SendReaction(message.EventID, view.selectContent)
|
||||||
|
case SelectRedact:
|
||||||
|
// TODO redact
|
||||||
|
}
|
||||||
|
view.selecting = false
|
||||||
|
view.selectContent = ""
|
||||||
|
view.MessageView().SetSelected(nil)
|
||||||
|
}
|
||||||
|
|
||||||
func (view *RoomView) GetStatus() string {
|
func (view *RoomView) GetStatus() string {
|
||||||
var buf strings.Builder
|
var buf strings.Builder
|
||||||
|
|
||||||
if view.editing != nil {
|
if view.editing != nil {
|
||||||
buf.WriteString("Editing message - ")
|
buf.WriteString("Editing message - ")
|
||||||
|
} else if view.replying != nil {
|
||||||
|
buf.WriteString("Replying to ")
|
||||||
|
buf.WriteString(view.replying.Sender)
|
||||||
|
buf.WriteString(" - ")
|
||||||
|
} else if view.selecting {
|
||||||
|
buf.WriteString("Selecting message to")
|
||||||
|
buf.WriteString(string(view.selectReason))
|
||||||
|
buf.WriteString(" - ")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(view.completions.list) > 0 {
|
if len(view.completions.list) > 0 {
|
||||||
@ -373,6 +408,8 @@ func (view *RoomView) SetEditing(evt *event.Event) {
|
|||||||
view.editMoveText = view.GetInputText()
|
view.editMoveText = view.GetInputText()
|
||||||
}
|
}
|
||||||
view.editing = evt
|
view.editing = evt
|
||||||
|
// replying should never be non-nil when SetEditing, but do this just to be safe
|
||||||
|
view.replying = nil
|
||||||
text := view.editing.Content.Body
|
text := view.editing.Content.Body
|
||||||
if view.editing.Content.MsgType == mautrix.MsgEmote {
|
if view.editing.Content.MsgType == mautrix.MsgEmote {
|
||||||
text = "/me " + text
|
text = "/me " + text
|
||||||
@ -393,7 +430,9 @@ func (view *RoomView) findMessageToEdit(forward bool) *event.Event {
|
|||||||
index = len(msgs) - i - 1
|
index = len(msgs) - i - 1
|
||||||
}
|
}
|
||||||
evt := msgs[index]
|
evt := msgs[index]
|
||||||
if currentFound {
|
if evt.EventID == "" || evt.EventID == evt.TxnID {
|
||||||
|
continue
|
||||||
|
} else if currentFound {
|
||||||
if evt.SenderID == self && evt.Event.Type == mautrix.EventMessage {
|
if evt.SenderID == self && evt.Event.Type == mautrix.EventMessage {
|
||||||
return evt.Event
|
return evt.Event
|
||||||
}
|
}
|
||||||
@ -413,6 +452,9 @@ func (view *RoomView) EditNext() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (view *RoomView) EditPrevious() {
|
func (view *RoomView) EditPrevious() {
|
||||||
|
if view.replying != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
foundEvent := view.findMessageToEdit(false)
|
foundEvent := view.findMessageToEdit(false)
|
||||||
if foundEvent != nil {
|
if foundEvent != nil {
|
||||||
view.SetEditing(foundEvent)
|
view.SetEditing(foundEvent)
|
||||||
@ -468,6 +510,35 @@ func (view *RoomView) InputSubmit(text string) {
|
|||||||
}
|
}
|
||||||
view.editMoveText = ""
|
view.editMoveText = ""
|
||||||
view.SetInputText("")
|
view.SetInputText("")
|
||||||
|
view.MessageView().SetSelected(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (view *RoomView) SendReaction(eventID string, reaction string) {
|
||||||
|
defer debug.Recover()
|
||||||
|
debug.Print("Reacting to", eventID, "in", view.Room.ID, "with", reaction)
|
||||||
|
eventID, err := view.parent.matrix.SendEvent(&event.Event{
|
||||||
|
Event: &mautrix.Event{
|
||||||
|
Type: mautrix.EventReaction,
|
||||||
|
RoomID: view.Room.ID,
|
||||||
|
Content: mautrix.Content{
|
||||||
|
RelatesTo: &mautrix.RelatesTo{
|
||||||
|
Type: mautrix.RelAnnotation,
|
||||||
|
EventID: eventID,
|
||||||
|
Key: reaction,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if httpErr, ok := err.(mautrix.HTTPError); ok {
|
||||||
|
err = httpErr
|
||||||
|
if respErr := httpErr.RespError; respErr != nil {
|
||||||
|
err = respErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
view.AddServiceMessage(fmt.Sprintf("Failed to send reaction: %v", err))
|
||||||
|
view.parent.parent.Render()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (view *RoomView) SendMessage(msgtype mautrix.MessageType, text string) {
|
func (view *RoomView) SendMessage(msgtype mautrix.MessageType, text string) {
|
||||||
@ -476,10 +547,23 @@ func (view *RoomView) SendMessage(msgtype mautrix.MessageType, text string) {
|
|||||||
if !view.config.Preferences.DisableEmojis {
|
if !view.config.Preferences.DisableEmojis {
|
||||||
text = emoji.Sprint(text)
|
text = emoji.Sprint(text)
|
||||||
}
|
}
|
||||||
evt := view.parent.matrix.PrepareMarkdownMessage(view.Room.ID, msgtype, text, view.editing)
|
var rel *ifc.Relation
|
||||||
msg := view.parseEvent(evt)
|
if view.editing != nil {
|
||||||
|
rel = &ifc.Relation{
|
||||||
|
Type: mautrix.RelReplace,
|
||||||
|
Event: view.editing,
|
||||||
|
}
|
||||||
|
} else if view.replying != nil {
|
||||||
|
rel = &ifc.Relation{
|
||||||
|
Type: mautrix.RelReference,
|
||||||
|
Event: view.replying,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
evt := view.parent.matrix.PrepareMarkdownMessage(view.Room.ID, msgtype, text, rel)
|
||||||
|
msg := view.parseEvent(evt.SomewhatDangerousCopy())
|
||||||
view.content.AddMessage(msg, AppendMessage)
|
view.content.AddMessage(msg, AppendMessage)
|
||||||
view.editing = nil
|
view.editing = nil
|
||||||
|
view.replying = nil
|
||||||
view.status.SetText(view.GetStatus())
|
view.status.SetText(view.GetStatus())
|
||||||
eventID, err := view.parent.matrix.SendEvent(evt)
|
eventID, err := view.parent.matrix.SendEvent(evt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user