diff --git a/database/portal.go b/database/portal.go index bd5a729..63fc489 100644 --- a/database/portal.go +++ b/database/portal.go @@ -244,8 +244,28 @@ func (portal *Portal) Update(txn dbutil.Execable) { } func (portal *Portal) Delete() { - _, err := portal.db.Exec("DELETE FROM portal WHERE jid=$1 AND receiver=$2", portal.Key.JID, portal.Key.Receiver) + txn, err := portal.db.Begin() if err != nil { - portal.log.Warnfln("Failed to delete %s: %v", portal.Key, err) + portal.log.Errorfln("Failed to begin transaction to delete portal %v: %v", portal.Key, err) + return + } + defer func() { + if err != nil { + err = txn.Rollback() + if err != nil { + portal.log.Warnfln("Failed to rollback failed portal delete transaction: %v", err) + } + } else if err = txn.Commit(); err != nil { + portal.log.Warnfln("Failed to commit portal delete transaction: %v", err) + } + }() + _, err = portal.db.Exec("UPDATE portal SET in_space=false WHERE parent_group=$1", portal.Key.JID) + if err != nil { + portal.log.Warnfln("Failed to mark child groups of %v as not in space: %v", portal.Key.JID, err) + return + } + _, err = portal.db.Exec("DELETE FROM portal WHERE jid=$1 AND receiver=$2", portal.Key.JID, portal.Key.Receiver) + if err != nil { + portal.log.Warnfln("Failed to delete %v: %v", portal.Key, err) } } diff --git a/portal.go b/portal.go index a5b26ea..6259357 100644 --- a/portal.go +++ b/portal.go @@ -1262,8 +1262,8 @@ func (portal *Portal) UpdateMetadata(user *User, groupInfo *types.GroupInfo) boo if portal.MXID != "" { portal.log.Warnfln("Existing group changed is_parent from %t to %t", portal.IsParent, groupInfo.IsParent) } + portal.IsParent = groupInfo.IsParent update = true - portal.IsParent = true } portal.RestrictMessageSending(groupInfo.IsAnnounce) @@ -1731,6 +1731,13 @@ func (portal *Portal) addToPersonalSpace(user *User) { } } +func (portal *Portal) removeSpaceParentEvent(space id.RoomID) { + _, err := portal.MainIntent().SendStateEvent(portal.MXID, event.StateSpaceParent, space.String(), &event.SpaceParentEventContent{}) + if err != nil { + portal.log.Warnfln("Failed to send m.space.parent event to remove portal from %s: %v", space, err) + } +} + func (portal *Portal) updateCommunitySpace(user *User, add, updateDB bool) bool { if add == portal.InSpace { return false @@ -4147,6 +4154,20 @@ func (portal *Portal) canBridgeFrom(sender *User, allowRelay bool) error { return nil } +func (portal *Portal) resetChildSpaceStatus() { + for _, childPortal := range portal.bridge.portalsByJID { + if childPortal.ParentGroup == portal.Key.JID { + if portal.MXID != "" && childPortal.InSpace { + go childPortal.removeSpaceParentEvent(portal.MXID) + } + childPortal.InSpace = false + if childPortal.parentPortal == portal { + childPortal.parentPortal = nil + } + } + } +} + func (portal *Portal) Delete() { portal.Portal.Delete() portal.bridge.portalsLock.Lock() @@ -4154,6 +4175,7 @@ func (portal *Portal) Delete() { if len(portal.MXID) > 0 { delete(portal.bridge.portalsByMXID, portal.MXID) } + portal.resetChildSpaceStatus() portal.bridge.portalsLock.Unlock() }