This commit is contained in:
onysd 2026-08-24 23:41:58 +03:00
parent a8ff844139
commit ed2e61d32a
2 changed files with 20 additions and 7 deletions

View file

@ -19,11 +19,16 @@ func (s *Service) HandlesInlineBot(botUserID int64) bool {
} }
// OnInlineQuery serves @gif's admin-curated catalog as inline gif results, // OnInlineQuery serves @gif's admin-curated catalog as inline gif results,
// ordered by title relevance to query (see rankGifCatalogEntries). // ordered by title relevance to query (see rankGifCatalogEntries) or, for a
// category-icon tap, filtered to that category (see gifCategoryFromQuery).
// //
// offset/paging is not implemented: the catalog is bounded by // offset/paging is not implemented: filtering/ranking runs over the whole
// MaxGifCatalogEntries, which is MaxBotInlineResults, so one response always // catalog (an operator's library can run into the thousands, see
// carries all of it. // files.Service.ListGifCatalog's doc comment for why that fetch is
// deliberately unbounded), then the result is truncated to
// MaxGifCatalogEntries -- the real per-response cap the client enforces --
// so one response always carries as much of the *relevant* slice as fits,
// not an arbitrary (sort_order, id) prefix of the whole catalog.
// //
// Note TDesktop only ever calls this with a non-empty query: its GIF tab has // Note TDesktop only ever calls this with a non-empty query: its GIF tab has
// no trending panel, and GifsListWidget::searchForGifs returns early on an // no trending panel, and GifsListWidget::searchForGifs returns early on an
@ -52,6 +57,9 @@ func (s *Service) OnInlineQuery(ctx context.Context, botUserID, _ int64, query,
if len(entries) == 0 { if len(entries) == 0 {
return domain.BotInlineResults{Gallery: true}, true, nil return domain.BotInlineResults{Gallery: true}, true, nil
} }
if len(entries) > domain.MaxGifCatalogEntries {
entries = entries[:domain.MaxGifCatalogEntries]
}
ids := make([]int64, len(entries)) ids := make([]int64, len(entries))
for i, e := range entries { for i, e := range entries {
ids[i] = e.DocumentID ids[i] = e.DocumentID

View file

@ -152,13 +152,18 @@ func (s *Service) AdminListGifCatalog(ctx context.Context) ([]domain.GifCatalogE
} }
// ListGifCatalog is bots.gifCatalogSource's read: onlyEnabled=true is what // ListGifCatalog is bots.gifCatalogSource's read: onlyEnabled=true is what
// @gif actually serves, capped at domain.MaxGifCatalogEntries -- the real // @gif actually serves. Deliberately unbounded, not capped at
// per-response limit the client enforces. // domain.MaxGifCatalogEntries here -- bots.Service filters/ranks by category
// or query text over the *whole* catalog and only then takes the top
// MaxGifCatalogEntries for one response. Capping the fetch itself would
// silently limit that filtering to an arbitrary (sort_order, id) slice of a
// large catalog, e.g. a category tap finding none of its members among the
// first 50 rows and falling back to showing the unfiltered catalog instead.
func (s *Service) ListGifCatalog(ctx context.Context, onlyEnabled bool) ([]domain.GifCatalogEntry, error) { func (s *Service) ListGifCatalog(ctx context.Context, onlyEnabled bool) ([]domain.GifCatalogEntry, error) {
if s.gifCatalog == nil { if s.gifCatalog == nil {
return nil, nil return nil, nil
} }
return s.gifCatalog.ListGifCatalog(ctx, onlyEnabled, domain.MaxGifCatalogEntries) return s.gifCatalog.ListGifCatalog(ctx, onlyEnabled, 0)
} }
// AdminSetGifCatalogEnabled toggles whether an entry is served. // AdminSetGifCatalogEnabled toggles whether an entry is served.