-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathim_room.go
105 lines (90 loc) · 2.89 KB
/
im_room.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package gotrix
import (
"errors"
"strconv"
"strings"
"github.com/chanbakjsd/gotrix/event"
"github.com/chanbakjsd/gotrix/matrix"
)
// ErrRoomAvatarNotFound is returned by RoomAvatar when the room avatar cannot be discovered.
var ErrRoomAvatarNotFound = errors.New("user is alone in the room and a room avatar has not been set")
// RoomAvatar retrieves the avatar of a room.
// It falls back to the profile picture of the first user to join the room that is not the current user otherwise.
// If the current user is alone, it returns nil and an error.
func (c *Client) RoomAvatar(roomID matrix.RoomID) (*matrix.URL, error) {
e, _ := c.RoomState(roomID, event.TypeRoomAvatar, "")
if e != nil {
avatarEvent := e.(*event.RoomAvatarEvent)
return &avatarEvent.URL, nil
}
summary, err := c.RoomSummary(roomID)
if err != nil {
return nil, err
}
if len(summary.Heroes) == 0 {
return nil, ErrRoomAvatarNotFound
}
return c.MemberAvatar(roomID, summary.Heroes[0])
}
// RoomName calculates the display name of a room.
func (c *Client) RoomName(roomID matrix.RoomID) (string, error) {
// Step 1: Check for m.room.name state event.
e, _ := c.RoomState(roomID, event.TypeRoomName, "")
if e != nil {
nameEvent := e.(*event.RoomNameEvent)
if nameEvent.Name != "" {
return nameEvent.Name, nil
}
}
// Step 2: Check for m.room.canonical_alias state event.
e, _ = c.RoomState(roomID, event.TypeRoomCanonicalAlias, "")
if e != nil {
aliasEvent := e.(*event.RoomCanonicalAliasEvent)
if aliasEvent.Alias != "" {
return aliasEvent.Alias, nil
}
}
summary, err := c.RoomSummary(roomID)
if err != nil {
return "", err
}
heroes := make([]string, 0, len(summary.Heroes))
for k, v := range summary.Heroes {
if k > 4 {
break // Sane limit of 5 names displayed.
}
name, err := c.MemberName(roomID, v)
if err != nil {
return "", err
}
heroes = append(heroes, name)
}
joinAndInvited := summary.JoinedCount + summary.InvitedCount
if len(heroes) == 0 {
if joinAndInvited <= 1 {
// User is alone in the room or the room is empty.
return "Empty Room", nil
}
// This should never happen but if there are no heroes, the room ID is the sanest option we have.
return string(roomID), nil
}
switch {
case len(summary.Heroes) == 1:
// Do nothing. There's no "and" to add.
case len(summary.Heroes) >= joinAndInvited-1 && len(heroes) > 1:
// There are only heroes in the room so just make it "and <Last Hero>".
heroes[len(heroes)-1] = "and " + heroes[len(heroes)-1]
default:
// There are more than just heroes in the room.
heroes = append(heroes, "and "+strconv.Itoa(joinAndInvited-len(summary.Heroes))+" others")
}
roomSummary := strings.Join(heroes, ", ")
if len(heroes) == 2 {
// Do "Alice and Bob" instead of "Alice, and Bob".
roomSummary = heroes[0] + " " + heroes[1]
}
if joinAndInvited <= 1 {
return "Empty Room (was " + roomSummary + ")", nil
}
return roomSummary, nil
}