aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTulir Asokan <tulir@maunium.net>2020-06-17 14:15:22 +0300
committerTulir Asokan <tulir@maunium.net>2020-06-17 14:15:22 +0300
commit38d5ef5603bba2241ec5ccf1c86f98ec24e023d6 (patch)
tree79dd23058b6598756c876e16e93e6cc9b0ba1d65
parenta8b6abe9703f0df95757686ca9340c697eca0f43 (diff)
Add alias management command and alt_aliases rendering
* /alias command can be used to create and remove local aliases * Changes to the alt_aliases are now rendered properly
-rw-r--r--ui/command-processor.go18
-rw-r--r--ui/commands.go85
-rw-r--r--ui/messages/parser.go146
3 files changed, 168 insertions, 81 deletions
diff --git a/ui/command-processor.go b/ui/command-processor.go
index 94b07b8..b8f41a2 100644
--- a/ui/command-processor.go
+++ b/ui/command-processor.go
@@ -41,11 +41,13 @@ type Command struct {
Command string
OrigCommand string
Args []string
+ RawArgs string
OrigText string
}
func (cmd *Command) Reply(message string, args ...interface{}) {
cmd.Room.AddServiceMessage(fmt.Sprintf(message, args...))
+ cmd.UI.Render()
}
type Alias struct {
@@ -128,6 +130,7 @@ func NewCommandProcessor(parent *MainView) *CommandProcessor {
"rainbow": cmdRainbow,
"rainbowme": cmdRainbowMe,
"notice": cmdNotice,
+ "alias": cmdAlias,
"tags": cmdTags,
"tag": cmdTag,
"untag": cmdUntag,
@@ -146,15 +149,22 @@ func (ch *CommandProcessor) ParseCommand(roomView *RoomView, text string) *Comma
return nil
}
text = text[1:]
- split := strings.SplitN(text, " ", -1)
+ split := strings.Fields(text)
+ command := split[0]
+ args := split[1:]
+ var rawArgs string
+ if len(text) > len(command)+1 {
+ rawArgs = text[len(command)+1:]
+ }
return &Command{
gomuksPointerContainer: ch.gomuksPointerContainer,
Handler: ch,
Room: roomView,
- Command: strings.ToLower(split[0]),
- OrigCommand: split[0],
- Args: split[1:],
+ Command: strings.ToLower(command),
+ OrigCommand: command,
+ Args: args,
+ RawArgs: rawArgs,
OrigText: text,
}
}
diff --git a/ui/commands.go b/ui/commands.go
index 71cee21..49bff0f 100644
--- a/ui/commands.go
+++ b/ui/commands.go
@@ -33,6 +33,7 @@ import (
"unicode"
"github.com/lucasb-eyer/go-colorful"
+ "github.com/pkg/errors"
"github.com/russross/blackfriday/v2"
"maunium.net/go/mautrix"
@@ -124,7 +125,7 @@ func cmdAccept(cmd *Command) {
_, server, _ := room.SessionMember.Sender.Parse()
_, err := cmd.Matrix.JoinRoom(room.ID, server)
if err != nil {
- cmd.Reply("Failed to accept invite:", err)
+ cmd.Reply("Failed to accept invite: %v", err)
} else {
cmd.Reply("Successfully accepted invite")
}
@@ -183,7 +184,7 @@ func cmdCopy(cmd *Command) {
if len(register) == 0 {
register = "clipboard"
}
- if (register == "clipboard" || register == "primary") {
+ if register == "clipboard" || register == "primary" {
cmd.Room.StartSelecting(SelectCopy, register)
} else {
cmd.Reply("Usage: /copy [register], where register is either \"clipboard\" or \"primary\". Defaults to \"clipboard\".")
@@ -199,6 +200,85 @@ func cmdReact(cmd *Command) {
cmd.Room.StartSelecting(SelectReact, strings.Join(cmd.Args, " "))
}
+func readRoomAlias(cmd *Command) (alias id.RoomAlias, err error) {
+ param := strings.Join(cmd.Args[1:], " ")
+ if strings.ContainsRune(param, ':') {
+ if param[0] != '#' {
+ return "", errors.New("Full aliases must start with #")
+ }
+
+ alias = id.RoomAlias(param)
+ } else {
+ _, homeserver, _ := cmd.Matrix.Client().UserID.Parse()
+ alias = id.NewRoomAlias(param, homeserver)
+ }
+ return
+}
+
+func cmdAlias(cmd *Command) {
+ if len(cmd.Args) < 2 {
+ cmd.Reply("Usage: /alias <add|remove> <localpart>")
+ return
+ }
+
+ alias, err := readRoomAlias(cmd)
+ if err != nil {
+ cmd.Reply(err.Error())
+ return
+ }
+
+ subcmd := strings.ToLower(cmd.Args[0])
+ switch subcmd {
+ case "add", "create":
+ cmdAddAlias(cmd, alias)
+ case "remove", "delete", "del", "rm":
+ cmdRemoveAlias(cmd, alias)
+ case "resolve", "get":
+ cmdResolveAlias(cmd, alias)
+ default:
+ cmd.Reply("Usage: /alias <add|remove|resolve> <localpart>")
+ }
+}
+
+func niceError(err error) string {
+ httpErr, ok := err.(mautrix.HTTPError)
+ if ok && httpErr.RespError != nil {
+ return httpErr.RespError.Error()
+ }
+ return err.Error()
+}
+
+func cmdAddAlias(cmd *Command, alias id.RoomAlias) {
+ _, err := cmd.Matrix.Client().CreateAlias(alias, cmd.Room.MxRoom().ID)
+ if err != nil {
+ cmd.Reply("Failed to create alias: %v", niceError(err))
+ } else {
+ cmd.Reply("Created alias %s", alias)
+ }
+}
+
+func cmdRemoveAlias(cmd *Command, alias id.RoomAlias) {
+ _, err := cmd.Matrix.Client().DeleteAlias(alias)
+ if err != nil {
+ cmd.Reply("Failed to delete alias: %v", niceError(err))
+ } else {
+ cmd.Reply("Deleted alias %s", alias)
+ }
+}
+
+func cmdResolveAlias(cmd *Command, alias id.RoomAlias) {
+ resp, err := cmd.Matrix.Client().ResolveAlias(alias)
+ if err != nil {
+ cmd.Reply("Failed to resolve alias: %v", niceError(err))
+ } else {
+ roomIDText := string(resp.RoomID)
+ if resp.RoomID == cmd.Room.MxRoom().ID {
+ roomIDText += " (this room)"
+ }
+ cmd.Reply("Alias %s points to room %s\nThere are %d servers in the room.", alias, roomIDText, len(resp.Servers))
+ }
+}
+
func cmdTags(cmd *Command) {
tags := cmd.Room.MxRoom().RawTags
if len(cmd.Args) > 0 && cmd.Args[0] == "--internal" {
@@ -384,6 +464,7 @@ Things: rooms, users, baremessages, images, typingnotif
/tag <tag> <priority> - Add the room to <tag>.
/untag <tag> - Remove the room from <tag>.
/tags - List the tags the room is in.
+/alias <act> <name> - Add or remove local addresses.
/leave - Leave the current room.
/kick <user id> [reason] - Kick a user.
diff --git a/ui/messages/parser.go b/ui/messages/parser.go
index 4a214f1..0f92f11 100644
--- a/ui/messages/parser.go
+++ b/ui/messages/parser.go
@@ -93,35 +93,94 @@ func directParseEvent(matrix ifc.MatrixContainer, room *rooms.Room, evt *muksevt
}
}
+func findAltAliasDifference(newList, oldList []string) (addedStr, removedStr tstring.TString) {
+ var addedList, removedList []tstring.TString
+OldLoop:
+ for _, oldAlias := range oldList {
+ for _, newAlias := range newList {
+ if oldAlias == newAlias {
+ continue OldLoop
+ }
+ }
+ removedList = append(removedList, tstring.NewStyleTString(oldAlias, tcell.StyleDefault.Foreground(widget.GetHashColor(oldAlias)).Underline(true)))
+ }
+NewLoop:
+ for _, newAlias := range newList {
+ for _, oldAlias := range oldList {
+ if newAlias == oldAlias {
+ continue NewLoop
+ }
+ }
+ addedList = append(addedList, tstring.NewStyleTString(newAlias, tcell.StyleDefault.Foreground(widget.GetHashColor(newAlias)).Underline(true)))
+ }
+ if len(addedList) == 1 {
+ addedStr = tstring.NewColorTString("added alternative address ", tcell.ColorGreen).AppendTString(addedList[0])
+ } else if len(addedList) != 0 {
+ addedStr = tstring.
+ Join(addedList[:len(addedList)-1], ", ").
+ PrependColor("added alternative addresses ", tcell.ColorGreen).
+ AppendColor(" and ", tcell.ColorGreen).
+ AppendTString(addedList[len(addedList)-1])
+ }
+ if len(removedList) == 1 {
+ removedStr = tstring.NewColorTString("removed alternative address ", tcell.ColorGreen).AppendTString(removedList[0])
+ } else if len(removedList) != 0 {
+ removedStr = tstring.
+ Join(removedList[:len(removedList)-1], ", ").
+ PrependColor("removed alternative addresses ", tcell.ColorGreen).
+ AppendColor(" and ", tcell.ColorGreen).
+ AppendTString(removedList[len(removedList)-1])
+ }
+ return
+}
+
func ParseStateEvent(evt *muksevt.Event, displayname string) *UIMessage {
- text := tstring.NewColorTString(displayname, widget.GetHashColor(evt.Sender))
+ text := tstring.NewColorTString(displayname, widget.GetHashColor(evt.Sender)).Append(" ")
switch content := evt.Content.Parsed.(type) {
case *event.TopicEventContent:
if len(content.Topic) == 0 {
- text = text.AppendColor(" removed the topic.", tcell.ColorGreen)
+ text = text.AppendColor("removed the topic.", tcell.ColorGreen)
} else {
- text = text.AppendColor(" changed the topic to ", tcell.ColorGreen).
+ text = text.AppendColor("changed the topic to ", tcell.ColorGreen).
AppendStyle(content.Topic, tcell.StyleDefault.Underline(true)).
AppendColor(".", tcell.ColorGreen)
}
case *event.RoomNameEventContent:
if len(content.Name) == 0 {
- text = text.AppendColor(" removed the room name.", tcell.ColorGreen)
+ text = text.AppendColor("removed the room name.", tcell.ColorGreen)
} else {
- text = text.AppendColor(" changed the room name to ", tcell.ColorGreen).
+ text = text.AppendColor("changed the room name to ", tcell.ColorGreen).
AppendStyle(content.Name, tcell.StyleDefault.Underline(true)).
AppendColor(".", tcell.ColorGreen)
}
case *event.CanonicalAliasEventContent:
- if len(content.Alias) == 0 {
- text = text.AppendColor(" removed the main address of the room.", tcell.ColorGreen)
+ _ = evt.Unsigned.PrevContent.ParseRaw(evt.Type)
+ prevContent := evt.Unsigned.PrevContent.AsCanonicalAlias()
+ debug.Printf("%+v -> %+v", prevContent, content)
+ if len(content.Alias) == 0 && len(prevContent.Alias) != 0 {
+ text = text.AppendColor("removed the main address of the room", tcell.ColorGreen)
+ } else if content.Alias != prevContent.Alias {
+ text = text.
+ AppendColor("changed the main address of the room to ", tcell.ColorGreen).
+ AppendStyle(string(content.Alias), tcell.StyleDefault.Underline(true))
} else {
- text = text.AppendColor(" changed the main address of the room to ", tcell.ColorGreen).
- AppendStyle(string(content.Alias), tcell.StyleDefault.Underline(true)).
- AppendColor(".", tcell.ColorGreen)
+ added, removed := findAltAliasDifference(content.AltAliases, prevContent.AltAliases)
+ if len(added) > 0 {
+ if len(removed) > 0 {
+ text = text.
+ AppendTString(added).
+ AppendColor(" and ", tcell.ColorGreen).
+ AppendTString(removed)
+ } else {
+ text = text.AppendTString(added)
+ }
+ } else if len(removed) > 0 {
+ text = text.AppendTString(removed)
+ } else {
+ text = text.AppendColor("changed nothing", tcell.ColorGreen)
+ }
+ text = text.AppendColor(" for this room", tcell.ColorGreen)
}
- //case event.StateAliases:
- // text = ParseAliasEvent(evt, displayname)
}
return NewExpandedTextMessage(evt, displayname, text)
}
@@ -243,66 +302,3 @@ func ParseMembershipEvent(room *rooms.Room, evt *muksevt.Event) *UIMessage {
return NewExpandedTextMessage(evt, displayname, text)
}
-
-//func ParseAliasEvent(evt *muksevt.Event, displayname string) tstring.TString {
-// var prevAliases []string
-// if evt.Unsigned.PrevContent != nil {
-// prevAliases = evt.Unsigned.PrevContent.Aliases
-// }
-// aliases := evt.Content.Aliases
-// var added, removed []tstring.TString
-//Outer1:
-// for _, oldAlias := range prevAliases {
-// for _, newAlias := range aliases {
-// if oldAlias == newAlias {
-// continue Outer1
-// }
-// }
-// removed = append(removed, tstring.NewStyleTString(oldAlias, tcell.StyleDefault.Foreground(widget.GetHashColor(oldAlias)).Underline(true)))
-// }
-//Outer2:
-// for _, newAlias := range aliases {
-// for _, oldAlias := range prevAliases {
-// if oldAlias == newAlias {
-// continue Outer2
-// }
-// }
-// added = append(added, tstring.NewStyleTString(newAlias, tcell.StyleDefault.Foreground(widget.GetHashColor(newAlias)).Underline(true)))
-// }
-// var addedStr, removedStr tstring.TString
-// if len(added) == 1 {
-// addedStr = added[0]
-// } else if len(added) > 1 {
-// addedStr = tstring.
-// Join(added[:len(added)-1], ", ").
-// Append(" and ").
-// AppendTString(added[len(added)-1])
-// }
-// if len(removed) == 1 {
-// removedStr = removed[0]
-// } else if len(removed) > 1 {
-// removedStr = tstring.
-// Join(removed[:len(removed)-1], ", ").
-// Append(" and ").
-// AppendTString(removed[len(removed)-1])
-// }
-// text := tstring.NewBlankTString()
-// if len(addedStr) > 0 && len(removedStr) > 0 {
-// text = text.AppendColor(fmt.Sprintf("%s added ", displayname), tcell.ColorGreen).
-// AppendTString(addedStr).
-// AppendColor(" and removed ", tcell.ColorGreen).
-// AppendTString(removedStr).
-// AppendColor(" as addresses for this room.", tcell.ColorGreen)
-// } else if len(addedStr) > 0 {
-// text = text.AppendColor(fmt.Sprintf("%s added ", displayname), tcell.ColorGreen).
-// AppendTString(addedStr).
-// AppendColor(" as addresses for this room.", tcell.ColorGreen)
-// } else if len(removedStr) > 0 {
-// text = text.AppendColor(fmt.Sprintf("%s removed ", displayname), tcell.ColorGreen).
-// AppendTString(removedStr).
-// AppendColor(" as addresses for this room.", tcell.ColorGreen)
-// } else {
-// return nil
-// }
-// return text
-//}