chore: refresh gramsrv public release
This commit is contained in:
parent
75cebe8dbf
commit
70b6820474
1274 changed files with 378751 additions and 59919 deletions
276
internal/rpc/messages_reactions_catalog.go
Normal file
276
internal/rpc/messages_reactions_catalog.go
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gotd/td/tg"
|
||||
"hash/fnv"
|
||||
"strconv"
|
||||
"strings"
|
||||
"telesrv/internal/compat/tdesktop"
|
||||
"telesrv/internal/domain"
|
||||
)
|
||||
|
||||
func (r *Router) onMessagesGetTopReactions(ctx context.Context, req *tg.MessagesGetTopReactionsRequest) (tg.MessagesReactionsClass, error) {
|
||||
userID, _, err := r.currentUserID(ctx)
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
if req.Limit < 0 || req.Limit > maxSearchResultsLimit {
|
||||
return nil, limitInvalidErr()
|
||||
}
|
||||
limit := req.Limit
|
||||
if limit == 0 {
|
||||
limit = defaultTopReactionsLimit
|
||||
}
|
||||
reactions := []domain.MessageReaction{}
|
||||
if r.deps.Channels != nil {
|
||||
var err error
|
||||
reactions, err = r.deps.Channels.TopReactions(ctx, userID, limit)
|
||||
if err != nil {
|
||||
return nil, channelInvalidErr(err)
|
||||
}
|
||||
}
|
||||
return messagesReactionsFromDomain(r.reactionsWithCatalogFallback(ctx, reactions, limit), req.Hash), nil
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesGetRecentReactions(ctx context.Context, req *tg.MessagesGetRecentReactionsRequest) (tg.MessagesReactionsClass, error) {
|
||||
userID, _, err := r.currentUserID(ctx)
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
if req.Limit < 0 || req.Limit > maxSearchResultsLimit {
|
||||
return nil, limitInvalidErr()
|
||||
}
|
||||
if r.deps.Channels == nil {
|
||||
return messagesReactionsEmpty(req.Hash), nil
|
||||
}
|
||||
reactions, err := r.deps.Channels.RecentReactions(ctx, userID, req.Limit)
|
||||
if err != nil {
|
||||
return nil, channelInvalidErr(err)
|
||||
}
|
||||
return messagesReactionsFromDomain(reactions, req.Hash), nil
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesClearRecentReactions(ctx context.Context) (bool, error) {
|
||||
userID, _, err := r.currentUserID(ctx)
|
||||
if err != nil {
|
||||
return false, internalErr()
|
||||
}
|
||||
if r.deps.Channels != nil {
|
||||
if err := r.deps.Channels.ClearRecentReactions(ctx, userID); err != nil {
|
||||
return false, channelInvalidErr(err)
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesGetSavedReactionTags(ctx context.Context, req *tg.MessagesGetSavedReactionTagsRequest) (tg.MessagesSavedReactionTagsClass, error) {
|
||||
userID, _, err := r.currentUserID(ctx)
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
if peer, ok := req.GetPeer(); ok && peer != nil {
|
||||
if _, err := r.checkedDomainPeerFromInputPeer(ctx, userID, peer); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return savedReactionTagsEmpty(req.Hash), nil
|
||||
}
|
||||
if r.deps.Channels == nil {
|
||||
return savedReactionTagsEmpty(req.Hash), nil
|
||||
}
|
||||
tags, err := r.deps.Channels.SavedReactionTags(ctx, userID, domain.MaxSavedReactionTags)
|
||||
if err != nil {
|
||||
return nil, channelInvalidErr(err)
|
||||
}
|
||||
return savedReactionTagsFromDomain(tags, req.Hash), nil
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesGetDefaultTagReactions(ctx context.Context, hash int64) (tg.MessagesReactionsClass, error) {
|
||||
if _, _, err := r.currentUserID(ctx); err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
return messagesReactionsEmpty(hash), nil
|
||||
}
|
||||
|
||||
func messagesReactionsEmpty(hash int64) tg.MessagesReactionsClass {
|
||||
if hash != 0 {
|
||||
return &tg.MessagesReactionsNotModified{}
|
||||
}
|
||||
return &tg.MessagesReactions{
|
||||
Hash: 0,
|
||||
Reactions: []tg.ReactionClass{},
|
||||
}
|
||||
}
|
||||
|
||||
func messagesReactionsFromDomain(reactions []domain.MessageReaction, requestHash int64) tg.MessagesReactionsClass {
|
||||
hash := messageReactionListHash(reactions)
|
||||
if hash != 0 && requestHash == hash {
|
||||
return &tg.MessagesReactionsNotModified{}
|
||||
}
|
||||
out := make([]tg.ReactionClass, 0, len(reactions))
|
||||
for _, reaction := range reactions {
|
||||
tgReaction := tgMessageReaction(reaction)
|
||||
if tgReaction != nil {
|
||||
out = append(out, tgReaction)
|
||||
}
|
||||
}
|
||||
return &tg.MessagesReactions{
|
||||
Hash: hash,
|
||||
Reactions: out,
|
||||
}
|
||||
}
|
||||
|
||||
func savedReactionTagsEmpty(_ int64) tg.MessagesSavedReactionTagsClass {
|
||||
return &tg.MessagesSavedReactionTags{
|
||||
Tags: []tg.SavedReactionTag{},
|
||||
Hash: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func savedReactionTagsFromDomain(tags []domain.SavedReactionTag, requestHash int64) tg.MessagesSavedReactionTagsClass {
|
||||
hash := savedReactionTagListHash(tags)
|
||||
if hash != 0 && requestHash == hash {
|
||||
return &tg.MessagesSavedReactionTagsNotModified{}
|
||||
}
|
||||
out := make([]tg.SavedReactionTag, 0, len(tags))
|
||||
for _, tag := range tags {
|
||||
reaction := tgMessageReaction(tag.Reaction)
|
||||
if reaction == nil {
|
||||
continue
|
||||
}
|
||||
item := tg.SavedReactionTag{
|
||||
Reaction: reaction,
|
||||
Count: tag.Count,
|
||||
}
|
||||
if tag.Title != "" {
|
||||
item.SetTitle(tag.Title)
|
||||
}
|
||||
out = append(out, item)
|
||||
}
|
||||
if len(out) == 0 {
|
||||
return savedReactionTagsEmpty(requestHash)
|
||||
}
|
||||
return &tg.MessagesSavedReactionTags{
|
||||
Tags: out,
|
||||
Hash: hash,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Router) reactionsWithCatalogFallback(ctx context.Context, reactions []domain.MessageReaction, limit int) []domain.MessageReaction {
|
||||
return mergeReactionCatalogFallback(reactions, r.availableReactionCatalog(ctx, limit), limit)
|
||||
}
|
||||
|
||||
func (r *Router) availableReactionCatalog(ctx context.Context, limit int) []domain.MessageReaction {
|
||||
if limit <= 0 {
|
||||
return nil
|
||||
}
|
||||
if r.deps.Files != nil {
|
||||
catalog, err := r.deps.Files.ListAvailableReactions(ctx)
|
||||
if err == nil {
|
||||
out := make([]domain.MessageReaction, 0, min(limit, len(catalog)))
|
||||
for _, item := range catalog {
|
||||
emoticon := strings.TrimSpace(item.Reaction)
|
||||
if item.Inactive || emoticon == "" {
|
||||
continue
|
||||
}
|
||||
out = append(out, domain.MessageReaction{Type: domain.MessageReactionEmoji, Emoticon: emoticon})
|
||||
if len(out) >= limit {
|
||||
return out
|
||||
}
|
||||
}
|
||||
if len(out) > 0 {
|
||||
return out
|
||||
}
|
||||
}
|
||||
}
|
||||
return staticReactionCatalog()
|
||||
}
|
||||
|
||||
func staticReactionCatalog() []domain.MessageReaction {
|
||||
emoticons := tdesktop.DefaultReactionEmoticons()
|
||||
out := make([]domain.MessageReaction, 0, len(emoticons))
|
||||
for _, emoticon := range emoticons {
|
||||
out = append(out, domain.MessageReaction{Type: domain.MessageReactionEmoji, Emoticon: emoticon})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func mergeReactionCatalogFallback(reactions, fallback []domain.MessageReaction, limit int) []domain.MessageReaction {
|
||||
if limit <= 0 {
|
||||
return []domain.MessageReaction{}
|
||||
}
|
||||
if limit > domain.MaxTopMessageReactions {
|
||||
limit = domain.MaxTopMessageReactions
|
||||
}
|
||||
out := make([]domain.MessageReaction, 0, limit)
|
||||
seen := make(map[string]struct{}, limit)
|
||||
for _, reaction := range reactions {
|
||||
if !reaction.Valid() {
|
||||
continue
|
||||
}
|
||||
key := reaction.Key()
|
||||
if _, ok := seen[key]; ok {
|
||||
continue
|
||||
}
|
||||
out = append(out, reaction)
|
||||
seen[key] = struct{}{}
|
||||
if len(out) >= limit {
|
||||
return out
|
||||
}
|
||||
}
|
||||
for _, reaction := range fallback {
|
||||
if !reaction.Valid() {
|
||||
continue
|
||||
}
|
||||
key := reaction.Key()
|
||||
if _, ok := seen[key]; ok {
|
||||
continue
|
||||
}
|
||||
out = append(out, reaction)
|
||||
seen[key] = struct{}{}
|
||||
if len(out) >= limit {
|
||||
return out
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func messageReactionListHash(reactions []domain.MessageReaction) int64 {
|
||||
if len(reactions) == 0 {
|
||||
return 0
|
||||
}
|
||||
h := fnv.New64a()
|
||||
for _, reaction := range reactions {
|
||||
_, _ = h.Write([]byte(reaction.Type))
|
||||
_, _ = h.Write([]byte{0})
|
||||
_, _ = h.Write([]byte(reaction.Value()))
|
||||
_, _ = h.Write([]byte{0xff})
|
||||
}
|
||||
sum := int64(h.Sum64() & 0x7fffffffffffffff)
|
||||
if sum == 0 {
|
||||
return 1
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
func savedReactionTagListHash(tags []domain.SavedReactionTag) int64 {
|
||||
if len(tags) == 0 {
|
||||
return 0
|
||||
}
|
||||
h := fnv.New64a()
|
||||
for _, tag := range tags {
|
||||
_, _ = h.Write([]byte(tag.Reaction.Type))
|
||||
_, _ = h.Write([]byte{0})
|
||||
_, _ = h.Write([]byte(tag.Reaction.Value()))
|
||||
_, _ = h.Write([]byte{0})
|
||||
_, _ = h.Write([]byte(tag.Title))
|
||||
_, _ = h.Write([]byte{0})
|
||||
_, _ = h.Write([]byte(strconv.Itoa(tag.Count)))
|
||||
_, _ = h.Write([]byte{0xff})
|
||||
}
|
||||
sum := int64(h.Sum64() & 0x7fffffffffffffff)
|
||||
if sum == 0 {
|
||||
return 1
|
||||
}
|
||||
return sum
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue