Sync read only and RCS status as power levels

This commit is contained in:
Tulir Asokan 2023-07-19 21:38:26 +03:00
parent 0d8edd817a
commit d367469000
4 changed files with 75 additions and 25 deletions

View file

@ -1761,14 +1761,15 @@ type Conversation struct {
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"`
// bool bool1 = 13;
Status ConvUpdateTypes `protobuf:"varint,12,opt,name=status,proto3,enum=conversations.ConvUpdateTypes" 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"`
}
@ -1861,6 +1862,13 @@ func (x *Conversation) GetStatus() ConvUpdateTypes {
return ConvUpdateTypes_UNKNOWN_CONVTYPE
}
func (x *Conversation) GetReadOnly() bool {
if x != nil {
return x.ReadOnly
}
return false
}
func (x *Conversation) GetAvatarHexColor() string {
if x != nil {
return x.AvatarHexColor
@ -1903,6 +1911,13 @@ func (x *Conversation) GetSubType() bool {
return false
}
func (x *Conversation) GetPinned() bool {
if x != nil {
return x.Pinned
}
return false
}
func (x *Conversation) GetUnknownTimestamp() int64 {
if x != nil {
return x.UnknownTimestamp

Binary file not shown.

View file

@ -132,14 +132,15 @@ message Conversation {
bool isGroupChat = 10; // not certain
string defaultOutgoingID = 11;
//bool bool1 = 13;
ConvUpdateTypes status = 12;
bool readOnly = 13;
string avatarHexColor = 15;
string latestMessageID = 17;
repeated Participant participants = 20;
repeated string otherParticipants = 21; // participant ids excluding me
ConversationType type = 22;
bool subType = 24;
bool pinned = 26;
int64 unknownTimestamp = 28; // set to lastMessageTimestamp + 1000 when marking as unread?
bool thirdType = 29;
}

View file

@ -800,6 +800,18 @@ func (portal *Portal) UpdateMetadata(user *User, info *gmproto.Conversation) []i
if portal.shouldSetDMRoomMetadata() {
update = portal.UpdateName(info.Name, false) || update
}
pls, err := portal.MainIntent().PowerLevels(portal.MXID)
if err != nil {
portal.zlog.Warn().Err(err).Msg("Failed to get power levels")
} else if portal.updatePowerLevels(info, pls) {
resp, err := portal.MainIntent().SetPowerLevels(portal.MXID, pls)
if err != nil {
portal.zlog.Warn().Err(err).Msg("Failed to update power levels")
} else {
portal.zlog.Debug().Str("event_id", resp.EventID.String()).Msg("Updated power levels")
}
}
// TODO avatar
if update {
err := portal.Update(context.TODO())
@ -830,25 +842,46 @@ func (portal *Portal) UpdateMatrixRoom(user *User, groupInfo *gmproto.Conversati
func (portal *Portal) GetBasePowerLevels() *event.PowerLevelsEventContent {
anyone := 0
nope := 99
invite := 50
return &event.PowerLevelsEventContent{
UsersDefault: anyone,
EventsDefault: anyone,
RedactPtr: &anyone,
StateDefaultPtr: &nope,
BanPtr: &nope,
InvitePtr: &invite,
KickPtr: &nope,
InvitePtr: &nope,
Users: map[id.UserID]int{
portal.MainIntent().UserID: 100,
portal.bridge.Bot.UserID: 100,
},
Events: map[string]int{
event.StateRoomName.Type: anyone,
event.StateRoomAvatar.Type: anyone,
event.EventReaction.Type: anyone, // TODO only allow reactions in RCS rooms
},
}
}
func (portal *Portal) updatePowerLevels(conv *gmproto.Conversation, pl *event.PowerLevelsEventContent) bool {
expectedEventsDefault := 0
if conv.GetReadOnly() {
expectedEventsDefault = 99
}
expectedReaction := 99
if conv.GetType() == gmproto.ConversationType_RCS {
expectedReaction = 0
}
changed := false
if pl.EventsDefault != expectedEventsDefault {
pl.EventsDefault = expectedEventsDefault
changed = true
}
changed = pl.EnsureEventLevel(event.EventReaction, expectedReaction) || changed
changed = pl.EnsureUserLevel(portal.bridge.Bot.UserID, 100) || changed
return changed
}
func (portal *Portal) getBridgeInfoStateKey() string {
return fmt.Sprintf("fi.mau.gmessages://gmessages/%s", portal.ID)
}
@ -928,11 +961,12 @@ func (portal *Portal) CreateMatrixRoom(user *User, conv *gmproto.Conversation) e
bridgeInfoStateKey, bridgeInfo := portal.getBridgeInfo()
pl := portal.GetBasePowerLevels()
portal.updatePowerLevels(conv, pl)
initialState := []*event.Event{{
Type: event.StatePowerLevels,
Content: event.Content{
Parsed: portal.GetBasePowerLevels(),
},
Content: event.Content{Parsed: pl},
}, {
Type: event.StateBridge,
Content: event.Content{Parsed: bridgeInfo},