feat: sync durable moderation and appeals
This commit is contained in:
parent
e1a95c7318
commit
9f467f4be7
140 changed files with 13730 additions and 316 deletions
83
internal/rpc/privacy_voice.go
Normal file
83
internal/rpc/privacy_voice.go
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/iamxvbaba/td/tg"
|
||||
|
||||
"telesrv/internal/domain"
|
||||
)
|
||||
|
||||
func (r *Router) ensureVoiceMessagesAllowed(ctx context.Context, senderUserID int64, peer domain.Peer, voiceOrRound bool) error {
|
||||
if !voiceOrRound || peer.Type != domain.PeerTypeUser || peer.ID == 0 || peer.ID == senderUserID || r.deps.Privacy == nil {
|
||||
return nil
|
||||
}
|
||||
allowed, err := r.deps.Privacy.CanSee(ctx, peer.ID, senderUserID, domain.PrivacyKeyVoiceMessages)
|
||||
if err != nil {
|
||||
return internalErr()
|
||||
}
|
||||
if !allowed {
|
||||
return chatSendVoicesForbiddenErr()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// preflightVoiceOrRound inspects upload attributes and referenced documents
|
||||
// before resolveInputMedia materializes any uploaded blob. Referenced document
|
||||
// misses are loaded in one bounded read-model batch.
|
||||
func (r *Router) preflightVoiceOrRound(ctx context.Context, inputs []tg.InputMediaClass) (bool, error) {
|
||||
documentIDs := make([]int64, 0)
|
||||
seen := make(map[int64]struct{})
|
||||
for _, input := range inputs {
|
||||
switch media := input.(type) {
|
||||
case *tg.InputMediaUploadedDocument:
|
||||
if documentAttributesVoiceOrRound(domainDocumentAttributes(media.Attributes)) {
|
||||
return true, nil
|
||||
}
|
||||
case *tg.InputMediaDocument:
|
||||
ids, ok := inputDocumentCandidateIDs(media.ID)
|
||||
if !ok {
|
||||
continue // resolveInputMedia retains MEDIA_INVALID precedence.
|
||||
}
|
||||
for _, id := range ids {
|
||||
if id == 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[id]; ok {
|
||||
continue
|
||||
}
|
||||
seen[id] = struct{}{}
|
||||
documentIDs = append(documentIDs, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(documentIDs) == 0 || r.deps.Files == nil {
|
||||
return false, nil
|
||||
}
|
||||
documents, err := r.deps.Files.GetDocuments(ctx, documentIDs)
|
||||
if err != nil {
|
||||
return false, internalErr()
|
||||
}
|
||||
for _, document := range documents {
|
||||
if documentAttributesVoiceOrRound(document.Attributes) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func documentAttributesVoiceOrRound(attributes []domain.DocumentAttribute) bool {
|
||||
for _, attribute := range attributes {
|
||||
switch attribute.Kind {
|
||||
case domain.DocAttrAudio:
|
||||
if attribute.Voice {
|
||||
return true
|
||||
}
|
||||
case domain.DocAttrVideo:
|
||||
if attribute.RoundMessage {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue