fix group member display names
This commit is contained in:
+27
-14
@@ -4828,11 +4828,6 @@ func serveIMGroupMembers(wrt http.ResponseWriter, req *http.Request, topic strin
|
||||
roleFilter := strings.TrimSpace(req.URL.Query().Get("role"))
|
||||
eligibleRole := strings.TrimSpace(req.URL.Query().Get("eligible_role"))
|
||||
muteEligible := parseIMBool(req.URL.Query().Get("mute_eligible"))
|
||||
cacheKey := groupMemberPageCacheKey(topic, principal.Uid, selfAccess, query, roleFilter, eligibleRole, limit, cursor, mentionableOnly, muteEligible)
|
||||
if cached, ok := store.GetCachedGroupMemberPage(principal.TenantID, cacheKey); ok {
|
||||
writeIMSuccess(wrt, req, cached)
|
||||
return
|
||||
}
|
||||
members, nextCursor, err := store.GroupBusiness.ListMembers(principal.TenantID, topic, types.GroupMemberListOptions{
|
||||
Role: roleFilter,
|
||||
EligibleRole: eligibleRole,
|
||||
@@ -4845,10 +4840,11 @@ func serveIMGroupMembers(wrt http.ResponseWriter, req *http.Request, topic strin
|
||||
writeIMError(wrt, req, http.StatusInternalServerError, 90000, imReasonInternal, "internal error", nil)
|
||||
return
|
||||
}
|
||||
remarks := groupMemberRemarkMap(principal.TenantID, principal.Uid, members)
|
||||
items := make([]map[string]any, 0, limit)
|
||||
for _, member := range members {
|
||||
access := groupMemberAccess(member)
|
||||
item := groupBusinessMemberPayload(member)
|
||||
item := groupBusinessMemberPayload(member, remarks[member.UserID])
|
||||
if eligibleRole != "" {
|
||||
eligible, reason := groupRoleEligibility(selfAccess, access, eligibleRole)
|
||||
item["eligible"] = eligible
|
||||
@@ -4874,7 +4870,6 @@ func serveIMGroupMembers(wrt http.ResponseWriter, req *http.Request, topic strin
|
||||
"next_cursor": nextCursor,
|
||||
"permissions": permissions,
|
||||
}
|
||||
store.CacheGroupMemberPage(principal.TenantID, cacheKey, payload)
|
||||
writeIMSuccess(wrt, req, payload)
|
||||
}
|
||||
|
||||
@@ -7386,10 +7381,10 @@ func groupMemberSettingsPayload(sub *types.Subscription) map[string]any {
|
||||
}
|
||||
}
|
||||
|
||||
func groupMemberPayload(sub types.Subscription, mentionable bool) map[string]any {
|
||||
func groupMemberPayload(sub types.Subscription, mentionable bool, remark string) map[string]any {
|
||||
access := sub.ModeGiven & sub.ModeWant
|
||||
user := &types.User{ObjHeader: types.ObjHeader{Id: sub.User}, Public: sub.GetPublic(), Trusted: sub.GetTrusted()}
|
||||
data := userSummaryPayload(user, "")
|
||||
data := userSummaryPayload(user, remark)
|
||||
if private := groupPrivateMap(sub.Private); stringFromAny(private["nickname"]) != "" {
|
||||
data["group_nickname"] = stringFromAny(private["nickname"])
|
||||
}
|
||||
@@ -7403,10 +7398,10 @@ func groupMemberPayload(sub types.Subscription, mentionable bool) map[string]any
|
||||
return data
|
||||
}
|
||||
|
||||
func groupBusinessMemberPayload(member types.GroupMember) map[string]any {
|
||||
func groupBusinessMemberPayload(member types.GroupMember, remark string) map[string]any {
|
||||
access := groupMemberAccess(member)
|
||||
user := &types.User{ObjHeader: types.ObjHeader{Id: member.UserID.String()}, Public: member.Public, Trusted: member.Trusted}
|
||||
data := userSummaryPayload(user, "")
|
||||
data := userSummaryPayload(user, remark)
|
||||
if nickname := strings.TrimSpace(member.Nickname); nickname != "" {
|
||||
data["group_nickname"] = nickname
|
||||
}
|
||||
@@ -7420,6 +7415,24 @@ func groupBusinessMemberPayload(member types.GroupMember) map[string]any {
|
||||
return data
|
||||
}
|
||||
|
||||
func groupMemberRemarkMap(tenantID types.TenantID, viewer types.Uid, members []types.GroupMember) map[types.Uid]string {
|
||||
remarks := make(map[types.Uid]string)
|
||||
for _, member := range members {
|
||||
if member.UserID.IsZero() || member.UserID == viewer {
|
||||
continue
|
||||
}
|
||||
ctx, err := store.Relations.GetRelationshipContext(tenantID, viewer, member.UserID, viewer.P2PName(member.UserID))
|
||||
if err != nil {
|
||||
logs.Warn.Printf("group member[%s:%s]: failed to resolve friend remark for viewer %s: %v", member.Topic, member.UserID.UserId(), viewer.UserId(), err)
|
||||
continue
|
||||
}
|
||||
if ctx != nil && ctx.Remark != "" {
|
||||
remarks[member.UserID] = ctx.Remark
|
||||
}
|
||||
}
|
||||
return remarks
|
||||
}
|
||||
|
||||
func groupMemberAccess(member types.GroupMember) types.AccessMode {
|
||||
access := member.ModeGiven & member.ModeWant
|
||||
if access != types.ModeNone {
|
||||
@@ -7436,7 +7449,7 @@ func groupMemberAccess(member types.GroupMember) types.AccessMode {
|
||||
}
|
||||
|
||||
func groupMemberProfilePayload(topic string, sub *types.Subscription, user *types.User, ctx *types.RelationshipContext) map[string]any {
|
||||
data := groupMemberPayload(*sub, true)
|
||||
data := groupMemberPayload(*sub, true, ctx.Remark)
|
||||
data["topic"] = topic
|
||||
data["relationship"] = ctx.Relationship
|
||||
data["capabilities"] = map[string]any{
|
||||
@@ -7448,7 +7461,7 @@ func groupMemberProfilePayload(topic string, sub *types.Subscription, user *type
|
||||
data["request_id"] = ctx.RequestID
|
||||
}
|
||||
if user != nil {
|
||||
for key, value := range userSummaryPayload(user, "") {
|
||||
for key, value := range userSummaryPayload(user, ctx.Remark) {
|
||||
if key == "avatar_file_id" || key == "display_name" {
|
||||
data[key] = value
|
||||
}
|
||||
@@ -7829,7 +7842,7 @@ func groupAdminItems(members []types.Subscription) []map[string]any {
|
||||
for _, member := range members {
|
||||
access := member.ModeGiven & member.ModeWant
|
||||
if access.IsAdmin() && !access.IsOwner() {
|
||||
items = append(items, groupMemberPayload(member, true))
|
||||
items = append(items, groupMemberPayload(member, true, ""))
|
||||
}
|
||||
}
|
||||
return items
|
||||
|
||||
+23
-6
@@ -3895,13 +3895,24 @@ func TestServeIMGroupMembers(t *testing.T) {
|
||||
expectIMBearer(t, ctrl, "token-1", 7, 42)
|
||||
oldSubs := store.Subs
|
||||
oldGroupBusiness := store.GroupBusiness
|
||||
oldRelations := store.Relations
|
||||
subs := mock_store.NewMockSubsPersistenceInterface(ctrl)
|
||||
store.Subs = subs
|
||||
groupStore := &testGroupBusinessStore{listMembersNext: "101"}
|
||||
store.GroupBusiness = groupStore
|
||||
store.Relations = &testRelationsStore{context: &types.RelationshipContext{
|
||||
TenantID: 7,
|
||||
UserID: 42,
|
||||
PeerID: types.Uid(101),
|
||||
Topic: types.Uid(42).P2PName(types.Uid(101)),
|
||||
Relationship: types.RelationshipFriend,
|
||||
CanSend: true,
|
||||
Remark: "老王",
|
||||
}}
|
||||
defer func() {
|
||||
store.Subs = oldSubs
|
||||
store.GroupBusiness = oldGroupBusiness
|
||||
store.Relations = oldRelations
|
||||
}()
|
||||
|
||||
subs.EXPECT().Get(types.TenantID(7), "grpMention", types.Uid(42), false).Return(&types.Subscription{
|
||||
@@ -3918,6 +3929,7 @@ func TestServeIMGroupMembers(t *testing.T) {
|
||||
Role: types.GroupMemberRoleMember,
|
||||
ModeWant: types.ModeCPublic,
|
||||
ModeGiven: types.ModeCPublic,
|
||||
Nickname: "群里小王",
|
||||
Public: map[string]any{"display_name": "Alice", "avatar_file_id": "alice.jpg"},
|
||||
MemberStatus: types.GroupMemberStatusActive,
|
||||
}}
|
||||
@@ -3933,7 +3945,8 @@ func TestServeIMGroupMembers(t *testing.T) {
|
||||
}
|
||||
data := decodeIMHTTPResponse(t, rec).Data.(map[string]any)
|
||||
items := data["items"].([]any)
|
||||
if len(items) != 1 || items[0].(map[string]any)["display_name"] != "Alice" ||
|
||||
if len(items) != 1 || items[0].(map[string]any)["display_name"] != "老王" ||
|
||||
items[0].(map[string]any)["group_nickname"] != "群里小王" ||
|
||||
items[0].(map[string]any)["avatar_file_id"] != "alice.jpg" ||
|
||||
items[0].(map[string]any)["mentionable"] != true {
|
||||
t.Fatalf("unexpected members response: %#v", data)
|
||||
@@ -3956,7 +3969,7 @@ func TestGroupMemberPayloadUserIDFormats(t *testing.T) {
|
||||
User: raw.String(),
|
||||
ModeWant: types.ModeJoin,
|
||||
ModeGiven: types.ModeJoin,
|
||||
}, true)
|
||||
}, true, "")
|
||||
if fromRaw["user_id"] != raw.UserId() {
|
||||
t.Fatalf("raw uid user_id: got %#v, want %s", fromRaw["user_id"], raw.UserId())
|
||||
}
|
||||
@@ -3966,7 +3979,7 @@ func TestGroupMemberPayloadUserIDFormats(t *testing.T) {
|
||||
User: prefixed.UserId(),
|
||||
ModeWant: types.ModeJoin,
|
||||
ModeGiven: types.ModeJoin,
|
||||
}, true)
|
||||
}, true, "")
|
||||
if fromPrefixed["user_id"] != prefixed.UserId() {
|
||||
t.Fatalf("prefixed uid user_id: got %#v, want %s", fromPrefixed["user_id"], prefixed.UserId())
|
||||
}
|
||||
@@ -3989,8 +4002,9 @@ func TestServeIMGroupMemberProfile(t *testing.T) {
|
||||
UserID: 42,
|
||||
PeerID: peer,
|
||||
Topic: types.Uid(42).P2PName(peer),
|
||||
Relationship: types.RelationshipNone,
|
||||
CanSend: false,
|
||||
Relationship: types.RelationshipFriend,
|
||||
CanSend: true,
|
||||
Remark: "老王",
|
||||
}}
|
||||
defer func() {
|
||||
store.Subs = oldSubs
|
||||
@@ -4024,9 +4038,12 @@ func TestServeIMGroupMemberProfile(t *testing.T) {
|
||||
t.Fatalf("status: got %d, want %d; body=%s", rec.Code, http.StatusOK, rec.Body.String())
|
||||
}
|
||||
data := decodeIMHTTPResponse(t, rec).Data.(map[string]any)
|
||||
if data["relationship"] != types.RelationshipNone || data["signature"] != "hi" || data["role"] != "member" {
|
||||
if data["relationship"] != types.RelationshipFriend || data["signature"] != "hi" || data["role"] != "member" {
|
||||
t.Fatalf("unexpected group member profile response: %#v", data)
|
||||
}
|
||||
if data["display_name"] != "老王" {
|
||||
t.Fatalf("group member profile display name should use friend remark: %#v", data)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServeIMGroupMemberProfileRejectsUserTopic(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user