Skip to content

Commit

Permalink
send mention
Browse files Browse the repository at this point in the history
  • Loading branch information
rnons committed Dec 24, 2024
1 parent 85b76f1 commit 6046d5a
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 9 deletions.
2 changes: 1 addition & 1 deletion pkg/connector/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func NewClient(userLogin *bridgev2.UserLogin, client *gchatmeow.Client) *GChatCl
userLogin: userLogin,
client: client,
users: map[string]*proto.User{},
msgConv: msgconv.NewMessageConverter(client),
msgConv: msgconv.NewMessageConverter(userLogin.Bridge, client),
}
}

Expand Down
3 changes: 3 additions & 0 deletions pkg/gchatmeow/proto/extra.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package proto

type MetadataAssociatedValue = isAnnotation_Metadata
3 changes: 1 addition & 2 deletions pkg/msgconv/from-matrix.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ func (mc *MessageConverter) ToGChat(
ctx context.Context,
content *event.MessageEventContent,
) (string, []*proto.Annotation) {
parser := &matrixfmt.HTMLParser{}
body, annotations := matrixfmt.Parse(ctx, parser, content)
body, annotations := matrixfmt.Parse(ctx, mc.matrixFmtParams, content)
return body, annotations
}
10 changes: 10 additions & 0 deletions pkg/msgconv/gchatfmt/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,15 @@ func MakeAnnotation(start, length int32, format proto.FormatMetadata_FormatType)
},
},
}
}

func MakeAnnotationFromMetadata(typ proto.AnnotationType, start, length int32, metadata proto.MetadataAssociatedValue) *proto.Annotation {
return &proto.Annotation{
Type: typ,
StartIndex: start,
Length: length,
ChipRenderType: proto.Annotation_DO_NOT_RENDER,
Metadata: metadata,
}

}
19 changes: 18 additions & 1 deletion pkg/msgconv/matrixfmt/html.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import (
"context"
"fmt"
"math"
"slices"
"strconv"
"strings"

"golang.org/x/net/html"
"maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"

"go.mau.fi/mautrix-googlechat/pkg/gchatmeow"
)
Expand Down Expand Up @@ -228,7 +230,7 @@ func (ctx Context) WithWhitespace() Context {

// HTMLParser is a somewhat customizable Matrix HTML parser.
type HTMLParser struct {
// GetUUIDFromMXID func(context.Context, id.UserID) uuid.UUID
GetUIDFromMXID func(context.Context, id.UserID) string
}

// TaggedString is a string that also contains a HTML tag.
Expand Down Expand Up @@ -345,6 +347,21 @@ func (parser *HTMLParser) linkToString(node *html.Node, ctx Context) *EntityStri
if len(href) == 0 {
return str
}
parsedMatrix, err := id.ParseMatrixURIOrMatrixToURL(href)
if err == nil && parsedMatrix != nil && parsedMatrix.Sigil1 == '@' {
mxid := parsedMatrix.UserID()
if ctx.AllowedMentions != nil && !slices.Contains(ctx.AllowedMentions.UserIDs, mxid) {
// Mention not allowed, use name as-is
return str
}
u := parser.GetUIDFromMXID(ctx.Ctx, mxid)
if u == "" {
return str
}
return NewEntityString("@" + str.String.String()).Format(Mention{
ID: u,
})
}
if str.String.String() == href {
return str
}
Expand Down
33 changes: 30 additions & 3 deletions pkg/msgconv/matrixfmt/tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,30 @@ import (
type BodyRangeValue interface {
String() string
Format(message string) string
Proto() proto.FormatMetadata_FormatType
Proto() proto.MetadataAssociatedValue
}

type Mention struct {
ID string
}

func (m Mention) String() string {
return fmt.Sprintf("Mention{ID: (%s)}", m.ID)
}

func (m Mention) Proto() proto.MetadataAssociatedValue {
return &proto.Annotation_UserMentionMetadata{
UserMentionMetadata: &proto.UserMentionMetadata{
Type: proto.UserMentionMetadata_MENTION,
Id: &proto.UserId{
Id: m.ID,
},
},
}
}

func (m Mention) Format(message string) string {
return message
}

type Style int
Expand All @@ -27,8 +50,12 @@ const (
StyleFontColor
)

func (s Style) Proto() proto.FormatMetadata_FormatType {
return proto.FormatMetadata_FormatType(s)
func (s Style) Proto() proto.MetadataAssociatedValue {
return &proto.Annotation_FormatMetadata{
FormatMetadata: &proto.FormatMetadata{
FormatType: proto.FormatMetadata_FormatType(s),
},
}
}

func (s Style) String() string {
Expand Down
8 changes: 7 additions & 1 deletion pkg/msgconv/matrixfmt/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,13 @@ func (b BodyRange) TruncateEnd(maxEnd int) *BodyRange {
}

func (b BodyRange) Proto() *proto.Annotation {
return gchatfmt.MakeAnnotation(int32(b.Start), int32(b.Length), b.Value.Proto())
metadata := b.Value.Proto()
typ := proto.AnnotationType_FORMAT_DATA
_, ok := metadata.(*proto.Annotation_UserMentionMetadata)
if ok {
typ = proto.AnnotationType_USER_MENTION
}
return gchatfmt.MakeAnnotationFromMetadata(typ, int32(b.Start), int32(b.Length), b.Value.Proto())
}

// LinkedRangeTree is a linked tree of formatting entities.
Expand Down
39 changes: 38 additions & 1 deletion pkg/msgconv/msgconv.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,52 @@
package msgconv

import (
"context"

"maunium.net/go/mautrix/bridgev2"
"maunium.net/go/mautrix/id"

"go.mau.fi/mautrix-googlechat/pkg/gchatmeow"
"go.mau.fi/mautrix-googlechat/pkg/msgconv/matrixfmt"
)

type contextKey int

const (
contextKeyPortal contextKey = iota
contextKeyClient
contextKeyIntent
)

type MessageConverter struct {
client *gchatmeow.Client

matrixFmtParams *matrixfmt.HTMLParser
}

func NewMessageConverter(client *gchatmeow.Client) *MessageConverter {
func NewMessageConverter(br *bridgev2.Bridge, client *gchatmeow.Client) *MessageConverter {
return &MessageConverter{
client: client,

matrixFmtParams: &matrixfmt.HTMLParser{
GetUIDFromMXID: func(ctx context.Context, userID id.UserID) string {
parsed, ok := br.Matrix.ParseGhostMXID(userID)
if ok {
return string(parsed)
}
user, _ := br.GetExistingUserByMXID(ctx, userID)
if user != nil {
preferredLogin, _, _ := getPortal(ctx).FindPreferredLogin(ctx, user, true)
if preferredLogin != nil {
return string(preferredLogin.ID)
}
}
return ""
},
},
}
}

func getPortal(ctx context.Context) *bridgev2.Portal {
return ctx.Value(contextKeyPortal).(*bridgev2.Portal)
}

0 comments on commit 6046d5a

Please sign in to comment.