owpengram-server/internal/rpc/channels_topics.go
2026-07-24 14:50:17 +08:00

114 lines
4.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package rpc
import (
"context"
"github.com/iamxvbaba/td/tg"
"telesrv/internal/domain"
)
func (r *Router) onChannelsToggleForum(ctx context.Context, req *tg.ChannelsToggleForumRequest) (tg.UpdatesClass, error) {
return r.applyChannelAdminStateMutation(ctx, req.Channel, func(ctx context.Context, userID, channelID int64) (domain.Channel, error) {
return r.deps.Channels.SetForum(ctx, userID, channelID, req.Enabled, req.Tabs)
})
}
func (r *Router) onChannelsToggleViewForumAsMessages(ctx context.Context, req *tg.ChannelsToggleViewForumAsMessagesRequest) (tg.UpdatesClass, error) {
if r.deps.Channels == nil {
return nil, notImplementedErr()
}
userID, _, err := r.currentUserID(ctx)
if err != nil {
return nil, internalErr()
}
channelID, err := r.channelIDFromInput(ctx, userID, req.Channel)
if err != nil {
return nil, err
}
changed, err := r.deps.Channels.SetViewForumAsMessages(ctx, userID, channelID, req.Enabled)
if err != nil {
return nil, channelInvalidErr(err)
}
if !changed {
return tgEmptyUpdates(int(r.clock.Now().Unix())), nil
}
r.invalidateRPCProjectionForPeer(userID, domain.Peer{Type: domain.PeerTypeChannel, ID: channelID})
event := domain.UpdateEvent{
Type: domain.UpdateEventChannelViewForum,
Peer: domain.Peer{Type: domain.PeerTypeChannel, ID: channelID},
Bool: req.Enabled,
PtsCount: 1,
Date: int(r.clock.Now().Unix()),
}
if r.deps.Updates != nil {
authKeyID, _ := AuthKeyIDFrom(ctx)
sessionID, _ := SessionIDFrom(ctx)
event, _, err = r.deps.Updates.RecordChannelViewForumAsMessages(ctx, authKeyID, userID, channelID, req.Enabled, rawAuthKeyIDForOrigin(ctx), sessionID)
if err != nil {
return nil, internalErr()
}
}
out := tgUpdateForOutboxEvent(event)
if out == nil {
out = tgEmptyUpdates(event.Date)
}
r.pushUserUpdatesIfNoReliableDispatch(ctx, userID, out)
return out, nil
}
func (r *Router) onMessagesUpdatePinnedMessage(ctx context.Context, req *tg.MessagesUpdatePinnedMessageRequest) (tg.UpdatesClass, error) {
userID, _, err := r.currentUserID(ctx)
if err != nil {
return nil, internalErr()
}
peer, err := r.checkedDomainPeerFromInputPeer(ctx, userID, req.Peer)
if err != nil {
return nil, err
}
if req.ID <= 0 || req.ID > domain.MaxMessageBoxID {
return nil, messageIDInvalidErr()
}
if peer.Type == domain.PeerTypeUser && peer.ID != 0 {
return r.updatePrivatePinnedMessage(ctx, userID, peer, req)
}
if r.deps.Channels == nil {
return nil, notImplementedErr()
}
if peer.Type != domain.PeerTypeChannel || peer.ID == 0 {
return nil, peerIDInvalidErr()
}
res, err := r.deps.Channels.UpdatePinnedMessage(ctx, userID, domain.UpdateChannelPinnedMessageRequest{
UserID: userID,
ChannelID: peer.ID,
MessageID: req.ID,
Pinned: !req.Unpin,
Silent: req.Silent,
Date: int(r.clock.Now().Unix()),
})
if err != nil {
return nil, channelAdminErr(err)
}
r.invalidateRPCProjectionForChannel(res.Channel.ID)
updates := r.channelPinnedUpdates(userID, res)
// pin fan-out 异步化(设计 Phase 0与已异步的 unpinAll(channels_stubs.go) 对齐。
// builder 无 Users 数组(仅 pinned update + ChatMin无需 owner 预热。pin 的真实变更由
// UpdatePinnedChannelMessages{pts} 承载、可经 getChannelDifference 兜底bundled 的无 pts
// UpdateChannel 对 pin 冗余pts payload 已含变更),丢弃无害——与 unpinAll 取舍一致。
r.enqueueChannelFanout(ctx, channelFanoutMessageBox, userID, res.Channel.ID, res.Event.Pts, res.Recipients, func(_ context.Context, viewerUserID int64) *tg.Updates {
return r.channelPinnedUpdates(viewerUserID, res)
})
return updates, nil
}
func (r *Router) channelPinnedUpdates(viewerUserID int64, res domain.UpdateChannelPinnedMessageResult) *tg.Updates {
updates := []tg.UpdateClass(nil)
if update := tgChannelUpdate(viewerUserID, res.Event); update != nil {
updates = append(updates, update)
}
updates = append(updates, &tg.UpdateChannel{ChannelID: res.Channel.ID})
return &tg.Updates{
Updates: updates,
Chats: []tg.ChatClass{tgChannelChatMin(viewerUserID, res.Channel)},
Date: int(r.clock.Now().Unix()),
Seq: 0,
}
}