owpengram-server/internal/rpc/channels_read_reactions.go

130 lines
4 KiB
Go

package rpc
import (
"context"
"errors"
"github.com/gotd/td/tg"
"telesrv/internal/domain"
)
func (r *Router) onChannelsReadMessageContents(ctx context.Context, req *tg.ChannelsReadMessageContentsRequest) (bool, error) {
if r.deps.Channels == nil {
return false, notImplementedErr()
}
if req == nil {
return false, inputRequestInvalidErr()
}
userID, _, err := r.currentUserID(ctx)
if err != nil {
return false, internalErr()
}
channelID, err := r.channelIDFromInput(ctx, userID, req.Channel)
if err != nil {
return false, err
}
read, err := r.deps.Channels.ReadMessageContents(ctx, userID, domain.ReadChannelMessageContentsRequest{
UserID: userID,
ChannelID: channelID,
IDs: req.ID,
})
if err != nil {
if errors.Is(err, domain.ErrMessageIDInvalid) {
return false, messageIDInvalidErr()
}
return false, channelInvalidErr(err)
}
if ids := readChannelMessageContentIDs(read.Messages); len(ids) > 0 {
r.pushUserUpdates(ctx, userID, &tg.Updates{
Updates: []tg.UpdateClass{&tg.UpdateChannelReadMessagesContents{
ChannelID: read.Channel.ID,
Messages: ids,
}},
Users: []tg.UserClass{},
Chats: []tg.ChatClass{tgChannelChatMin(userID, read.Channel)},
Date: int(r.clock.Now().Unix()),
Seq: 0,
})
}
if len(read.ClearedUnreadReactionMessageIDs) > 0 {
r.pushUserUpdates(ctx, userID, r.channelMessagesReactionsUpdates(ctx, userID, domain.ChannelMessageReactionsResult{
Channel: read.Channel,
Messages: read.Messages,
}, read.ClearedUnreadReactionMessageIDs))
}
return true, nil
}
func (r *Router) onChannelsReadHistory(ctx context.Context, req *tg.ChannelsReadHistoryRequest) (bool, error) {
if r.deps.Channels == nil {
return true, nil
}
userID, _, err := r.currentUserID(ctx)
if err != nil {
return false, internalErr()
}
channelID, err := r.channelIDFromInput(ctx, userID, req.Channel)
if err != nil {
return false, err
}
read, err := r.deps.Channels.ReadHistory(ctx, userID, domain.ReadChannelHistoryRequest{
UserID: userID,
ChannelID: channelID,
MaxID: req.MaxID,
Date: int(r.clock.Now().Unix()),
})
if err != nil {
return false, channelInvalidErr(err)
}
if _, err := r.recordChannelReadInbox(ctx, userID, read); err != nil {
return false, err
}
r.pushChannelReadOutboxUpdates(ctx, read.ChannelID, read.OutboxUpdates)
r.advanceForumGeneralReadAfterChannelRead(ctx, userID, read)
return true, nil
}
func domainChannelReactionPolicy(req *tg.MessagesSetChatAvailableReactionsRequest) (domain.ChannelReactionPolicy, error) {
if req == nil || req.AvailableReactions == nil {
return domain.ChannelReactionPolicy{}, tgerr400("REACTION_INVALID")
}
if req.ReactionsLimit < 0 || req.ReactionsLimit > domain.MaxChannelReactionsLimit {
return domain.ChannelReactionPolicy{}, limitInvalidErr()
}
policy := domain.ChannelReactionPolicy{
Limit: req.ReactionsLimit,
PaidEnabled: req.PaidEnabled,
}
switch reactions := req.AvailableReactions.(type) {
case *tg.ChatReactionsNone:
policy.Type = domain.ChannelReactionPolicyNone
case *tg.ChatReactionsAll:
policy.Type = domain.ChannelReactionPolicyAll
policy.AllowCustom = reactions.AllowCustom
case *tg.ChatReactionsSome:
if len(reactions.Reactions) > domain.MaxChannelReactionTypes {
return domain.ChannelReactionPolicy{}, limitInvalidErr()
}
policy.Type = domain.ChannelReactionPolicySome
seen := make(map[string]struct{}, len(reactions.Reactions))
for _, reaction := range reactions.Reactions {
parsed, err := domainMessageReactionFromTL(reaction)
if err != nil {
return domain.ChannelReactionPolicy{}, tgerr400("REACTION_INVALID")
}
key := parsed.Key()
if _, ok := seen[key]; ok {
continue
}
seen[key] = struct{}{}
switch parsed.Type {
case domain.MessageReactionEmoji:
policy.Emoticons = append(policy.Emoticons, parsed.Emoticon)
case domain.MessageReactionCustomEmoji:
policy.CustomEmojiIDs = append(policy.CustomEmojiIDs, parsed.DocumentID)
}
}
default:
return domain.ChannelReactionPolicy{}, tgerr400("REACTION_INVALID")
}
return policy, nil
}