diff options
author | Tulir Asokan <tulir@maunium.net> | 2018-03-18 21:24:03 +0200 |
---|---|---|
committer | Tulir Asokan <tulir@maunium.net> | 2018-03-18 21:24:03 +0200 |
commit | 72945c9a284b6858594f1e8a43743c397e90c380 (patch) | |
tree | c4dc096f97c546dcc546d50385e2909e2e10b82d /matrix/room | |
parent | 0509b195625c959a7b5556e3baae4f869c4d62f6 (diff) |
Organize files
Diffstat (limited to 'matrix/room')
-rw-r--r-- | matrix/room/member.go | 51 | ||||
-rw-r--r-- | matrix/room/room.go | 145 |
2 files changed, 196 insertions, 0 deletions
diff --git a/matrix/room/member.go b/matrix/room/member.go new file mode 100644 index 0000000..474d2fd --- /dev/null +++ b/matrix/room/member.go @@ -0,0 +1,51 @@ +// gomuks - A terminal Matrix client written in Go. +// Copyright (C) 2018 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package room + +import ( + "maunium.net/go/gomatrix" +) + +type Member struct { + UserID string `json:"-"` + Membership string `json:"membership"` + DisplayName string `json:"displayname"` + AvatarURL string `json:"avatar_url"` +} + +func eventToRoomMember(userID string, event *gomatrix.Event) *Member { + if event == nil { + return &Member{ + UserID: userID, + Membership: "leave", + } + } + membership, _ := event.Content["membership"].(string) + avatarURL, _ := event.Content["avatar_url"].(string) + + displayName, _ := event.Content["displayname"].(string) + if len(displayName) == 0 { + displayName = userID + } + + return &Member{ + UserID: userID, + Membership: membership, + DisplayName: displayName, + AvatarURL: avatarURL, + } +} diff --git a/matrix/room/room.go b/matrix/room/room.go new file mode 100644 index 0000000..4b3bda2 --- /dev/null +++ b/matrix/room/room.go @@ -0,0 +1,145 @@ +// gomuks - A terminal Matrix client written in Go. +// Copyright (C) 2018 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package room + +import ( + "maunium.net/go/gomatrix" +) + +// Room represents a single Matrix room. +type Room struct { + *gomatrix.Room + + PrevBatch string + memberCache map[string]*Member + nameCache string + topicCache string +} + +// UpdateState updates the room's current state with the given Event. This will clobber events based +// on the type/state_key combination. +func (room *Room) UpdateState(event *gomatrix.Event) { + _, exists := room.State[event.Type] + if !exists { + room.State[event.Type] = make(map[string]*gomatrix.Event) + } + switch event.Type { + case "m.room.member": + room.memberCache = nil + case "m.room.name": + case "m.room.canonical_alias": + case "m.room.alias": + room.nameCache = "" + case "m.room.topic": + room.topicCache = "" + } + room.State[event.Type][*event.StateKey] = event +} + +// GetStateEvent returns the state event for the given type/state_key combo, or nil. +func (room *Room) GetStateEvent(eventType string, stateKey string) *gomatrix.Event { + stateEventMap, _ := room.State[eventType] + event, _ := stateEventMap[stateKey] + return event +} + +// GetStateEvents returns the state events for the given type. +func (room *Room) GetStateEvents(eventType string) map[string]*gomatrix.Event { + stateEventMap, _ := room.State[eventType] + return stateEventMap +} + +// GetTopic returns the topic of the room. +func (room *Room) GetTopic() string { + if len(room.topicCache) == 0 { + topicEvt := room.GetStateEvent("m.room.topic", "") + if topicEvt != nil { + room.topicCache, _ = topicEvt.Content["topic"].(string) + } + } + return room.topicCache +} + +// GetTitle returns the display title of the room. +func (room *Room) GetTitle() string { + if len(room.nameCache) == 0 { + nameEvt := room.GetStateEvent("m.room.name", "") + if nameEvt != nil { + room.nameCache, _ = nameEvt.Content["name"].(string) + } + } + if len(room.nameCache) == 0 { + canonicalAliasEvt := room.GetStateEvent("m.room.canonical_alias", "") + if canonicalAliasEvt != nil { + room.nameCache, _ = canonicalAliasEvt.Content["alias"].(string) + } + } + if len(room.nameCache) == 0 { + // TODO the spec says clients should not use m.room.aliases for room names. + // However, Riot also uses m.room.aliases, so this is here now. + aliasEvents := room.GetStateEvents("m.room.aliases") + for _, event := range aliasEvents { + aliases, _ := event.Content["aliases"].([]interface{}) + if len(aliases) > 0 { + room.nameCache, _ = aliases[0].(string) + break + } + } + } + if len(room.nameCache) == 0 { + // TODO follow other title rules in spec + room.nameCache = room.ID + } + return room.nameCache +} + +func (room *Room) createMemberCache() map[string]*Member { + cache := make(map[string]*Member) + events := room.GetStateEvents("m.room.member") + if events != nil { + for userID, event := range events { + member := eventToRoomMember(userID, event) + if member.Membership != "leave" { + cache[member.UserID] = member + } + } + } + room.memberCache = cache + return cache +} + +func (room *Room) GetMembers() map[string]*Member { + if len(room.memberCache) == 0 { + room.createMemberCache() + } + return room.memberCache +} + +func (room *Room) GetMember(userID string) *Member { + if len(room.memberCache) == 0 { + room.createMemberCache() + } + member, _ := room.memberCache[userID] + return member +} + +// NewRoom creates a new Room with the given ID +func NewRoom(roomID string) *Room { + return &Room{ + Room: gomatrix.NewRoom(roomID), + } +} |