diff --git a/src/api/gramjs/methods/chats.ts b/src/api/gramjs/methods/chats.ts index 5a891c33d..d0edd3948 100644 --- a/src/api/gramjs/methods/chats.ts +++ b/src/api/gramjs/methods/chats.ts @@ -39,8 +39,9 @@ import { buildChatBannedRights, buildChatAdminRights, } from '../gramjsBuilders'; -import { addEntitiesWithPhotosToLocalDb, addMessageToLocalDb } from '../helpers'; +import { addEntitiesWithPhotosToLocalDb, addMessageToLocalDb, addPhotoToLocalDb } from '../helpers'; import { buildApiPeerId, getApiChatIdFromMtpPeer } from '../apiBuilders/peers'; +import { buildApiPhoto } from '../apiBuilders/common'; const MAX_INT_32 = 2 ** 31 - 1; let onUpdate: OnApiUpdate; @@ -1005,13 +1006,24 @@ export async function openChatByInvite(hash: string) { let chat: ApiChat | undefined; if (result instanceof GramJs.ChatInvite) { + const { + photo, participantsCount, title, channel, requestNeeded, about, + } = result; + + if (photo instanceof GramJs.Photo) { + addPhotoToLocalDb(result.photo); + } + onUpdate({ '@type': 'showInvite', data: { - title: result.title, + title, + about, hash, - participantsCount: result.participantsCount, - isChannel: result.channel, + participantsCount, + isChannel: channel, + isRequestNeeded: requestNeeded, + ...(photo instanceof GramJs.Photo && { photo: buildApiPhoto(photo) }), }, }); } else { diff --git a/src/api/types/misc.ts b/src/api/types/misc.ts index e137f5849..40ca9ef5c 100644 --- a/src/api/types/misc.ts +++ b/src/api/types/misc.ts @@ -1,4 +1,4 @@ -import { ApiDocument } from './messages'; +import { ApiDocument, ApiPhoto } from './messages'; export interface ApiInitialArgs { userAgent: string; @@ -89,9 +89,12 @@ export type ApiFieldError = { export type ApiInviteInfo = { title: string; + about?: string; hash: string; isChannel?: boolean; participantsCount?: number; + isRequestNeeded?: true; + photo?: ApiPhoto; }; export interface ApiCountry { diff --git a/src/components/common/Avatar.tsx b/src/components/common/Avatar.tsx index aaa71ad22..8e3ac2b76 100644 --- a/src/components/common/Avatar.tsx +++ b/src/components/common/Avatar.tsx @@ -2,7 +2,7 @@ import { MouseEvent as ReactMouseEvent } from 'react'; import React, { FC, memo, useCallback } from '../../lib/teact/teact'; import { - ApiChat, ApiMediaFormat, ApiUser, ApiUserStatus, + ApiChat, ApiMediaFormat, ApiPhoto, ApiUser, ApiUserStatus, } from '../../api/types'; import { IS_TEST } from '../../config'; @@ -30,6 +30,7 @@ type OwnProps = { size?: 'micro' | 'tiny' | 'small' | 'medium' | 'large' | 'jumbo'; chat?: ApiChat; user?: ApiUser; + photo?: ApiPhoto; userStatus?: ApiUserStatus; text?: string; isSavedMessages?: boolean; @@ -42,6 +43,7 @@ const Avatar: FC = ({ size = 'large', chat, user, + photo, userStatus, text, isSavedMessages, @@ -57,6 +59,8 @@ const Avatar: FC = ({ imageHash = getChatAvatarHash(user); } else if (chat) { imageHash = getChatAvatarHash(chat); + } else if (photo) { + imageHash = `photo${photo.id}?size=m`; } } diff --git a/src/components/main/Dialogs.tsx b/src/components/main/Dialogs.tsx index 90f9d8c3c..fc8ee9be4 100644 --- a/src/components/main/Dialogs.tsx +++ b/src/components/main/Dialogs.tsx @@ -1,7 +1,7 @@ import React, { FC, memo } from '../../lib/teact/teact'; import { getDispatch, withGlobal } from '../../lib/teact/teactn'; -import { ApiError, ApiInviteInfo } from '../../api/types'; +import { ApiError, ApiInviteInfo, ApiPhoto } from '../../api/types'; import getReadableErrorText from '../../util/getReadableErrorText'; import { pick } from '../../util/iteratees'; @@ -10,6 +10,7 @@ import renderText from '../common/helpers/renderText'; import Modal from '../ui/Modal'; import Button from '../ui/Button'; +import Avatar from '../common/Avatar'; import './Dialogs.scss'; @@ -26,9 +27,23 @@ const Dialogs: FC = ({ dialogs }) => { return undefined; } + function renderInviteHeader(title: string, photo?: ApiPhoto) { + return ( +
+ {photo && } +
+ {renderText(title)} +
+ +
+ ); + } + const renderInvite = (invite: ApiInviteInfo) => { const { - hash, title, participantsCount, isChannel, + hash, title, about, participantsCount, isChannel, photo, isRequestNeeded, } = invite; const handleJoinClick = () => { @@ -43,16 +58,28 @@ const Dialogs: FC = ({ dialogs }) => { : lang('Members', participantsCount, 'i'); const joinText = isChannel ? lang('ChannelJoin') : lang('JoinGroup'); + const requestToJoinText = isChannel + ? lang('MemberRequests.RequestToJoinChannel') : lang('MemberRequests.RequestToJoinGroup'); return ( + {about &&

{renderText(about)}

} {participantsCount !== undefined &&

{participantsText}

} - + {isRequestNeeded && ( +

+ {isChannel + ? lang('MemberRequests.RequestToJoinDescriptionChannel') + : lang('MemberRequests.RequestToJoinDescriptionGroup')} +

+ )} +
); diff --git a/src/components/ui/Modal.scss b/src/components/ui/Modal.scss index aa85ca1aa..0c5c5a367 100644 --- a/src/components/ui/Modal.scss +++ b/src/components/ui/Modal.scss @@ -139,6 +139,16 @@ text-align: initial; } + .modal-about { + font-weight: bold; + } + + .modal-help { + color: var(--color-text-secondary); + font-size: 0.9375rem; + line-height: 1.3; + } + .dialog-buttons { display: flex; align-items: flex-end;