Implement selecting message to reply/react to with keyboard

This commit is contained in:
Tulir Asokan 2020-03-01 17:11:56 +02:00
parent da4a2c670d
commit 3c21281ada
3 changed files with 92 additions and 35 deletions

View File

@ -147,19 +147,14 @@ const (
) )
func cmdReply(cmd *Command) { func cmdReply(cmd *Command) {
cmd.Room.selecting = true cmd.Room.StartSelecting(SelectReply, strings.Join(cmd.Args, " "))
cmd.Room.selectReason = SelectReply
cmd.Room.selectContent = strings.Join(cmd.Args, " ")
cmd.Room.OnSelect(cmd.Room.MessageView().selected)
} }
func cmdRedact(cmd *Command) { func cmdRedact(cmd *Command) {
cmd.Reply("Not yet implemented 3:") cmd.Reply("Not yet implemented 3:")
// This needs to be implemented in RoomView's OnSelect method // This needs to be implemented in RoomView's OnSelect method
//cmd.Room.selecting = true //cmd.Room.StartSelecting(SelectRedact, "")
//cmd.Room.selectReason = SelectRedact
//cmd.Room.OnSelect(cmd.Room.MessageView().selected)
} }
func cmdReact(cmd *Command) { func cmdReact(cmd *Command) {
@ -168,10 +163,7 @@ func cmdReact(cmd *Command) {
return return
} }
cmd.Room.selecting = true cmd.Room.StartSelecting(SelectReact, strings.Join(cmd.Args, " "))
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) {

View File

@ -85,6 +85,13 @@ type UIMessage struct {
Renderer MessageRenderer Renderer MessageRenderer
} }
func (msg *UIMessage) GetEvent() *event.Event {
if msg == nil {
return nil
}
return msg.Event
}
const DateFormat = "January _2, 2006" const DateFormat = "January _2, 2006"
const TimeFormat = "15:04:05" const TimeFormat = "15:04:05"
@ -314,9 +321,9 @@ func (msg *UIMessage) DrawReactions(screen mauview.Screen) {
} }
func (msg *UIMessage) Draw(screen mauview.Screen) { func (msg *UIMessage) Draw(screen mauview.Screen) {
screen = msg.DrawReply(screen) proxyScreen := msg.DrawReply(screen)
msg.Renderer.Draw(screen) msg.Renderer.Draw(proxyScreen)
msg.DrawReactions(screen) msg.DrawReactions(proxyScreen)
if msg.IsSelected { if msg.IsSelected {
w, h := screen.Size() w, h := screen.Size()
for x := 0; x < w; x++ { for x := 0; x < w; x++ {
@ -324,7 +331,7 @@ func (msg *UIMessage) Draw(screen mauview.Screen) {
mainc, combc, style, _ := screen.GetContent(x, y) mainc, combc, style, _ := screen.GetContent(x, y)
_, bg, _ := style.Decompose() _, bg, _ := style.Decompose()
if bg == tcell.ColorDefault { if bg == tcell.ColorDefault {
screen.SetContent(x, y, mainc, combc, style.Background(tcell.ColorLightSkyBlue)) screen.SetContent(x, y, mainc, combc, style.Background(tcell.ColorDarkGreen))
} }
} }
} }

View File

@ -154,10 +154,29 @@ func (view *RoomView) Focus() {
} }
func (view *RoomView) Blur() { func (view *RoomView) Blur() {
view.MessageView().SetSelected(nil) view.StopSelecting()
view.input.Blur() view.input.Blur()
} }
func (view *RoomView) StartSelecting(reason SelectReason, content string) {
view.selecting = true
view.selectReason = reason
view.selectContent = content
msgView := view.MessageView()
if msgView.selected != nil {
view.OnSelect(msgView.selected)
} else {
view.input.Blur()
view.SelectPrevious()
}
}
func (view *RoomView) StopSelecting() {
view.selecting = false
view.selectContent = ""
view.MessageView().SetSelected(nil)
}
func (view *RoomView) OnSelect(message *messages.UIMessage) { func (view *RoomView) OnSelect(message *messages.UIMessage) {
if !view.selecting || message == nil { if !view.selecting || message == nil {
return return
@ -176,6 +195,7 @@ func (view *RoomView) OnSelect(message *messages.UIMessage) {
view.selecting = false view.selecting = false
view.selectContent = "" view.selectContent = ""
view.MessageView().SetSelected(nil) view.MessageView().SetSelected(nil)
view.input.Focus()
} }
func (view *RoomView) GetStatus() string { func (view *RoomView) GetStatus() string {
@ -281,18 +301,33 @@ func (view *RoomView) Draw(screen mauview.Screen) {
} }
func (view *RoomView) ClearAllContext() { func (view *RoomView) ClearAllContext() {
view.MessageView().SetSelected(nil)
view.SetEditing(nil) view.SetEditing(nil)
view.StopSelecting()
view.replying = nil view.replying = nil
view.selecting = false view.input.Focus()
view.selectContent = ""
} }
func (view *RoomView) OnKeyEvent(event mauview.KeyEvent) bool { func (view *RoomView) OnKeyEvent(event mauview.KeyEvent) bool {
msgView := view.MessageView() msgView := view.MessageView()
if view.selecting {
switch event.Key() {
case tcell.KeyEscape:
view.ClearAllContext()
case tcell.KeyUp:
view.SelectPrevious()
case tcell.KeyDown:
view.SelectNext()
case tcell.KeyEnter:
view.OnSelect(msgView.selected)
default:
return false
}
return true
}
switch event.Key() { switch event.Key() {
case tcell.KeyEscape: case tcell.KeyEscape:
view.ClearAllContext() view.ClearAllContext()
return true
case tcell.KeyPgUp: case tcell.KeyPgUp:
if msgView.IsAtTop() { if msgView.IsAtTop() {
go view.parent.LoadHistory(view.Room.ID) go view.parent.LoadHistory(view.Room.ID)
@ -430,8 +465,8 @@ func (view *RoomView) SetEditing(evt *event.Event) {
view.input.SetCursorOffset(-1) view.input.SetCursorOffset(-1)
} }
func (view *RoomView) findMessageToEdit(forward bool) *event.Event { func (view *RoomView) findMessage(current *event.Event, ownMessage, forward bool) *messages.UIMessage {
currentFound := view.editing == nil currentFound := current == nil
self := view.parent.matrix.Client().UserID self := view.parent.matrix.Client().UserID
msgs := view.MessageView().messages msgs := view.MessageView().messages
for i := 0; i < len(msgs); i++ { for i := 0; i < len(msgs); i++ {
@ -440,13 +475,15 @@ 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 evt.EventID == "" || evt.EventID == evt.TxnID { if evt.EventID == "" || evt.EventID == evt.TxnID || evt.IsService {
continue continue
} else if currentFound { } else if currentFound {
if evt.SenderID == self && evt.Event.Type == mautrix.EventMessage { if ownMessage && evt.SenderID == self && evt.Event.Type == mautrix.EventMessage {
return evt.Event return evt
} else if !ownMessage {
return evt
} }
} else if evt.EventID == view.editing.ID { } else if evt.EventID == current.ID {
currentFound = true currentFound = true
} }
} }
@ -457,17 +494,38 @@ func (view *RoomView) EditNext() {
if view.editing == nil { if view.editing == nil {
return return
} }
foundEvent := view.findMessageToEdit(true) foundMsg := view.findMessage(view.editing, true, true)
view.SetEditing(foundEvent) view.SetEditing(foundMsg.GetEvent())
} }
func (view *RoomView) EditPrevious() { func (view *RoomView) EditPrevious() {
if view.replying != nil { if view.replying != nil {
return return
} }
foundEvent := view.findMessageToEdit(false) foundMsg := view.findMessage(view.editing, true, false)
if foundEvent != nil { if foundMsg != nil {
view.SetEditing(foundEvent) view.SetEditing(foundMsg.GetEvent())
}
}
func (view *RoomView) SelectNext() {
msgView := view.MessageView()
if msgView.selected == nil {
return
}
foundMsg := view.findMessage(msgView.selected.GetEvent(), true, true)
if foundMsg != nil {
msgView.SetSelected(foundMsg)
// TODO scroll selected message into view
}
}
func (view *RoomView) SelectPrevious() {
msgView := view.MessageView()
foundMsg := view.findMessage(msgView.selected.GetEvent(), true, false)
if foundMsg != nil {
msgView.SetSelected(foundMsg)
// TODO scroll selected message into view
} }
} }
@ -524,12 +582,12 @@ func (view *RoomView) InputSubmit(text string) {
func (view *RoomView) SendReaction(eventID string, reaction string) { func (view *RoomView) SendReaction(eventID string, reaction string) {
defer debug.Recover() defer debug.Recover()
debug.Print("Reacting to", eventID, "in", view.Room.ID, "with", reaction) debug.Print("Reacting to", eventID, "in", view.Room.ID, "with", reaction)
eventID, err := view.parent.matrix.SendEvent(&event.Event{ eventID, err := view.parent.matrix.SendEvent(&event.Event{
Event: &mautrix.Event{ Event: &mautrix.Event{
Type: mautrix.EventReaction, Type: mautrix.EventReaction,
RoomID: view.Room.ID, RoomID: view.Room.ID,
Content: mautrix.Content{ Content: mautrix.Content{
RelatesTo: &mautrix.RelatesTo{ RelatesTo: &mautrix.RelatesTo{
Type: mautrix.RelAnnotation, Type: mautrix.RelAnnotation,
EventID: eventID, EventID: eventID,