diff --git a/src/api/gramjs/methods/chats.ts b/src/api/gramjs/methods/chats.ts index 29954a215..8ce3fb0ab 100644 --- a/src/api/gramjs/methods/chats.ts +++ b/src/api/gramjs/methods/chats.ts @@ -44,6 +44,15 @@ import { import { addEntitiesWithPhotosToLocalDb, addMessageToLocalDb, addPhotoToLocalDb } from '../helpers'; import { buildApiPeerId, getApiChatIdFromMtpPeer } from '../apiBuilders/peers'; import { buildApiPhoto } from '../apiBuilders/common'; +import { buildStickerSet } from '../apiBuilders/symbols'; + +type FullChatData = { + fullInfo: ApiChatFullInfo; + users?: ApiUser[]; + userStatusesById: { [userId: string]: ApiUserStatus }; + groupCall?: Partial; + membersCount?: number; +}; const MAX_INT_32 = 2 ** 31 - 1; let onUpdate: OnApiUpdate; @@ -336,13 +345,7 @@ export function clearDraft(chat: ApiChat) { })); } -async function getFullChatInfo(chatId: string): Promise<{ - fullInfo: ApiChatFullInfo; - users?: ApiUser[]; - userStatusesById?: { [userId: string]: ApiUserStatus }; - groupCall?: Partial; - membersCount?: number; -} | undefined> { +async function getFullChatInfo(chatId: string): Promise { const result = await invokeRequest(new GramJs.messages.GetFullChat({ chatId: buildInputEntity(chatId) as BigInt.BigInteger, })); @@ -404,13 +407,7 @@ async function getFullChannelInfo( id: string, accessHash: string, adminRights?: ApiChatAdminRights, -): Promise<{ - fullInfo: ApiChatFullInfo; - users?: ApiUser[]; - userStatusesById: { [userId: string]: ApiUserStatus }; - groupCall?: Partial; - membersCount?: number; - } | undefined> { +): Promise { const result = await invokeRequest(new GramJs.channels.GetFullChannel({ channel: buildInputEntity(id, accessHash) as GramJs.InputChannel, })); @@ -439,6 +436,7 @@ async function getFullChannelInfo( recentRequesters, statsDc, participantsCount, + stickerset, } = result.fullChat; const inviteLink = exportedInvite instanceof GramJs.ChatInviteExported @@ -501,6 +499,7 @@ async function getFullChannelInfo( requestsPending, recentRequesterIds: recentRequesters?.map((userId) => buildApiPeerId(userId, 'user')), statisticsDcId: statsDc, + stickerSet: stickerset ? buildStickerSet(stickerset) : undefined, }, users: [...(users || []), ...(bannedUsers || []), ...(adminUsers || [])], userStatusesById: statusesById, diff --git a/src/api/types/chats.ts b/src/api/types/chats.ts index 5f280eb57..5941b5318 100644 --- a/src/api/types/chats.ts +++ b/src/api/types/chats.ts @@ -1,4 +1,4 @@ -import { ApiMessage, ApiPhoto } from './messages'; +import { ApiMessage, ApiPhoto, ApiStickerSet } from './messages'; import { ApiBotCommand } from './bots'; import { ApiChatInviteImporter } from './misc'; import { ApiFakeType } from './users'; @@ -104,6 +104,7 @@ export interface ApiChatFullInfo { recentRequesterIds?: string[]; requestsPending?: number; statisticsDcId?: number; + stickerSet?: ApiStickerSet; } export interface ApiChatMember { diff --git a/src/components/middle/composer/StickerPicker.tsx b/src/components/middle/composer/StickerPicker.tsx index 237c85af1..fafa19b52 100644 --- a/src/components/middle/composer/StickerPicker.tsx +++ b/src/components/middle/composer/StickerPicker.tsx @@ -3,10 +3,11 @@ import React, { } from '../../../lib/teact/teact'; import { getActions, withGlobal } from '../../../global'; -import { ApiStickerSet, ApiSticker } from '../../../api/types'; +import { ApiStickerSet, ApiSticker, ApiChat } from '../../../api/types'; import { StickerSetOrRecent } from '../../../types'; import { + CHAT_STICKER_SET_ID, FAVORITE_SYMBOL_SET_ID, RECENT_SYMBOL_SET_ID, SLIDE_TRANSITION_DURATION, STICKER_SIZE_PICKER_HEADER, } from '../../../config'; import { IS_TOUCH_ENV } from '../../../util/environment'; @@ -14,7 +15,8 @@ import { MEMO_EMPTY_ARRAY } from '../../../util/memo'; import fastSmoothScroll from '../../../util/fastSmoothScroll'; import buildClassName from '../../../util/buildClassName'; import fastSmoothScrollHorizontal from '../../../util/fastSmoothScrollHorizontal'; -import { selectIsChatWithSelf } from '../../../global/selectors'; +import { pickTruthy } from '../../../util/iteratees'; +import { selectChat, selectIsChatWithSelf } from '../../../global/selectors'; import useAsyncRendering from '../../right/hooks/useAsyncRendering'; import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver'; @@ -22,6 +24,7 @@ import useHorizontalScroll from '../../../hooks/useHorizontalScroll'; import useLang from '../../../hooks/useLang'; import useSendMessageAction from '../../../hooks/useSendMessageAction'; +import Avatar from '../../common/Avatar'; import Loading from '../../ui/Loading'; import Button from '../../ui/Button'; import StickerButton from '../../common/StickerButton'; @@ -41,6 +44,7 @@ type OwnProps = { }; type StateProps = { + chat?: ApiChat; recentStickers: ApiSticker[]; favoriteStickers: ApiSticker[]; stickerSetsById: Record; @@ -56,7 +60,7 @@ const STICKER_INTERSECTION_THROTTLE = 200; const stickerSetIntersections: boolean[] = []; const StickerPicker: FC = ({ - chatId, + chat, threadId, className, loadAndPlay, @@ -82,7 +86,8 @@ const StickerPicker: FC = ({ // eslint-disable-next-line no-null/no-null const headerRef = useRef(null); const [activeSetIndex, setActiveSetIndex] = useState(0); - const sendMessageAction = useSendMessageAction(chatId, threadId); + + const sendMessageAction = useSendMessageAction(chat!.id, threadId); const { observe: observeIntersection } = useIntersectionObserver({ rootRef: containerRef, @@ -139,11 +144,23 @@ const StickerPicker: FC = ({ }); } + if (chat?.fullInfo?.stickerSet) { + const fullSet = stickerSetsById[chat.fullInfo.stickerSet.id]; + if (fullSet) { + defaultSets.push({ + id: CHAT_STICKER_SET_ID, + title: lang('GroupStickers'), + stickers: fullSet.stickers, + count: fullSet.stickers!.length, + }); + } + } + return [ ...defaultSets, - ...addedSetIds.map((id) => stickerSetsById[id]).filter(Boolean), + ...Object.values(pickTruthy(stickerSetsById, addedSetIds)), ]; - }, [addedSetIds, lang, recentStickers, favoriteStickers, stickerSetsById]); + }, [addedSetIds, favoriteStickers, recentStickers, chat, lang, stickerSetsById]); const noPopulatedSets = useMemo(() => ( areAddedLoaded @@ -213,6 +230,7 @@ const StickerPicker: FC = ({ if (stickerSet.id === RECENT_SYMBOL_SET_ID || stickerSet.id === FAVORITE_SYMBOL_SET_ID + || stickerSet.id === CHAT_STICKER_SET_ID || stickerSet.hasThumbnail || !firstSticker) { return ( @@ -230,6 +248,8 @@ const StickerPicker: FC = ({ ) : stickerSet.id === FAVORITE_SYMBOL_SET_ID ? ( + ) : stickerSet.id === CHAT_STICKER_SET_ID ? ( + ) : stickerSet.isLottie ? ( ( } = global.stickers; const isSavedMessages = selectIsChatWithSelf(global, chatId); + const chat = selectChat(global, chatId); return { + chat, recentStickers: recent.stickers, favoriteStickers: favorite.stickers, stickerSetsById: setsById, diff --git a/src/config.ts b/src/config.ts index 9e71991b8..df9b4d92f 100644 --- a/src/config.ts +++ b/src/config.ts @@ -141,6 +141,7 @@ export const RECENT_STICKERS_LIMIT = 20; export const NO_STICKER_SET_ID = 'NO_STICKER_SET'; export const RECENT_SYMBOL_SET_ID = 'recent'; export const FAVORITE_SYMBOL_SET_ID = 'favorite'; +export const CHAT_STICKER_SET_ID = 'chatStickers'; export const BASE_EMOJI_KEYWORD_LANG = 'en'; diff --git a/src/global/actions/api/chats.ts b/src/global/actions/api/chats.ts index 15ca44a84..09c082fbf 100644 --- a/src/global/actions/api/chats.ts +++ b/src/global/actions/api/chats.ts @@ -1135,6 +1135,15 @@ export async function loadFullChat(chat: ApiChat) { setGlobal(global); + const stickerSet = fullInfo.stickerSet; + if (stickerSet) { + getActions().loadStickers({ + stickerSetId: stickerSet.id, + stickerSetAccessHash: stickerSet.accessHash, + stickerSetShortName: stickerSet.shortName, + }); + } + return result; }