Only set force RCS flag if chat has had e2ee tombstone
This commit is contained in:
parent
56bfc105ed
commit
2c373db8fc
10 changed files with 217 additions and 109 deletions
|
@ -37,18 +37,18 @@ func newPortal(qh *dbutil.QueryHelper[*Portal]) *Portal {
|
|||
}
|
||||
|
||||
const (
|
||||
getAllPortalsQuery = "SELECT id, receiver, self_user, other_user, type, mxid, name, name_set, encrypted, in_space FROM portal"
|
||||
getAllPortalsQuery = "SELECT id, receiver, self_user, other_user, type, send_mode, force_rcs, mxid, name, name_set, encrypted, in_space FROM portal"
|
||||
getAllPortalsForUserQuery = getAllPortalsQuery + " WHERE receiver=$1"
|
||||
getPortalByKeyQuery = getAllPortalsQuery + " WHERE id=$1 AND receiver=$2"
|
||||
getPortalByOtherUserQuery = getAllPortalsQuery + " WHERE other_user=$1 AND receiver=$2"
|
||||
getPortalByMXIDQuery = getAllPortalsQuery + " WHERE mxid=$1"
|
||||
insertPortalQuery = `
|
||||
INSERT INTO portal (id, receiver, self_user, other_user, type, mxid, name, name_set, encrypted, in_space)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
||||
INSERT INTO portal (id, receiver, self_user, other_user, type, send_mode, force_rcs, mxid, name, name_set, encrypted, in_space)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
||||
`
|
||||
updatePortalQuery = `
|
||||
UPDATE portal
|
||||
SET self_user=$3, other_user=$4, type=$5, mxid=$6, name=$7, name_set=$8, encrypted=$9, in_space=$10
|
||||
SET self_user=$3, other_user=$4, type=$5, send_mode=$6, force_rcs=$7, mxid=$8, name=$9, name_set=$10, encrypted=$11, in_space=$12
|
||||
WHERE id=$1 AND receiver=$2
|
||||
`
|
||||
deletePortalQuery = "DELETE FROM portal WHERE id=$1 AND receiver=$2"
|
||||
|
@ -96,6 +96,8 @@ type Portal struct {
|
|||
MXID id.RoomID
|
||||
|
||||
Type gmproto.ConversationType
|
||||
SendMode gmproto.ConversationSendMode
|
||||
ForceRCS bool
|
||||
Name string
|
||||
NameSet bool
|
||||
Encrypted bool
|
||||
|
@ -104,15 +106,16 @@ type Portal struct {
|
|||
|
||||
func (portal *Portal) Scan(row dbutil.Scannable) (*Portal, error) {
|
||||
var mxid, selfUserID, otherUserID sql.NullString
|
||||
var convType int
|
||||
var convType, sendMode int
|
||||
err := row.Scan(
|
||||
&portal.ID, &portal.Receiver, &selfUserID, &otherUserID, &convType, &mxid,
|
||||
&portal.ID, &portal.Receiver, &selfUserID, &otherUserID, &convType, &sendMode, &portal.ForceRCS, &mxid,
|
||||
&portal.Name, &portal.NameSet, &portal.Encrypted, &portal.InSpace,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
portal.Type = gmproto.ConversationType(convType)
|
||||
portal.SendMode = gmproto.ConversationSendMode(sendMode)
|
||||
portal.MXID = id.RoomID(mxid.String)
|
||||
portal.OutgoingID = selfUserID.String
|
||||
portal.OtherUserID = otherUserID.String
|
||||
|
@ -122,7 +125,7 @@ func (portal *Portal) Scan(row dbutil.Scannable) (*Portal, error) {
|
|||
func (portal *Portal) sqlVariables() []any {
|
||||
return []any{
|
||||
portal.ID, portal.Receiver, dbutil.StrPtr(portal.OutgoingID), dbutil.StrPtr(portal.OtherUserID),
|
||||
int(portal.Type), dbutil.StrPtr(portal.MXID),
|
||||
int(portal.Type), int(portal.SendMode), portal.ForceRCS, dbutil.StrPtr(portal.MXID),
|
||||
portal.Name, portal.NameSet, portal.Encrypted, portal.InSpace,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
-- v0 -> v9: Latest revision
|
||||
-- v0 -> v10 (compatible with v9+): Latest revision
|
||||
|
||||
CREATE TABLE "user" (
|
||||
-- only: postgres
|
||||
|
@ -44,6 +44,8 @@ CREATE TABLE portal (
|
|||
self_user TEXT,
|
||||
other_user TEXT,
|
||||
type INTEGER NOT NULL,
|
||||
send_mode INTEGER NOT NULL,
|
||||
force_rcs BOOLEAN NOT NULL DEFAULT false,
|
||||
mxid TEXT UNIQUE,
|
||||
name TEXT NOT NULL,
|
||||
name_set BOOLEAN NOT NULL DEFAULT false,
|
||||
|
|
3
database/upgrades/10-send-mode.sql
Normal file
3
database/upgrades/10-send-mode.sql
Normal file
|
@ -0,0 +1,3 @@
|
|||
-- v10 (compatible with v9+): Store send mode for portals
|
||||
ALTER TABLE portal ADD COLUMN send_mode INTEGER NOT NULL DEFAULT 0;
|
||||
ALTER TABLE portal ADD COLUMN force_rcs BOOLEAN NOT NULL DEFAULT false;
|
|
@ -2383,7 +2383,7 @@ type SendMessageRequest struct {
|
|||
MessagePayload *MessagePayload `protobuf:"bytes,3,opt,name=messagePayload,proto3" json:"messagePayload,omitempty"`
|
||||
SIMPayload *SIMPayload `protobuf:"bytes,4,opt,name=SIMPayload,proto3" json:"SIMPayload,omitempty"`
|
||||
TmpID string `protobuf:"bytes,5,opt,name=tmpID,proto3" json:"tmpID,omitempty"`
|
||||
IsRCS bool `protobuf:"varint,6,opt,name=isRCS,proto3" json:"isRCS,omitempty"` // not sure
|
||||
ForceRCS bool `protobuf:"varint,6,opt,name=forceRCS,proto3" json:"forceRCS,omitempty"`
|
||||
Reply *ReplyPayload `protobuf:"bytes,8,opt,name=reply,proto3" json:"reply,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -2447,9 +2447,9 @@ func (x *SendMessageRequest) GetTmpID() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (x *SendMessageRequest) GetIsRCS() bool {
|
||||
func (x *SendMessageRequest) GetForceRCS() bool {
|
||||
if x != nil {
|
||||
return x.IsRCS
|
||||
return x.ForceRCS
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -255,7 +255,7 @@ message SendMessageRequest {
|
|||
MessagePayload messagePayload = 3;
|
||||
settings.SIMPayload SIMPayload = 4;
|
||||
string tmpID = 5;
|
||||
bool isRCS = 6; // not sure
|
||||
bool forceRCS = 6;
|
||||
ReplyPayload reply = 8;
|
||||
}
|
||||
|
||||
|
|
|
@ -153,6 +153,55 @@ func (IdentifierType) EnumDescriptor() ([]byte, []int) {
|
|||
return file_conversations_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
type ConversationSendMode int32
|
||||
|
||||
const (
|
||||
ConversationSendMode_SEND_MODE_AUTO ConversationSendMode = 0
|
||||
ConversationSendMode_SEND_MODE_XMS ConversationSendMode = 1
|
||||
ConversationSendMode_SEND_MODE_XMS_LATCH ConversationSendMode = 2
|
||||
)
|
||||
|
||||
// Enum value maps for ConversationSendMode.
|
||||
var (
|
||||
ConversationSendMode_name = map[int32]string{
|
||||
0: "SEND_MODE_AUTO",
|
||||
1: "SEND_MODE_XMS",
|
||||
2: "SEND_MODE_XMS_LATCH",
|
||||
}
|
||||
ConversationSendMode_value = map[string]int32{
|
||||
"SEND_MODE_AUTO": 0,
|
||||
"SEND_MODE_XMS": 1,
|
||||
"SEND_MODE_XMS_LATCH": 2,
|
||||
}
|
||||
)
|
||||
|
||||
func (x ConversationSendMode) Enum() *ConversationSendMode {
|
||||
p := new(ConversationSendMode)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x ConversationSendMode) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (ConversationSendMode) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_conversations_proto_enumTypes[2].Descriptor()
|
||||
}
|
||||
|
||||
func (ConversationSendMode) Type() protoreflect.EnumType {
|
||||
return &file_conversations_proto_enumTypes[2]
|
||||
}
|
||||
|
||||
func (x ConversationSendMode) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ConversationSendMode.Descriptor instead.
|
||||
func (ConversationSendMode) EnumDescriptor() ([]byte, []int) {
|
||||
return file_conversations_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
type ConversationType int32
|
||||
|
||||
const (
|
||||
|
@ -186,11 +235,11 @@ func (x ConversationType) String() string {
|
|||
}
|
||||
|
||||
func (ConversationType) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_conversations_proto_enumTypes[2].Descriptor()
|
||||
return file_conversations_proto_enumTypes[3].Descriptor()
|
||||
}
|
||||
|
||||
func (ConversationType) Type() protoreflect.EnumType {
|
||||
return &file_conversations_proto_enumTypes[2]
|
||||
return &file_conversations_proto_enumTypes[3]
|
||||
}
|
||||
|
||||
func (x ConversationType) Number() protoreflect.EnumNumber {
|
||||
|
@ -199,7 +248,7 @@ func (x ConversationType) Number() protoreflect.EnumNumber {
|
|||
|
||||
// Deprecated: Use ConversationType.Descriptor instead.
|
||||
func (ConversationType) EnumDescriptor() ([]byte, []int) {
|
||||
return file_conversations_proto_rawDescGZIP(), []int{2}
|
||||
return file_conversations_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
type MessageStatusType int32
|
||||
|
@ -463,11 +512,11 @@ func (x MessageStatusType) String() string {
|
|||
}
|
||||
|
||||
func (MessageStatusType) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_conversations_proto_enumTypes[3].Descriptor()
|
||||
return file_conversations_proto_enumTypes[4].Descriptor()
|
||||
}
|
||||
|
||||
func (MessageStatusType) Type() protoreflect.EnumType {
|
||||
return &file_conversations_proto_enumTypes[3]
|
||||
return &file_conversations_proto_enumTypes[4]
|
||||
}
|
||||
|
||||
func (x MessageStatusType) Number() protoreflect.EnumNumber {
|
||||
|
@ -476,7 +525,7 @@ func (x MessageStatusType) Number() protoreflect.EnumNumber {
|
|||
|
||||
// Deprecated: Use MessageStatusType.Descriptor instead.
|
||||
func (MessageStatusType) EnumDescriptor() ([]byte, []int) {
|
||||
return file_conversations_proto_rawDescGZIP(), []int{3}
|
||||
return file_conversations_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
type ConversationStatus int32
|
||||
|
@ -524,11 +573,11 @@ func (x ConversationStatus) String() string {
|
|||
}
|
||||
|
||||
func (ConversationStatus) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_conversations_proto_enumTypes[4].Descriptor()
|
||||
return file_conversations_proto_enumTypes[5].Descriptor()
|
||||
}
|
||||
|
||||
func (ConversationStatus) Type() protoreflect.EnumType {
|
||||
return &file_conversations_proto_enumTypes[4]
|
||||
return &file_conversations_proto_enumTypes[5]
|
||||
}
|
||||
|
||||
func (x ConversationStatus) Number() protoreflect.EnumNumber {
|
||||
|
@ -537,7 +586,7 @@ func (x ConversationStatus) Number() protoreflect.EnumNumber {
|
|||
|
||||
// Deprecated: Use ConversationStatus.Descriptor instead.
|
||||
func (ConversationStatus) EnumDescriptor() ([]byte, []int) {
|
||||
return file_conversations_proto_rawDescGZIP(), []int{4}
|
||||
return file_conversations_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
type MediaFormats int32
|
||||
|
@ -696,11 +745,11 @@ func (x MediaFormats) String() string {
|
|||
}
|
||||
|
||||
func (MediaFormats) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_conversations_proto_enumTypes[5].Descriptor()
|
||||
return file_conversations_proto_enumTypes[6].Descriptor()
|
||||
}
|
||||
|
||||
func (MediaFormats) Type() protoreflect.EnumType {
|
||||
return &file_conversations_proto_enumTypes[5]
|
||||
return &file_conversations_proto_enumTypes[6]
|
||||
}
|
||||
|
||||
func (x MediaFormats) Number() protoreflect.EnumNumber {
|
||||
|
@ -709,7 +758,7 @@ func (x MediaFormats) Number() protoreflect.EnumNumber {
|
|||
|
||||
// Deprecated: Use MediaFormats.Descriptor instead.
|
||||
func (MediaFormats) EnumDescriptor() ([]byte, []int) {
|
||||
return file_conversations_proto_rawDescGZIP(), []int{5}
|
||||
return file_conversations_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
type Contact struct {
|
||||
|
@ -1839,24 +1888,25 @@ type Conversation struct {
|
|||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
LatestMessage *LatestMessage `protobuf:"bytes,4,opt,name=latestMessage,proto3" json:"latestMessage,omitempty"`
|
||||
LastMessageTimestamp int64 `protobuf:"varint,5,opt,name=lastMessageTimestamp,proto3" json:"lastMessageTimestamp,omitempty"`
|
||||
Unread bool `protobuf:"varint,6,opt,name=unread,proto3" json:"unread,omitempty"`
|
||||
IsGroupChat bool `protobuf:"varint,10,opt,name=isGroupChat,proto3" json:"isGroupChat,omitempty"` // not certain
|
||||
DefaultOutgoingID string `protobuf:"bytes,11,opt,name=defaultOutgoingID,proto3" json:"defaultOutgoingID,omitempty"`
|
||||
Status ConversationStatus `protobuf:"varint,12,opt,name=status,proto3,enum=conversations.ConversationStatus" json:"status,omitempty"`
|
||||
ReadOnly bool `protobuf:"varint,13,opt,name=readOnly,proto3" json:"readOnly,omitempty"`
|
||||
AvatarHexColor string `protobuf:"bytes,15,opt,name=avatarHexColor,proto3" json:"avatarHexColor,omitempty"`
|
||||
LatestMessageID string `protobuf:"bytes,17,opt,name=latestMessageID,proto3" json:"latestMessageID,omitempty"`
|
||||
Participants []*Participant `protobuf:"bytes,20,rep,name=participants,proto3" json:"participants,omitempty"`
|
||||
OtherParticipants []string `protobuf:"bytes,21,rep,name=otherParticipants,proto3" json:"otherParticipants,omitempty"` // participant ids excluding me
|
||||
Type ConversationType `protobuf:"varint,22,opt,name=type,proto3,enum=conversations.ConversationType" json:"type,omitempty"`
|
||||
SubType bool `protobuf:"varint,24,opt,name=subType,proto3" json:"subType,omitempty"`
|
||||
Pinned bool `protobuf:"varint,26,opt,name=pinned,proto3" json:"pinned,omitempty"`
|
||||
UnknownTimestamp int64 `protobuf:"varint,28,opt,name=unknownTimestamp,proto3" json:"unknownTimestamp,omitempty"` // set to lastMessageTimestamp + 1000 when marking as unread?
|
||||
ThirdType bool `protobuf:"varint,29,opt,name=thirdType,proto3" json:"thirdType,omitempty"`
|
||||
ConversationID string `protobuf:"bytes,1,opt,name=conversationID,proto3" json:"conversationID,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
LatestMessage *LatestMessage `protobuf:"bytes,4,opt,name=latestMessage,proto3" json:"latestMessage,omitempty"`
|
||||
LastMessageTimestamp int64 `protobuf:"varint,5,opt,name=lastMessageTimestamp,proto3" json:"lastMessageTimestamp,omitempty"`
|
||||
Unread bool `protobuf:"varint,6,opt,name=unread,proto3" json:"unread,omitempty"`
|
||||
IsGroupChat bool `protobuf:"varint,10,opt,name=isGroupChat,proto3" json:"isGroupChat,omitempty"` // not certain
|
||||
DefaultOutgoingID string `protobuf:"bytes,11,opt,name=defaultOutgoingID,proto3" json:"defaultOutgoingID,omitempty"`
|
||||
Status ConversationStatus `protobuf:"varint,12,opt,name=status,proto3,enum=conversations.ConversationStatus" json:"status,omitempty"`
|
||||
ReadOnly bool `protobuf:"varint,13,opt,name=readOnly,proto3" json:"readOnly,omitempty"`
|
||||
AvatarHexColor string `protobuf:"bytes,15,opt,name=avatarHexColor,proto3" json:"avatarHexColor,omitempty"`
|
||||
LatestMessageID string `protobuf:"bytes,17,opt,name=latestMessageID,proto3" json:"latestMessageID,omitempty"`
|
||||
SendMode ConversationSendMode `protobuf:"varint,18,opt,name=sendMode,proto3,enum=conversations.ConversationSendMode" json:"sendMode,omitempty"`
|
||||
Participants []*Participant `protobuf:"bytes,20,rep,name=participants,proto3" json:"participants,omitempty"`
|
||||
OtherParticipants []string `protobuf:"bytes,21,rep,name=otherParticipants,proto3" json:"otherParticipants,omitempty"` // participant ids excluding me
|
||||
Type ConversationType `protobuf:"varint,22,opt,name=type,proto3,enum=conversations.ConversationType" json:"type,omitempty"`
|
||||
SubType bool `protobuf:"varint,24,opt,name=subType,proto3" json:"subType,omitempty"`
|
||||
Pinned bool `protobuf:"varint,26,opt,name=pinned,proto3" json:"pinned,omitempty"`
|
||||
UnknownTimestamp int64 `protobuf:"varint,28,opt,name=unknownTimestamp,proto3" json:"unknownTimestamp,omitempty"` // set to lastMessageTimestamp + 1000 when marking as unread?
|
||||
ThirdType bool `protobuf:"varint,29,opt,name=thirdType,proto3" json:"thirdType,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Conversation) Reset() {
|
||||
|
@ -1968,6 +2018,13 @@ func (x *Conversation) GetLatestMessageID() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (x *Conversation) GetSendMode() ConversationSendMode {
|
||||
if x != nil {
|
||||
return x.SendMode
|
||||
}
|
||||
return ConversationSendMode_SEND_MODE_AUTO
|
||||
}
|
||||
|
||||
func (x *Conversation) GetParticipants() []*Participant {
|
||||
if x != nil {
|
||||
return x.Participants
|
||||
|
@ -2673,77 +2730,79 @@ func file_conversations_proto_rawDescGZIP() []byte {
|
|||
return file_conversations_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_conversations_proto_enumTypes = make([]protoimpl.EnumInfo, 6)
|
||||
var file_conversations_proto_enumTypes = make([]protoimpl.EnumInfo, 7)
|
||||
var file_conversations_proto_msgTypes = make([]protoimpl.MessageInfo, 26)
|
||||
var file_conversations_proto_goTypes = []interface{}{
|
||||
(EmojiType)(0), // 0: conversations.EmojiType
|
||||
(IdentifierType)(0), // 1: conversations.IdentifierType
|
||||
(ConversationType)(0), // 2: conversations.ConversationType
|
||||
(MessageStatusType)(0), // 3: conversations.MessageStatusType
|
||||
(ConversationStatus)(0), // 4: conversations.ConversationStatus
|
||||
(MediaFormats)(0), // 5: conversations.MediaFormats
|
||||
(*Contact)(nil), // 6: conversations.Contact
|
||||
(*ContactNumber)(nil), // 7: conversations.ContactNumber
|
||||
(*Message)(nil), // 8: conversations.Message
|
||||
(*ReactionEntry)(nil), // 9: conversations.ReactionEntry
|
||||
(*CustomEmojiData)(nil), // 10: conversations.CustomEmojiData
|
||||
(*ReactionData)(nil), // 11: conversations.ReactionData
|
||||
(*EmojiMeta)(nil), // 12: conversations.EmojiMeta
|
||||
(*EmojiMetaData)(nil), // 13: conversations.EmojiMetaData
|
||||
(*ReplyMessage)(nil), // 14: conversations.ReplyMessage
|
||||
(*ReplyMessageData)(nil), // 15: conversations.ReplyMessageData
|
||||
(*MessageInfo)(nil), // 16: conversations.MessageInfo
|
||||
(*MediaContent)(nil), // 17: conversations.MediaContent
|
||||
(*Dimensions)(nil), // 18: conversations.Dimensions
|
||||
(*MessageContent)(nil), // 19: conversations.MessageContent
|
||||
(*MsgType)(nil), // 20: conversations.MsgType
|
||||
(*MessageStatus)(nil), // 21: conversations.MessageStatus
|
||||
(*Conversation)(nil), // 22: conversations.Conversation
|
||||
(*Participant)(nil), // 23: conversations.Participant
|
||||
(*SmallInfo)(nil), // 24: conversations.SmallInfo
|
||||
(*LatestMessage)(nil), // 25: conversations.LatestMessage
|
||||
(*LatestMessageStatus)(nil), // 26: conversations.LatestMessageStatus
|
||||
(*Muted)(nil), // 27: conversations.Muted
|
||||
(*CustomEmojiData_Inner)(nil), // 28: conversations.CustomEmojiData.Inner
|
||||
(*CustomEmojiData_Inner_ImageData)(nil), // 29: conversations.CustomEmojiData.Inner.ImageData
|
||||
(*CustomEmojiData_Inner_WrappedImageData)(nil), // 30: conversations.CustomEmojiData.Inner.WrappedImageData
|
||||
(*CustomEmojiData_Inner_WrappedImageData_ImageData)(nil), // 31: conversations.CustomEmojiData.Inner.WrappedImageData.ImageData
|
||||
(ConversationSendMode)(0), // 2: conversations.ConversationSendMode
|
||||
(ConversationType)(0), // 3: conversations.ConversationType
|
||||
(MessageStatusType)(0), // 4: conversations.MessageStatusType
|
||||
(ConversationStatus)(0), // 5: conversations.ConversationStatus
|
||||
(MediaFormats)(0), // 6: conversations.MediaFormats
|
||||
(*Contact)(nil), // 7: conversations.Contact
|
||||
(*ContactNumber)(nil), // 8: conversations.ContactNumber
|
||||
(*Message)(nil), // 9: conversations.Message
|
||||
(*ReactionEntry)(nil), // 10: conversations.ReactionEntry
|
||||
(*CustomEmojiData)(nil), // 11: conversations.CustomEmojiData
|
||||
(*ReactionData)(nil), // 12: conversations.ReactionData
|
||||
(*EmojiMeta)(nil), // 13: conversations.EmojiMeta
|
||||
(*EmojiMetaData)(nil), // 14: conversations.EmojiMetaData
|
||||
(*ReplyMessage)(nil), // 15: conversations.ReplyMessage
|
||||
(*ReplyMessageData)(nil), // 16: conversations.ReplyMessageData
|
||||
(*MessageInfo)(nil), // 17: conversations.MessageInfo
|
||||
(*MediaContent)(nil), // 18: conversations.MediaContent
|
||||
(*Dimensions)(nil), // 19: conversations.Dimensions
|
||||
(*MessageContent)(nil), // 20: conversations.MessageContent
|
||||
(*MsgType)(nil), // 21: conversations.MsgType
|
||||
(*MessageStatus)(nil), // 22: conversations.MessageStatus
|
||||
(*Conversation)(nil), // 23: conversations.Conversation
|
||||
(*Participant)(nil), // 24: conversations.Participant
|
||||
(*SmallInfo)(nil), // 25: conversations.SmallInfo
|
||||
(*LatestMessage)(nil), // 26: conversations.LatestMessage
|
||||
(*LatestMessageStatus)(nil), // 27: conversations.LatestMessageStatus
|
||||
(*Muted)(nil), // 28: conversations.Muted
|
||||
(*CustomEmojiData_Inner)(nil), // 29: conversations.CustomEmojiData.Inner
|
||||
(*CustomEmojiData_Inner_ImageData)(nil), // 30: conversations.CustomEmojiData.Inner.ImageData
|
||||
(*CustomEmojiData_Inner_WrappedImageData)(nil), // 31: conversations.CustomEmojiData.Inner.WrappedImageData
|
||||
(*CustomEmojiData_Inner_WrappedImageData_ImageData)(nil), // 32: conversations.CustomEmojiData.Inner.WrappedImageData.ImageData
|
||||
}
|
||||
var file_conversations_proto_depIdxs = []int32{
|
||||
7, // 0: conversations.Contact.number:type_name -> conversations.ContactNumber
|
||||
20, // 1: conversations.Message.msgType:type_name -> conversations.MsgType
|
||||
21, // 2: conversations.Message.messageStatus:type_name -> conversations.MessageStatus
|
||||
16, // 3: conversations.Message.messageInfo:type_name -> conversations.MessageInfo
|
||||
9, // 4: conversations.Message.reactions:type_name -> conversations.ReactionEntry
|
||||
14, // 5: conversations.Message.replyMessage:type_name -> conversations.ReplyMessage
|
||||
11, // 6: conversations.ReactionEntry.data:type_name -> conversations.ReactionData
|
||||
28, // 7: conversations.CustomEmojiData.innerData:type_name -> conversations.CustomEmojiData.Inner
|
||||
8, // 0: conversations.Contact.number:type_name -> conversations.ContactNumber
|
||||
21, // 1: conversations.Message.msgType:type_name -> conversations.MsgType
|
||||
22, // 2: conversations.Message.messageStatus:type_name -> conversations.MessageStatus
|
||||
17, // 3: conversations.Message.messageInfo:type_name -> conversations.MessageInfo
|
||||
10, // 4: conversations.Message.reactions:type_name -> conversations.ReactionEntry
|
||||
15, // 5: conversations.Message.replyMessage:type_name -> conversations.ReplyMessage
|
||||
12, // 6: conversations.ReactionEntry.data:type_name -> conversations.ReactionData
|
||||
29, // 7: conversations.CustomEmojiData.innerData:type_name -> conversations.CustomEmojiData.Inner
|
||||
0, // 8: conversations.ReactionData.type:type_name -> conversations.EmojiType
|
||||
10, // 9: conversations.ReactionData.customEmoji:type_name -> conversations.CustomEmojiData
|
||||
13, // 10: conversations.EmojiMeta.emojiMetaData:type_name -> conversations.EmojiMetaData
|
||||
15, // 11: conversations.ReplyMessage.replyMessageData:type_name -> conversations.ReplyMessageData
|
||||
19, // 12: conversations.MessageInfo.messageContent:type_name -> conversations.MessageContent
|
||||
17, // 13: conversations.MessageInfo.mediaContent:type_name -> conversations.MediaContent
|
||||
5, // 14: conversations.MediaContent.format:type_name -> conversations.MediaFormats
|
||||
18, // 15: conversations.MediaContent.dimensions:type_name -> conversations.Dimensions
|
||||
3, // 16: conversations.MessageStatus.status:type_name -> conversations.MessageStatusType
|
||||
25, // 17: conversations.Conversation.latestMessage:type_name -> conversations.LatestMessage
|
||||
4, // 18: conversations.Conversation.status:type_name -> conversations.ConversationStatus
|
||||
23, // 19: conversations.Conversation.participants:type_name -> conversations.Participant
|
||||
2, // 20: conversations.Conversation.type:type_name -> conversations.ConversationType
|
||||
24, // 21: conversations.Participant.ID:type_name -> conversations.SmallInfo
|
||||
27, // 22: conversations.Participant.muted:type_name -> conversations.Muted
|
||||
1, // 23: conversations.SmallInfo.type:type_name -> conversations.IdentifierType
|
||||
26, // 24: conversations.LatestMessage.latestMessageStatus:type_name -> conversations.LatestMessageStatus
|
||||
3, // 25: conversations.LatestMessageStatus.status:type_name -> conversations.MessageStatusType
|
||||
29, // 26: conversations.CustomEmojiData.Inner.first:type_name -> conversations.CustomEmojiData.Inner.ImageData
|
||||
30, // 27: conversations.CustomEmojiData.Inner.second:type_name -> conversations.CustomEmojiData.Inner.WrappedImageData
|
||||
31, // 28: conversations.CustomEmojiData.Inner.WrappedImageData.data:type_name -> conversations.CustomEmojiData.Inner.WrappedImageData.ImageData
|
||||
29, // [29:29] is the sub-list for method output_type
|
||||
29, // [29:29] is the sub-list for method input_type
|
||||
29, // [29:29] is the sub-list for extension type_name
|
||||
29, // [29:29] is the sub-list for extension extendee
|
||||
0, // [0:29] is the sub-list for field type_name
|
||||
11, // 9: conversations.ReactionData.customEmoji:type_name -> conversations.CustomEmojiData
|
||||
14, // 10: conversations.EmojiMeta.emojiMetaData:type_name -> conversations.EmojiMetaData
|
||||
16, // 11: conversations.ReplyMessage.replyMessageData:type_name -> conversations.ReplyMessageData
|
||||
20, // 12: conversations.MessageInfo.messageContent:type_name -> conversations.MessageContent
|
||||
18, // 13: conversations.MessageInfo.mediaContent:type_name -> conversations.MediaContent
|
||||
6, // 14: conversations.MediaContent.format:type_name -> conversations.MediaFormats
|
||||
19, // 15: conversations.MediaContent.dimensions:type_name -> conversations.Dimensions
|
||||
4, // 16: conversations.MessageStatus.status:type_name -> conversations.MessageStatusType
|
||||
26, // 17: conversations.Conversation.latestMessage:type_name -> conversations.LatestMessage
|
||||
5, // 18: conversations.Conversation.status:type_name -> conversations.ConversationStatus
|
||||
2, // 19: conversations.Conversation.sendMode:type_name -> conversations.ConversationSendMode
|
||||
24, // 20: conversations.Conversation.participants:type_name -> conversations.Participant
|
||||
3, // 21: conversations.Conversation.type:type_name -> conversations.ConversationType
|
||||
25, // 22: conversations.Participant.ID:type_name -> conversations.SmallInfo
|
||||
28, // 23: conversations.Participant.muted:type_name -> conversations.Muted
|
||||
1, // 24: conversations.SmallInfo.type:type_name -> conversations.IdentifierType
|
||||
27, // 25: conversations.LatestMessage.latestMessageStatus:type_name -> conversations.LatestMessageStatus
|
||||
4, // 26: conversations.LatestMessageStatus.status:type_name -> conversations.MessageStatusType
|
||||
30, // 27: conversations.CustomEmojiData.Inner.first:type_name -> conversations.CustomEmojiData.Inner.ImageData
|
||||
31, // 28: conversations.CustomEmojiData.Inner.second:type_name -> conversations.CustomEmojiData.Inner.WrappedImageData
|
||||
32, // 29: conversations.CustomEmojiData.Inner.WrappedImageData.data:type_name -> conversations.CustomEmojiData.Inner.WrappedImageData.ImageData
|
||||
30, // [30:30] is the sub-list for method output_type
|
||||
30, // [30:30] is the sub-list for method input_type
|
||||
30, // [30:30] is the sub-list for extension type_name
|
||||
30, // [30:30] is the sub-list for extension extendee
|
||||
0, // [0:30] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_conversations_proto_init() }
|
||||
|
@ -3080,7 +3139,7 @@ func file_conversations_proto_init() {
|
|||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_conversations_proto_rawDesc,
|
||||
NumEnums: 6,
|
||||
NumEnums: 7,
|
||||
NumMessages: 26,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
|
|
Binary file not shown.
|
@ -168,6 +168,7 @@ message Conversation {
|
|||
bool readOnly = 13;
|
||||
string avatarHexColor = 15;
|
||||
string latestMessageID = 17;
|
||||
ConversationSendMode sendMode = 18;
|
||||
repeated Participant participants = 20;
|
||||
repeated string otherParticipants = 21; // participant ids excluding me
|
||||
ConversationType type = 22;
|
||||
|
@ -221,6 +222,12 @@ message Muted {
|
|||
int64 isMuted = 1;
|
||||
}
|
||||
|
||||
enum ConversationSendMode {
|
||||
SEND_MODE_AUTO = 0;
|
||||
SEND_MODE_XMS = 1;
|
||||
SEND_MODE_XMS_LATCH = 2;
|
||||
}
|
||||
|
||||
enum ConversationType {
|
||||
UNKNOWN_CONVERSATION_TYPE = 0;
|
||||
SMS = 1;
|
||||
|
|
38
portal.go
38
portal.go
|
@ -774,6 +774,26 @@ func (portal *Portal) handleMessage(source *User, evt *gmproto.Message, raw []by
|
|||
case gmproto.MessageStatusType_INCOMING_AUTO_DOWNLOADING, gmproto.MessageStatusType_INCOMING_RETRYING_AUTO_DOWNLOAD:
|
||||
log.Debug().Msg("Not handling incoming auto-downloading MMS")
|
||||
return
|
||||
case gmproto.MessageStatusType_MESSAGE_STATUS_TOMBSTONE_PROTOCOL_SWITCH_RCS_TO_E2EE, gmproto.MessageStatusType_MESSAGE_STATUS_TOMBSTONE_PROTOCOL_SWITCH_TEXT_TO_E2EE:
|
||||
if !portal.ForceRCS {
|
||||
portal.ForceRCS = true
|
||||
err := portal.Update(ctx)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to update portal to force RCS")
|
||||
} else {
|
||||
log.Debug().Msg("Setting force RCS flag for portal due to E2EE tombstone")
|
||||
}
|
||||
}
|
||||
case gmproto.MessageStatusType_MESSAGE_STATUS_TOMBSTONE_PROTOCOL_SWITCH_E2EE_TO_RCS, gmproto.MessageStatusType_MESSAGE_STATUS_TOMBSTONE_PROTOCOL_SWITCH_E2EE_TO_TEXT:
|
||||
if portal.ForceRCS {
|
||||
portal.ForceRCS = false
|
||||
err := portal.Update(ctx)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to update portal to unforce RCS")
|
||||
} else {
|
||||
log.Debug().Msg("Removing force RCS flag for portal due to non-E2EE tombstone")
|
||||
}
|
||||
}
|
||||
}
|
||||
if time.Since(eventTS) > 24*time.Hour {
|
||||
lastMessage, err := portal.bridge.DB.Message.GetLastInChat(ctx, portal.Key)
|
||||
|
@ -1486,6 +1506,14 @@ func (portal *Portal) UpdateMetadata(ctx context.Context, user *User, info *gmpr
|
|||
portal.Type = info.Type
|
||||
update = true
|
||||
}
|
||||
if portal.SendMode != info.SendMode {
|
||||
portal.zlog.Debug().
|
||||
Str("old_send_mode", portal.SendMode.String()).
|
||||
Str("new_send_mode", info.SendMode.String()).
|
||||
Msg("Conversation send mode changed")
|
||||
portal.SendMode = info.SendMode
|
||||
update = true
|
||||
}
|
||||
if portal.OutgoingID != info.DefaultOutgoingID {
|
||||
portal.zlog.Debug().
|
||||
Str("old_id", portal.OutgoingID).
|
||||
|
@ -1932,6 +1960,7 @@ func (portal *Portal) uploadMedia(ctx context.Context, intent *appservice.Intent
|
|||
|
||||
func (portal *Portal) convertMatrixMessage(ctx context.Context, sender *User, content *event.MessageEventContent, raw map[string]any, txnID string) (*gmproto.SendMessageRequest, error) {
|
||||
log := zerolog.Ctx(ctx)
|
||||
sim := sender.GetSIM(portal.OutgoingID)
|
||||
req := &gmproto.SendMessageRequest{
|
||||
ConversationID: portal.ID,
|
||||
TmpID: txnID,
|
||||
|
@ -1941,7 +1970,7 @@ func (portal *Portal) convertMatrixMessage(ctx context.Context, sender *User, co
|
|||
TmpID2: txnID,
|
||||
ParticipantID: portal.OutgoingID,
|
||||
},
|
||||
SIMPayload: sender.GetSIM(portal.OutgoingID).GetSIMData().GetSIMPayload(),
|
||||
SIMPayload: sim.GetSIMData().GetSIMPayload(),
|
||||
}
|
||||
|
||||
replyToMXID := content.RelatesTo.GetReplyTo()
|
||||
|
@ -1955,7 +1984,12 @@ func (portal *Portal) convertMatrixMessage(ctx context.Context, sender *User, co
|
|||
req.Reply = &gmproto.ReplyPayload{MessageID: replyToMsg.ID}
|
||||
}
|
||||
}
|
||||
req.IsRCS = portal.Type == gmproto.ConversationType_RCS
|
||||
req.ForceRCS = portal.Type == gmproto.ConversationType_RCS &&
|
||||
portal.SendMode == gmproto.ConversationSendMode_SEND_MODE_AUTO &&
|
||||
portal.ForceRCS
|
||||
if req.ForceRCS && !sim.GetRCSChats().GetEnabled() {
|
||||
log.Warn().Msg("Forcing RCS but RCS is disabled on sim")
|
||||
}
|
||||
|
||||
switch content.MsgType {
|
||||
case event.MsgText, event.MsgEmote, event.MsgNotice:
|
||||
|
|
Loading…
Reference in a new issue