owpengram-server/internal/rpc/payments_star_gift_collections.go
2026-07-16 12:38:53 +08:00

235 lines
7 KiB
Go

package rpc
import (
"context"
"errors"
"strings"
"github.com/iamxvbaba/td/tg"
"telesrv/internal/domain"
)
func (r *Router) onPaymentsGetStarGiftCollections(ctx context.Context, req *tg.PaymentsGetStarGiftCollectionsRequest) (tg.PaymentsStarGiftCollectionsClass, error) {
if req == nil {
return nil, inputRequestInvalidErr()
}
userID, _, err := r.currentUserID(ctx)
if err != nil {
return nil, internalErr()
}
owner, err := r.starGiftOwnerPeer(ctx, userID, req.Peer)
if err != nil {
return nil, err
}
if r.deps.Gifts == nil {
return &tg.PaymentsStarGiftCollections{Collections: []tg.StarGiftCollection{}}, nil
}
collections, err := r.deps.Gifts.ListCollections(ctx, owner)
if err != nil {
return nil, starGiftCollectionErr(err)
}
if req.Hash != 0 && req.Hash == domain.StarGiftCollectionsHash(collections) {
return &tg.PaymentsStarGiftCollectionsNotModified{}, nil
}
return &tg.PaymentsStarGiftCollections{Collections: tgStarGiftCollections(collections)}, nil
}
func (r *Router) onPaymentsCreateStarGiftCollection(ctx context.Context, req *tg.PaymentsCreateStarGiftCollectionRequest) (*tg.StarGiftCollection, error) {
if req == nil || r.deps.Gifts == nil {
return nil, inputRequestInvalidErr()
}
userID, _, err := r.currentUserID(ctx)
if err != nil {
return nil, internalErr()
}
owner, err := r.starGiftOwnerPeer(ctx, userID, req.Peer)
if err != nil {
return nil, err
}
if err := r.ensureCanManageStarGiftOwner(ctx, userID, owner); err != nil {
return nil, err
}
ids, err := r.resolveStarGiftCollectionRefs(ctx, userID, owner, req.Stargift)
if err != nil {
return nil, err
}
collection, err := r.deps.Gifts.CreateCollection(ctx, owner, strings.TrimSpace(req.Title), ids)
if err != nil {
return nil, starGiftCollectionErr(err)
}
r.invalidateStarGiftOwnerProjection(owner)
out := tgStarGiftCollection(collection)
return &out, nil
}
func (r *Router) onPaymentsUpdateStarGiftCollection(ctx context.Context, req *tg.PaymentsUpdateStarGiftCollectionRequest) (*tg.StarGiftCollection, error) {
if req == nil || req.CollectionID <= 0 || r.deps.Gifts == nil {
return nil, inputRequestInvalidErr()
}
userID, _, err := r.currentUserID(ctx)
if err != nil {
return nil, internalErr()
}
owner, err := r.starGiftOwnerPeer(ctx, userID, req.Peer)
if err != nil {
return nil, err
}
if err := r.ensureCanManageStarGiftOwner(ctx, userID, owner); err != nil {
return nil, err
}
patch := domain.StarGiftCollectionPatch{}
if title, ok := req.GetTitle(); ok {
title = strings.TrimSpace(title)
patch.Title = &title
}
if refs, ok := req.GetDeleteStargift(); ok {
patch.DeleteIDs, err = r.resolveStarGiftCollectionRefs(ctx, userID, owner, refs)
if err != nil {
return nil, err
}
}
if refs, ok := req.GetAddStargift(); ok {
patch.AddIDs, err = r.resolveStarGiftCollectionRefs(ctx, userID, owner, refs)
if err != nil {
return nil, err
}
}
if refs, ok := req.GetOrder(); ok {
patch.Order, err = r.resolveStarGiftCollectionRefs(ctx, userID, owner, refs)
if err != nil {
return nil, err
}
}
collection, err := r.deps.Gifts.UpdateCollection(ctx, owner, req.CollectionID, patch)
if err != nil {
return nil, starGiftCollectionErr(err)
}
r.invalidateStarGiftOwnerProjection(owner)
out := tgStarGiftCollection(collection)
return &out, nil
}
func (r *Router) onPaymentsDeleteStarGiftCollection(ctx context.Context, req *tg.PaymentsDeleteStarGiftCollectionRequest) (bool, error) {
if req == nil || req.CollectionID <= 0 || r.deps.Gifts == nil {
return false, inputRequestInvalidErr()
}
userID, _, err := r.currentUserID(ctx)
if err != nil {
return false, internalErr()
}
owner, err := r.starGiftOwnerPeer(ctx, userID, req.Peer)
if err != nil {
return false, err
}
if err := r.ensureCanManageStarGiftOwner(ctx, userID, owner); err != nil {
return false, err
}
deleted, err := r.deps.Gifts.DeleteCollection(ctx, owner, req.CollectionID)
if err != nil {
return false, starGiftCollectionErr(err)
}
if !deleted {
return false, starGiftCollectionErr(domain.ErrStarGiftCollectionNotFound)
}
r.invalidateStarGiftOwnerProjection(owner)
return true, nil
}
func (r *Router) onPaymentsReorderStarGiftCollections(ctx context.Context, req *tg.PaymentsReorderStarGiftCollectionsRequest) (bool, error) {
if req == nil || r.deps.Gifts == nil {
return false, inputRequestInvalidErr()
}
userID, _, err := r.currentUserID(ctx)
if err != nil {
return false, internalErr()
}
owner, err := r.starGiftOwnerPeer(ctx, userID, req.Peer)
if err != nil {
return false, err
}
if err := r.ensureCanManageStarGiftOwner(ctx, userID, owner); err != nil {
return false, err
}
if err := r.deps.Gifts.ReorderCollections(ctx, owner, req.Order); err != nil {
return false, starGiftCollectionErr(err)
}
return true, nil
}
func (r *Router) onPaymentsToggleStarGiftsPinnedToTop(ctx context.Context, req *tg.PaymentsToggleStarGiftsPinnedToTopRequest) (bool, error) {
if req == nil || r.deps.Gifts == nil {
return false, inputRequestInvalidErr()
}
userID, _, err := r.currentUserID(ctx)
if err != nil {
return false, internalErr()
}
owner, err := r.starGiftOwnerPeer(ctx, userID, req.Peer)
if err != nil {
return false, err
}
if err := r.ensureCanManageStarGiftOwner(ctx, userID, owner); err != nil {
return false, err
}
ids, err := r.resolveStarGiftCollectionRefs(ctx, userID, owner, req.Stargift)
if err != nil {
return false, err
}
if err := r.deps.Gifts.SetPinned(ctx, owner, ids); err != nil {
return false, starGiftCollectionErr(err)
}
r.invalidateStarGiftOwnerProjection(owner)
return true, nil
}
func (r *Router) resolveStarGiftCollectionRefs(ctx context.Context, userID int64, owner domain.Peer, refs []tg.InputSavedStarGiftClass) ([]int64, error) {
if len(refs) > domain.MaxStarGiftCollectionItems {
return nil, inputRequestInvalidErr()
}
domainRefs := make([]domain.SavedStarGiftRef, 0, len(refs))
for _, input := range refs {
ref, ok, err := r.starGiftRefFromInput(ctx, userID, input)
if err != nil {
return nil, err
}
if !ok || ref.Owner != owner {
return nil, starGiftInvalidErr()
}
domainRefs = append(domainRefs, ref)
}
ids, err := r.deps.Gifts.ResolveSavedIDs(ctx, owner, domainRefs)
if err != nil {
return nil, starGiftCollectionErr(err)
}
return ids, nil
}
func tgStarGiftCollections(in []domain.StarGiftCollection) []tg.StarGiftCollection {
out := make([]tg.StarGiftCollection, 0, len(in))
for _, collection := range in {
out = append(out, tgStarGiftCollection(collection))
}
return out
}
func tgStarGiftCollection(in domain.StarGiftCollection) tg.StarGiftCollection {
return tg.StarGiftCollection{
CollectionID: in.CollectionID,
Title: in.Title,
GiftsCount: len(in.GiftIDs),
Hash: in.Hash,
}
}
func starGiftCollectionErr(err error) error {
switch {
case errors.Is(err, domain.ErrStarGiftNotFound),
errors.Is(err, domain.ErrStarGiftCollectibleInvalid),
errors.Is(err, domain.ErrStarGiftCollectionNotFound),
errors.Is(err, domain.ErrStarGiftCollectionsFull):
return inputRequestInvalidErr()
default:
return internalErr()
}
}