From edeb50b87a2d0cc7ec1842e9501e6bae76a6a852 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 9 Jul 2022 16:33:51 +0300 Subject: [PATCH] Allow leaving main space and add command to rejoin it --- commands.go | 33 +++++++++++++++ user.go | 119 +++++++++++++++++++++++++--------------------------- 2 files changed, 91 insertions(+), 61 deletions(-) diff --git a/commands.go b/commands.go index 77379aa..6910682 100644 --- a/commands.go +++ b/commands.go @@ -19,6 +19,7 @@ package main import ( "context" "fmt" + "strconv" "strings" "github.com/skip2/go-qrcode" @@ -46,6 +47,7 @@ func (br *DiscordBridge) RegisterCommands() { cmdReconnect, cmdDisconnect, cmdGuilds, + cmdRejoinSpace, cmdDeleteAllPortals, ) } @@ -221,6 +223,37 @@ func fnReconnect(ce *WrappedCommandEvent) { } } +var cmdRejoinSpace = &commands.FullHandler{ + Func: wrapCommand(fnRejoinSpace), + Name: "rejoin-space", + Help: commands.HelpMeta{ + Section: commands.HelpSectionUnclassified, + Description: "Ask the bridge for an invite to a space you left", + Args: "<_guild ID_/main/dms>", + }, + RequiresLogin: true, +} + +func fnRejoinSpace(ce *WrappedCommandEvent) { + if len(ce.Args) == 0 { + ce.Reply("**Usage**: `$cmdprefix rejoin-space `") + return + } + user := ce.User + if ce.Args[0] == "main" { + user.ensureInvited(nil, user.GetSpaceRoom(), false) + ce.Reply("Invited you to your main space ([link](%s))", user.GetSpaceRoom().URI(ce.Bridge.AS.HomeserverDomain).MatrixToURL()) + } else if ce.Args[0] == "dms" { + user.ensureInvited(nil, user.GetDMSpaceRoom(), false) + ce.Reply("Invited you to your DM space ([link](%s))", user.GetDMSpaceRoom().URI(ce.Bridge.AS.HomeserverDomain).MatrixToURL()) + } else if _, err := strconv.Atoi(ce.Args[0]); err == nil { + ce.Reply("Rejoining guild spaces is not yet implemented") + } else { + ce.Reply("**Usage**: `$cmdprefix rejoin-space `") + return + } +} + var cmdGuilds = &commands.FullHandler{ Func: wrapCommand(fnGuilds), Name: "guilds", diff --git a/user.go b/user.go index 0793ed5..8d1833c 100644 --- a/user.go +++ b/user.go @@ -260,84 +260,81 @@ func (user *User) SetManagementRoom(roomID id.RoomID) { user.Update() } -func (user *User) getSpaceRoom(ptr *id.RoomID, checked *bool, name, topic string, parent id.RoomID) id.RoomID { - if len(*ptr) == 0 { - user.spaceCreateLock.Lock() - defer user.spaceCreateLock.Unlock() - if len(*ptr) > 0 { - return *ptr - } +func (user *User) getSpaceRoom(ptr *id.RoomID, name, topic string, parent id.RoomID) id.RoomID { + if len(*ptr) > 0 { + return *ptr + } + user.spaceCreateLock.Lock() + defer user.spaceCreateLock.Unlock() + if len(*ptr) > 0 { + return *ptr + } - initialState := []*event.Event{{ - Type: event.StateRoomAvatar, + initialState := []*event.Event{{ + Type: event.StateRoomAvatar, + Content: event.Content{ + Parsed: &event.RoomAvatarEventContent{ + URL: user.bridge.Config.AppService.Bot.ParsedAvatar, + }, + }, + }} + + if parent != "" { + parentIDStr := parent.String() + initialState = append(initialState, &event.Event{ + Type: event.StateSpaceParent, + StateKey: &parentIDStr, Content: event.Content{ - Parsed: &event.RoomAvatarEventContent{ - URL: user.bridge.Config.AppService.Bot.ParsedAvatar, - }, - }, - }} - - if parent != "" { - parentIDStr := parent.String() - initialState = append(initialState, &event.Event{ - Type: event.StateSpaceParent, - StateKey: &parentIDStr, - Content: event.Content{ - Parsed: &event.SpaceParentEventContent{ - Canonical: true, - Via: []string{user.bridge.AS.HomeserverDomain}, - }, - }, - }) - } - - resp, err := user.bridge.Bot.CreateRoom(&mautrix.ReqCreateRoom{ - Visibility: "private", - Name: name, - Topic: topic, - InitialState: initialState, - CreationContent: map[string]interface{}{ - "type": event.RoomTypeSpace, - }, - PowerLevelOverride: &event.PowerLevelsEventContent{ - Users: map[id.UserID]int{ - user.bridge.Bot.UserID: 9001, - user.MXID: 50, + Parsed: &event.SpaceParentEventContent{ + Canonical: true, + Via: []string{user.bridge.AS.HomeserverDomain}, }, }, }) + } - if err != nil { - user.log.Errorln("Failed to auto-create space room:", err) - } else { - *ptr = resp.RoomID - user.Update() - user.ensureInvited(nil, *ptr, false) + resp, err := user.bridge.Bot.CreateRoom(&mautrix.ReqCreateRoom{ + Visibility: "private", + Name: name, + Topic: topic, + InitialState: initialState, + CreationContent: map[string]interface{}{ + "type": event.RoomTypeSpace, + }, + PowerLevelOverride: &event.PowerLevelsEventContent{ + Users: map[id.UserID]int{ + user.bridge.Bot.UserID: 9001, + user.MXID: 50, + }, + }, + }) - if parent != "" { - _, err = user.bridge.Bot.SendStateEvent(parent, event.StateSpaceChild, resp.RoomID.String(), &event.SpaceChildEventContent{ - Via: []string{user.bridge.AS.HomeserverDomain}, - Order: " 0000", - }) - if err != nil { - user.log.Errorfln("Failed to add space room %s to parent space %s: %v", resp.RoomID, parent, err) - } + if err != nil { + user.log.Errorln("Failed to auto-create space room:", err) + } else { + *ptr = resp.RoomID + user.Update() + user.ensureInvited(nil, *ptr, false) + + if parent != "" { + _, err = user.bridge.Bot.SendStateEvent(parent, event.StateSpaceChild, resp.RoomID.String(), &event.SpaceChildEventContent{ + Via: []string{user.bridge.AS.HomeserverDomain}, + Order: " 0000", + }) + if err != nil { + user.log.Errorfln("Failed to add space room %s to parent space %s: %v", resp.RoomID, parent, err) } } - } else if !*checked && !user.bridge.StateStore.IsInRoom(*ptr, user.MXID) { - user.ensureInvited(nil, *ptr, false) } - *checked = true - return *ptr } func (user *User) GetSpaceRoom() id.RoomID { - return user.getSpaceRoom(&user.SpaceRoom, &user.spaceMembershipChecked, "Discord", "Your Discord bridged chats", "") + return user.getSpaceRoom(&user.SpaceRoom, "Discord", "Your Discord bridged chats", "") } func (user *User) GetDMSpaceRoom() id.RoomID { - return user.getSpaceRoom(&user.DMSpaceRoom, &user.dmSpaceMembershipChecked, "Direct Messages", "Your Discord direct messages", user.GetSpaceRoom()) + return user.getSpaceRoom(&user.DMSpaceRoom, "Direct Messages", "Your Discord direct messages", user.GetSpaceRoom()) } func (user *User) tryAutomaticDoublePuppeting() {