diff --git a/src/api/gramjs/apiBuilders/users.ts b/src/api/gramjs/apiBuilders/users.ts index 90df95c50..bb4a11b19 100644 --- a/src/api/gramjs/apiBuilders/users.ts +++ b/src/api/gramjs/apiBuilders/users.ts @@ -60,6 +60,7 @@ export function buildApiUser(mtpUser: GramJs.TypeUser): ApiUser | undefined { const { id, firstName, lastName, fake, scam, support, closeFriend, storiesUnavailable, storiesMaxId, + bot, botActiveUsers, botInlinePlaceholder, botAttachMenu, botCanEdit, } = mtpUser; const hasVideoAvatar = mtpUser.photo instanceof GramJs.UserProfilePhoto ? Boolean(mtpUser.photo.hasVideo) : undefined; const avatarPhotoId = mtpUser.photo && buildAvatarPhotoId(mtpUser.photo); @@ -80,7 +81,7 @@ export function buildApiUser(mtpUser: GramJs.TypeUser): ApiUser | undefined { type: userType, firstName, lastName, - canEditBot: Boolean(mtpUser.botCanEdit), + canEditBot: botCanEdit, ...(userType === 'userTypeBot' && { canBeInvitedToGroup: !mtpUser.botNochats }), ...(usernames && { usernames }), phoneNumber: mtpUser.phone || '', @@ -92,8 +93,9 @@ export function buildApiUser(mtpUser: GramJs.TypeUser): ApiUser | undefined { areStoriesHidden: Boolean(mtpUser.storiesHidden), maxStoryId: storiesMaxId, hasStories: Boolean(storiesMaxId) && !storiesUnavailable, - ...(mtpUser.bot && mtpUser.botInlinePlaceholder && { botPlaceholder: mtpUser.botInlinePlaceholder }), - ...(mtpUser.bot && mtpUser.botAttachMenu && { isAttachBot: mtpUser.botAttachMenu }), + ...(bot && botInlinePlaceholder && { botPlaceholder: botInlinePlaceholder }), + ...(bot && botAttachMenu && { isAttachBot: botAttachMenu }), + botActiveUsers, color: mtpUser.color && buildApiPeerColor(mtpUser.color), }; } diff --git a/src/api/gramjs/methods/bots.ts b/src/api/gramjs/methods/bots.ts index 2a3ddb7d4..42c73e192 100644 --- a/src/api/gramjs/methods/bots.ts +++ b/src/api/gramjs/methods/bots.ts @@ -82,6 +82,24 @@ export async function fetchTopInlineBots() { }; } +export async function fetchTopBotApps() { + const topPeers = await invokeRequest(new GramJs.contacts.GetTopPeers({ + botsApp: true, + })); + + if (!(topPeers instanceof GramJs.contacts.TopPeers)) { + return undefined; + } + + const users = topPeers.users.map(buildApiUser).filter(Boolean); + const ids = users.map(({ id }) => id); + + return { + ids, + users, + }; +} + export async function fetchInlineBot({ username }: { username: string }) { const resolvedPeer = await invokeRequest(new GramJs.contacts.ResolveUsername({ username })); @@ -582,3 +600,30 @@ export function setBotInfo({ shouldReturnTrue: true, }); } + +export async function fetchPopularAppBots({ + offset = '', limit, +}: { + offset?: string; + limit?: number; +}) { + const result = await invokeRequest(new GramJs.bots.GetPopularAppBots({ + offset, + limit, + })); + + if (!result) { + return undefined; + } + + addEntitiesToLocalDb(result.users); + + const users = result.users.map(buildApiUser).filter(Boolean); + const chats = result.users.map((c) => buildApiChatFromPreview(c)).filter(Boolean); + + return { + users, + chats, + nextOffset: result.nextOffset, + }; +} diff --git a/src/api/gramjs/methods/index.ts b/src/api/gramjs/methods/index.ts index 0a809c562..b7679fe65 100644 --- a/src/api/gramjs/methods/index.ts +++ b/src/api/gramjs/methods/index.ts @@ -66,7 +66,7 @@ export { export { answerCallbackButton, setBotInfo, fetchTopInlineBots, fetchInlineBot, fetchInlineBotResults, - sendInlineBotResult, startBot, + sendInlineBotResult, startBot, fetchPopularAppBots, fetchTopBotApps, requestWebView, requestSimpleWebView, sendWebViewData, prolongWebView, loadAttachBots, toggleAttachBot, fetchBotApp, requestBotUrlAuth, requestLinkUrlAuth, acceptBotUrlAuth, acceptLinkUrlAuth, loadAttachBot, requestAppWebView, allowBotSendMessages, fetchBotCanSendMessage, invokeWebViewCustomMethod, diff --git a/src/api/types/users.ts b/src/api/types/users.ts index 1d37d9cd9..ad71d5fe1 100644 --- a/src/api/types/users.ts +++ b/src/api/types/users.ts @@ -40,6 +40,7 @@ export interface ApiUser { maxStoryId?: number; color?: ApiPeerColor; canEditBot?: boolean; + botActiveUsers?: number; } export interface ApiUserFullInfo { diff --git a/src/components/common/Composer.scss b/src/components/common/Composer.scss index 1d536ce9e..eea71137a 100644 --- a/src/components/common/Composer.scss +++ b/src/components/common/Composer.scss @@ -462,6 +462,7 @@ } .bot-menu-text { + --emoji-size: 1rem; font-size: 0.875rem; font-weight: 500; white-space: nowrap; diff --git a/src/components/left/main/LeftMain.scss b/src/components/left/main/LeftMain.scss index 2e2962fc2..d8e864331 100644 --- a/src/components/left/main/LeftMain.scss +++ b/src/components/left/main/LeftMain.scss @@ -29,8 +29,6 @@ .TabList { justify-content: flex-start; - padding-left: 0.5625rem; - padding-bottom: 1px; border-bottom: 0; z-index: 1; @@ -45,15 +43,6 @@ .Tab { flex: 0 0 auto; - padding-left: 0.625rem; - padding-right: 0.625rem; - - /* stylelint-disable-next-line */ - > span { - padding-left: 0.5rem; - padding-right: 0.5rem; - white-space: pre; - } } > .Transition { diff --git a/src/components/left/search/AudioResults.tsx b/src/components/left/search/AudioResults.tsx index d71d89141..26e08dad5 100644 --- a/src/components/left/search/AudioResults.tsx +++ b/src/components/left/search/AudioResults.tsx @@ -8,7 +8,6 @@ import { AudioOrigin, LoadMoreDirection } from '../../../types'; import { SLIDE_TRANSITION_DURATION } from '../../../config'; import { getIsDownloading, getMessageDownloadableMedia } from '../../../global/helpers'; -import buildClassName from '../../../util/buildClassName'; import { formatMonthAndYear, toYearMonth } from '../../../util/dates/dateFormat'; import { parseSearchResultKey } from '../../../util/keys/searchResultKey'; import { MEMO_EMPTY_ARRAY } from '../../../util/memo'; @@ -58,7 +57,7 @@ const AudioResults: FC = ({ }); }); } - // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps -- `searchQuery` is required to prevent infinite message loading + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps -- `searchQuery` is required to prevent infinite message loading }, [currentType, searchMessagesGlobal, searchQuery]); const foundMessages = useMemo(() => { @@ -89,36 +88,35 @@ const AudioResults: FC = ({ const media = getMessageDownloadableMedia(message)!; return ( -
+ <> {shouldDrawDateDivider && (

{formatMonthAndYear(lang, new Date(message.date * 1000))}

)} -
+ > +