Sync profile source and message topic seq
This commit is contained in:
@@ -50,9 +50,13 @@ func stampTenantUser(id t.TenantID, user *t.User) *t.User {
|
||||
type profileUserRow struct {
|
||||
TenantID t.TenantID `db:"tenant_id"`
|
||||
ID string `db:"id"`
|
||||
Username string
|
||||
CreatedAt time.Time `db:"createdat"`
|
||||
UpdatedAt time.Time `db:"updatedat"`
|
||||
State t.ObjState `db:"state"`
|
||||
StateAt *time.Time `db:"stateat"`
|
||||
Access t.DefaultAccess
|
||||
Phone string `db:"phone"`
|
||||
LastSeen sql.NullTime `db:"lastseen"`
|
||||
UserAgent string `db:"useragent"`
|
||||
Public any `db:"public"`
|
||||
@@ -80,8 +84,31 @@ func (row profileUserRow) profilePublic() any {
|
||||
return profilePublicFromFields(common.FromJSON(row.Public), row.ProfileNickname, row.ProfileAvatarFileID)
|
||||
}
|
||||
|
||||
func profileUserFromRow(row profileUserRow) t.User {
|
||||
user := t.User{
|
||||
ObjHeader: t.ObjHeader{
|
||||
Id: row.ID,
|
||||
CreatedAt: row.CreatedAt,
|
||||
UpdatedAt: row.effectiveUpdatedAt(),
|
||||
},
|
||||
TenantID: row.TenantID,
|
||||
State: row.State,
|
||||
StateAt: row.StateAt,
|
||||
Username: row.Username,
|
||||
Access: row.Access,
|
||||
LastSeen: row.lastSeen(),
|
||||
UserAgent: row.UserAgent,
|
||||
Phone: row.Phone,
|
||||
Public: row.profilePublic(),
|
||||
Trusted: common.FromJSON(row.Trusted),
|
||||
}
|
||||
user.SetUid(common.EncodeUidString(row.ID))
|
||||
return user
|
||||
}
|
||||
|
||||
func profilePublicFromFields(base any, nickname, avatarFileID sql.NullString) any {
|
||||
public := publicMap(base)
|
||||
clearProfilePublicFields(public)
|
||||
if nickname.Valid {
|
||||
value := strings.TrimSpace(nickname.String)
|
||||
if value != "" {
|
||||
@@ -99,6 +126,29 @@ func profilePublicFromFields(base any, nickname, avatarFileID sql.NullString) an
|
||||
return public
|
||||
}
|
||||
|
||||
func clearProfilePublicFields(public map[string]any) {
|
||||
for _, key := range []string{"display_name", "nickname", "fn", "name", "avatar_file_id", "photo", "avatar"} {
|
||||
delete(public, key)
|
||||
}
|
||||
}
|
||||
|
||||
func profileSeedFromPublic(public any) (nickname, avatarFileID string) {
|
||||
values := publicMap(public)
|
||||
for _, key := range []string{"display_name", "nickname", "fn", "name"} {
|
||||
if value := strings.TrimSpace(fmt.Sprint(values[key])); value != "" && value != "<nil>" {
|
||||
nickname = value
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, key := range []string{"avatar_file_id", "photo", "avatar"} {
|
||||
if value := strings.TrimSpace(fmt.Sprint(values[key])); value != "" && value != "<nil>" {
|
||||
avatarFileID = value
|
||||
break
|
||||
}
|
||||
}
|
||||
return nickname, avatarFileID
|
||||
}
|
||||
|
||||
func publicMap(value any) map[string]any {
|
||||
switch public := value.(type) {
|
||||
case map[string]any:
|
||||
@@ -282,9 +332,12 @@ func (a *adapter) TenantUserGet(id t.TenantID, uid t.Uid) (*t.User, error) {
|
||||
if cancel != nil {
|
||||
defer cancel()
|
||||
}
|
||||
var user t.User
|
||||
err = a.db.GetContext(ctx, &user, `SELECT tenant_id,id,username,createdat,updatedat,state,stateat,access,lastseen,useragent,
|
||||
COALESCE(phone,'') AS phone,public,trusted FROM im_users WHERE tenant_id=? AND id=? AND state!=?`,
|
||||
var row profileUserRow
|
||||
err = a.db.GetContext(ctx, &row, `SELECT u.tenant_id,u.id,u.username,u.createdat,u.updatedat,u.state,u.stateat,u.access,u.lastseen,u.useragent,
|
||||
COALESCE(u.phone,'') AS phone,u.public,u.trusted,
|
||||
p.nickname AS profile_nickname,p.avatar_file_id AS profile_avatar_file_id,p.updated_at AS profile_updated_at
|
||||
FROM im_users AS u LEFT JOIN im_user_profiles AS p ON p.tenant_id=u.tenant_id AND p.user_id=u.id
|
||||
WHERE u.tenant_id=? AND u.id=? AND u.state!=?`,
|
||||
id, decodeUID(uid), t.StateDeleted)
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
@@ -292,7 +345,7 @@ func (a *adapter) TenantUserGet(id t.TenantID, uid t.Uid) (*t.User, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
scanTenantUser(&user)
|
||||
user := profileUserFromRow(row)
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
@@ -9264,8 +9317,10 @@ func (a *adapter) TenantUserSearch(id t.TenantID, viewer t.Uid, queryText, searc
|
||||
if cancel != nil {
|
||||
defer cancel()
|
||||
}
|
||||
rows, err := a.db.QueryxContext(ctx, `SELECT DISTINCT u.id,u.username,u.createdat,u.updatedat,u.state,u.stateat,u.access,u.lastseen,u.useragent,
|
||||
COALESCE(u.phone,'') AS phone,u.public,u.trusted FROM im_users AS u `+strings.Join(joins, " ")+`
|
||||
rows, err := a.db.QueryxContext(ctx, `SELECT DISTINCT u.tenant_id,u.id,u.username,u.createdat,u.updatedat,u.state,u.stateat,u.access,u.lastseen,u.useragent,
|
||||
COALESCE(u.phone,'') AS phone,u.public,u.trusted,
|
||||
profile.nickname AS profile_nickname,profile.avatar_file_id AS profile_avatar_file_id,profile.updated_at AS profile_updated_at
|
||||
FROM im_users AS u `+strings.Join(joins, " ")+`
|
||||
WHERE `+strings.Join(where, " AND ")+` ORDER BY u.id ASC LIMIT ?`, args...)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
@@ -9274,11 +9329,11 @@ func (a *adapter) TenantUserSearch(id t.TenantID, viewer t.Uid, queryText, searc
|
||||
users := make([]t.User, 0, limit)
|
||||
nextCursor := ""
|
||||
for rows.Next() {
|
||||
var user t.User
|
||||
if err = rows.StructScan(&user); err != nil {
|
||||
var row profileUserRow
|
||||
if err = rows.StructScan(&row); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
scanTenantUser(&user)
|
||||
user := profileUserFromRow(row)
|
||||
if len(users) == limit {
|
||||
nextCursor = strconv.FormatInt(decodeUID(user.Uid()), 10)
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user