|
@@ -6,6 +6,7 @@ import (
|
|
|
"strings"
|
|
|
|
|
|
"github.com/yuin/goldmark"
|
|
|
+ "maunium.net/go/mautrix/id"
|
|
|
|
|
|
"maunium.net/go/mautrix/event"
|
|
|
"maunium.net/go/mautrix/format"
|
|
@@ -23,8 +24,55 @@ func renderDiscordMarkdown(text string) event.MessageEventContent {
|
|
|
return format.RenderMarkdownCustom(text, mdRenderer)
|
|
|
}
|
|
|
|
|
|
+const formatterContextUserKey = "fi.mau.discord.user"
|
|
|
+const formatterContextPortalKey = "fi.mau.discord.portal"
|
|
|
+
|
|
|
+func pillConverter(displayname, mxid, eventID string, ctx format.Context) string {
|
|
|
+ if len(mxid) == 0 {
|
|
|
+ return displayname
|
|
|
+ }
|
|
|
+ user := ctx[formatterContextUserKey].(*User)
|
|
|
+ if mxid[0] == '#' {
|
|
|
+ alias, err := user.bridge.Bot.ResolveAlias(id.RoomAlias(mxid))
|
|
|
+ if err != nil {
|
|
|
+ return displayname
|
|
|
+ }
|
|
|
+ mxid = alias.RoomID.String()
|
|
|
+ }
|
|
|
+ if mxid[0] == '!' {
|
|
|
+ portal := user.bridge.GetPortalByMXID(id.RoomID(mxid))
|
|
|
+ if portal != nil {
|
|
|
+ if eventID == "" {
|
|
|
+ //currentPortal := ctx[formatterContextPortalKey].(*Portal)
|
|
|
+ return fmt.Sprintf("<#%s>", portal.Key.ChannelID)
|
|
|
+ //if currentPortal.GuildID == portal.GuildID {
|
|
|
+ //} else if portal.GuildID != "" {
|
|
|
+ // return fmt.Sprintf("<#%s:%s:%s>", portal.Key.ChannelID, portal.GuildID, portal.Name)
|
|
|
+ //} else {
|
|
|
+ // // TODO is mentioning private channels possible at all?
|
|
|
+ //}
|
|
|
+ } else if msg := user.bridge.DB.Message.GetByMXID(portal.Key, id.EventID(eventID)); msg != nil {
|
|
|
+ guildID := portal.GuildID
|
|
|
+ if guildID == "" {
|
|
|
+ guildID = "@me"
|
|
|
+ }
|
|
|
+ return fmt.Sprintf("https://discord.com/channels/%s/%s/%s", guildID, msg.DiscordProtoChannelID(), msg.DiscordID)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if mxid[0] == '@' {
|
|
|
+ parsedID, ok := user.bridge.ParsePuppetMXID(id.UserID(mxid))
|
|
|
+ if ok {
|
|
|
+ return fmt.Sprintf("<@%s>", parsedID)
|
|
|
+ }
|
|
|
+ mentionedUser := user.bridge.GetUserByMXID(id.UserID(mxid))
|
|
|
+ if mentionedUser != nil && mentionedUser.DiscordID != "" {
|
|
|
+ return fmt.Sprintf("<@%s>", mentionedUser.DiscordID)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return displayname
|
|
|
+}
|
|
|
+
|
|
|
var matrixHTMLParser = &format.HTMLParser{
|
|
|
- PillConverter: nil,
|
|
|
TabsToSpaces: 4,
|
|
|
Newline: "\n",
|
|
|
HorizontalLine: "\n---\n",
|
|
@@ -45,6 +93,10 @@ var matrixHTMLParser = &format.HTMLParser{
|
|
|
},
|
|
|
}
|
|
|
|
|
|
+func init() {
|
|
|
+ matrixHTMLParser.PillConverter = pillConverter
|
|
|
+}
|
|
|
+
|
|
|
var discordMarkdownEscaper = strings.NewReplacer(
|
|
|
`\`, `\\`,
|
|
|
`_`, `\_`,
|
|
@@ -52,11 +104,15 @@ var discordMarkdownEscaper = strings.NewReplacer(
|
|
|
`~`, `\~`,
|
|
|
"`", "\\`",
|
|
|
`|`, `\|`,
|
|
|
+ `<`, `\<`,
|
|
|
)
|
|
|
|
|
|
-func parseMatrixHTML(content *event.MessageEventContent) string {
|
|
|
+func (portal *Portal) parseMatrixHTML(user *User, content *event.MessageEventContent) string {
|
|
|
if content.Format == event.FormatHTML && len(content.FormattedBody) > 0 {
|
|
|
- return matrixHTMLParser.Parse(content.FormattedBody, make(format.Context))
|
|
|
+ return matrixHTMLParser.Parse(content.FormattedBody, format.Context{
|
|
|
+ formatterContextUserKey: user,
|
|
|
+ formatterContextPortalKey: portal,
|
|
|
+ })
|
|
|
} else {
|
|
|
return discordMarkdownEscaper.Replace(content.Body)
|
|
|
}
|