Skip to content

Commit

Permalink
third line
Browse files Browse the repository at this point in the history
  • Loading branch information
nkonev committed Jan 23, 2025
1 parent 2483c00 commit 3a50aa7
Show file tree
Hide file tree
Showing 11 changed files with 204 additions and 45 deletions.
2 changes: 2 additions & 0 deletions chat/config/config-dev/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ otlp:
endpoint: "localhost:4317"

previewMaxTextSize: 240
previewMaxTextSizeDb: 280

# Along with resending, it makes all files in private chat available to GET by any logged in user
canResendFromTetATet: true

Expand Down
85 changes: 76 additions & 9 deletions chat/db/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,11 @@ type Blog struct {

type ChatWithParticipants struct {
Chat
ParticipantsIds []int64
ParticipantsCount int
IsAdmin bool
ParticipantsIds []int64
ParticipantsCount int
IsAdmin bool
LastMessagePreview *string
LastMessageOwnerId *int64
}

// CreateChat creates a new chat.
Expand Down Expand Up @@ -209,24 +211,38 @@ func getChatSearchClause(additionalFoundUserIds []int64) string {
)
}

func convertToWithParticipants(ctx context.Context, db CommonOperations, chat *Chat, behalfUserId int64, participantsSize, participantsOffset int) (*ChatWithParticipants, error) {
if ids, err := db.GetParticipantIds(ctx, chat.Id, participantsSize, participantsOffset); err != nil {
func convertToWithParticipants(ctx context.Context, co CommonOperations, chat *Chat, behalfUserId int64, participantsSize, participantsOffset int) (*ChatWithParticipants, error) {
if ids, err := co.GetParticipantIds(ctx, chat.Id, participantsSize, participantsOffset); err != nil {
return nil, err
} else {
admin, err := db.IsAdmin(ctx, behalfUserId, chat.Id)
admin, err := co.IsAdmin(ctx, behalfUserId, chat.Id)
if err != nil {
return nil, err
}
participantsCount, err := db.GetParticipantsCount(ctx, chat.Id)
participantsCount, err := co.GetParticipantsCount(ctx, chat.Id)
if err != nil {
return nil, err
}

messagePreviews, err := getLastMessagePreview(ctx, co, []int64{chat.Id})
if err != nil {
return nil, err
}

ccc := &ChatWithParticipants{
Chat: *chat,
ParticipantsIds: ids,
IsAdmin: admin,
ParticipantsCount: participantsCount,
}

messagePreview := messagePreviews[chat.Id]

if messagePreview != nil {
ccc.LastMessagePreview = &messagePreview.LastMessagePreview
ccc.LastMessageOwnerId = &messagePreview.LastMessageOwnerId
}

return ccc, nil
}
}
Expand All @@ -245,7 +261,7 @@ type ParticipantIds struct {
ParticipantIds []int64
}

func convertToWithParticipantsBatch(chat *Chat, participantIdsBatch []*ParticipantIds, isAdminBatch map[int64]bool, participantsCountBatch map[int64]int) (*ChatWithParticipants, error) {
func convertToWithParticipantsBatch(chat *Chat, participantIdsBatch []*ParticipantIds, isAdminBatch map[int64]bool, participantsCountBatch map[int64]int, messagePreviewsBatch map[int64]*LastMessagePreview) (*ChatWithParticipants, error) {
participantsCount := participantsCountBatch[chat.Id]

var participantsIds []int64 = make([]int64, 0)
Expand All @@ -258,15 +274,61 @@ func convertToWithParticipantsBatch(chat *Chat, participantIdsBatch []*Participa

admin := isAdminBatch[chat.Id]

messagePreview := messagePreviewsBatch[chat.Id]

ccc := &ChatWithParticipants{
Chat: *chat,
ParticipantsIds: participantsIds,
IsAdmin: admin,
ParticipantsCount: participantsCount,
}

if messagePreview != nil {
ccc.LastMessagePreview = &messagePreview.LastMessagePreview
ccc.LastMessageOwnerId = &messagePreview.LastMessageOwnerId
}

return ccc, nil
}

type LastMessagePreview struct {
LastMessagePreview string
LastMessageOwnerId int64
}

func getLastMessagePreview(ctx context.Context, co CommonOperations, chatIds []int64) (map[int64]*LastMessagePreview, error) {
ret := map[int64]*LastMessagePreview{}
if len(chatIds) == 0 {
return ret, nil
}

maxPrevSizeDb := viper.GetInt("previewMaxTextSizeDb")

bldr := ""
for i, chatId := range chatIds {
if i != 0 {
bldr += " UNION ALL "
}
bldr += fmt.Sprintf("(select %v, substring(strip_tags(text), 0, %v), owner_id from message_chat_%v order by id desc limit 1)", chatId, maxPrevSizeDb, chatId)
}
rows, err := co.QueryContext(ctx, bldr)
if err != nil {
return nil, eris.Wrap(err, "error during interacting with db")
}
defer rows.Close()

for rows.Next() {
item := &LastMessagePreview{}
var chatId int64
if err = rows.Scan(&chatId, &item.LastMessagePreview, &item.LastMessageOwnerId); err != nil {
return nil, eris.Wrap(err, "error during interacting with db")
} else if chatId != 0 {
ret[chatId] = item
}
}
return ret, nil
}

func getChats(ctx context.Context, co CommonOperations, participantId int64, limit int, leftRowNumber, rightRowNumber int64, orderDirection string, searchString, searchStringPercents string, additionalFoundUserIds []int64) ([]*Chat, error) {
list := make([]*Chat, 0)

Expand Down Expand Up @@ -538,10 +600,15 @@ func getChatsWithParticipantsCommon(ctx context.Context, commonOps CommonOperati
return nil, err
}

messagePreviewsBatch, err := getLastMessagePreview(ctx, commonOps, chatIds)
if err != nil {
return nil, err
}

list := make([]*ChatWithParticipants, 0)

for _, cc := range chats {
if ccc, err := convertToWithParticipantsBatch(cc, participantIdsBatch, isAdminBatch, participantsCountBatch); err != nil {
if ccc, err := convertToWithParticipantsBatch(cc, participantIdsBatch, isAdminBatch, participantsCountBatch, messagePreviewsBatch); err != nil {
return nil, err
} else {
list = append(list, ccc)
Expand Down
3 changes: 2 additions & 1 deletion chat/dto/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ type ChatDeletedDto struct {

type ChatDto struct {
BaseChatDto
Participants []*User `json:"participants"`
Participants []*User `json:"participants"`
LastMessagePreview *string `json:"lastMessagePreview"`
}

type ChatDtoWithTetATet interface {
Expand Down
71 changes: 42 additions & 29 deletions chat/handlers/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,27 +120,33 @@ func (ch *ChatHandler) getChats(ctx context.Context, tx *db.Tx, userId int64, si
return nil, err
}

var participantIdSet = map[int64]bool{}
var participantOftetAtetIdSet = map[int64]bool{}
for _, dc := range dbChats {
for _, participantId := range dc.ParticipantsIds {
participantIdSet[participantId] = true
if dc.TetATet {
participantOftetAtetIdSet[participantId] = true
}
}
}
for _, dbch := range dbChats {
if dbch.LastMessageOwnerId != nil {
participantIdSet[*dbch.LastMessageOwnerId] = true
}
}
var users = getUsersRemotelyOrEmpty(ctx, ch.lgr, participantIdSet, ch.restClient)

chatDtos := make([]*dto.ChatDto, 0)
for _, cc := range dbChats {
messages := unreadMessageBatch[cc.Id]
isParticipant := membership[cc.Id]

cd := convertToDto(cc, true, []*dto.User{}, messages, isParticipant)
cd := ch.convertToDto(cc, true, users, messages, isParticipant)

chatDtos = append(chatDtos, cd)
}

var participantIdSet = map[int64]bool{}
var participantOftetAtetIdSet = map[int64]bool{}
for _, chatDto := range chatDtos {
for _, participantId := range chatDto.ParticipantIds {
participantIdSet[participantId] = true
if chatDto.IsTetATet {
participantOftetAtetIdSet[participantId] = true
}
}
}
var users = getUsersRemotelyOrEmpty(ctx, ch.lgr, participantIdSet, ch.restClient)
tetAtetOnlines, err := ch.getParticipantsOnlineForTetATetMap(ctx, participantOftetAtetIdSet)
if err != nil {
ch.lgr.WithTracing(ctx).Warnf("Something bad duringh getting tetAtetOnlines: %v", err)
Expand All @@ -149,7 +155,6 @@ func (ch *ChatHandler) getChats(ctx context.Context, tx *db.Tx, userId int64, si
for _, participantId := range chatDto.ParticipantIds {
user := users[participantId]
if user != nil {
chatDto.Participants = append(chatDto.Participants, user)
utils.ReplaceForTetATet(chatDto, tetAtetOnlines, user, userId, len(chatDto.ParticipantIds) == 1)
}
}
Expand Down Expand Up @@ -280,8 +285,6 @@ func (ch *ChatHandler) getChatCommon(
) (*dto.ChatDto, error) {
fixedParticipantsSize := utils.FixSize(participantsSize)

var users []*dto.User = []*dto.User{}

cc, err := co.GetChatWithParticipants(ctx, performPersonalization, behalfParticipantId, chatId, fixedParticipantsSize, participantsOffset)
if err != nil {
return nil, err
Expand All @@ -290,11 +293,15 @@ func (ch *ChatHandler) getChatCommon(
return nil, nil
}

users, err = ch.restClient.GetUsers(ctx, cc.ParticipantsIds)
if err != nil {
users = []*dto.User{}
ch.lgr.WithTracing(ctx).Warn("Error during getting users from aaa")
participantIdSet := map[int64]bool{}
if cc.LastMessageOwnerId != nil {
participantIdSet[*cc.LastMessageOwnerId] = true
}
for _, pp := range cc.ParticipantsIds {
participantIdSet[pp] = true
}

var users = getUsersRemotelyOrEmpty(ctx, ch.lgr, participantIdSet, ch.restClient)

var unreadMessages int64
var isParticipant bool
Expand All @@ -311,7 +318,7 @@ func (ch *ChatHandler) getChatCommon(
}
}

chatDto := convertToDto(cc, performPersonalization, users, unreadMessages, isParticipant)
chatDto := ch.convertToDto(cc, performPersonalization, users, unreadMessages, isParticipant)

if performPersonalization && chatDto.IsTetATet {
tetAtetOnlines, err := ch.getParticipantsOnlineForTetATetMap(ctx, utils.GetInt64BoolMap(cc.ParticipantsIds))
Expand All @@ -320,9 +327,7 @@ func (ch *ChatHandler) getChatCommon(
}

for _, participant := range users {

isSingleTetATetParticipant := len(cc.ParticipantsIds) == 1

utils.ReplaceForTetATet(chatDto, tetAtetOnlines, participant, behalfParticipantId, isSingleTetATetParticipant)
}
}
Expand Down Expand Up @@ -476,7 +481,7 @@ func (ch *ChatHandler) IsFreshChatsPage(c echo.Context) error {
})
}

func convertToDto(c *db.ChatWithParticipants, performPersonalization bool, users []*dto.User, unreadMessages int64, participant bool) *dto.ChatDto {
func (ch *ChatHandler) convertToDto(c *db.ChatWithParticipants, performPersonalization bool, users map[int64]*dto.User, unreadMessages int64, participant bool) *dto.ChatDto {
b := dto.BaseChatDto{
Id: c.Id,
Name: c.Title,
Expand Down Expand Up @@ -504,18 +509,26 @@ func convertToDto(c *db.ChatWithParticipants, performPersonalization bool, users
// set participant order as in c.ParticipantsIds
orderedParticipants := make([]*dto.User, 0)
for _, participantId := range c.ParticipantsIds {
for _, u := range users {
if u.Id == participantId {
orderedParticipants = append(orderedParticipants, u)
break
}
u := users[participantId]
if u != nil {
orderedParticipants = append(orderedParticipants, u)
}
}

return &dto.ChatDto{
ret := dto.ChatDto{
BaseChatDto: b,
Participants: orderedParticipants,
}

if c.LastMessageOwnerId != nil && c.LastMessagePreview != nil {
u := users[*c.LastMessageOwnerId]
if u != nil {
preview := createMessagePreview(ch.stripTagsPolicy, *c.LastMessagePreview, u.Login)
ret.LastMessagePreview = &preview
}
}

return &ret
}

func (ch *ChatHandler) CreateChat(c echo.Context) error {
Expand Down
3 changes: 2 additions & 1 deletion event/dto/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ type ChatDeletedDto struct {

type ChatDto struct {
BaseChatDto
Participants []*User `json:"participants"`
Participants []*User `json:"participants"`
LastMessagePreview *string `json:"lastMessagePreview"`
}

type ChatUnreadMessageChanged struct {
Expand Down
Loading

0 comments on commit 3a50aa7

Please sign in to comment.