package memory import ( "context" "telesrv/internal/domain" ) func (s *ChannelStore) GetChannelMessageViews(_ context.Context, req domain.ChannelMessageViewsRequest) (domain.ChannelMessageViewsResult, error) { if req.UserID == 0 || req.ChannelID == 0 { return domain.ChannelMessageViewsResult{}, domain.ErrChannelInvalid } if len(req.IDs) == 0 { return domain.ChannelMessageViewsResult{Views: map[int]int{}, Replies: map[int]*domain.ChannelMessageReplies{}}, nil } if len(req.IDs) > domain.MaxGetMessageIDs { return domain.ChannelMessageViewsResult{}, domain.ErrChannelInvalid } s.mu.Lock() defer s.mu.Unlock() channel, member, err := s.channelAndMemberLocked(req.UserID, req.ChannelID) if err != nil { return domain.ChannelMessageViewsResult{}, err } wanted := make(map[int]struct{}, len(req.IDs)) for _, id := range req.IDs { if id <= 0 || id > domain.MaxMessageBoxID { return domain.ChannelMessageViewsResult{}, domain.ErrMessageIDInvalid } wanted[id] = struct{}{} } visible := make(map[int]struct{}, len(wanted)) for _, msg := range s.messages[req.ChannelID] { if _, ok := wanted[msg.ID]; !ok { continue } if msg.Deleted || msg.ID <= member.AvailableMinID { continue } visible[msg.ID] = struct{}{} } if s.msgViews[req.ChannelID] == nil { s.msgViews[req.ChannelID] = make(map[int]int) } if s.msgViewers[req.ChannelID] == nil { s.msgViewers[req.ChannelID] = make(map[int]map[int64]struct{}) } for id := range visible { if req.Increment { if s.msgViewers[req.ChannelID][id] == nil { s.msgViewers[req.ChannelID][id] = make(map[int64]struct{}) } if _, seen := s.msgViewers[req.ChannelID][id][req.UserID]; !seen { s.msgViewers[req.ChannelID][id][req.UserID] = struct{}{} s.msgViews[req.ChannelID][id]++ } } } out := make(map[int]int, len(visible)) replies := make(map[int]*domain.ChannelMessageReplies, len(visible)) peerSeen := make(map[domain.Peer]struct{}, len(visible)) peers := make([]domain.Peer, 0, len(visible)) for id := range visible { out[id] = s.msgViews[req.ChannelID][id] } for _, msg := range s.messages[req.ChannelID] { if _, ok := visible[msg.ID]; !ok { continue } peer := msg.From if peer.ID == 0 && msg.SenderUserID != 0 { peer = domain.Peer{Type: domain.PeerTypeUser, ID: msg.SenderUserID} } if peer.ID != 0 { if _, ok := peerSeen[peer]; !ok { peerSeen[peer] = struct{}{} peers = append(peers, peer) } } if reply := s.channelMessageRepliesLocked(req.UserID, req.ChannelID, msg); reply != nil { replies[msg.ID] = reply } } return domain.ChannelMessageViewsResult{Channel: channel, Views: out, Replies: replies, Peers: peers}, nil }