Skip to content

Commit

Permalink
Message: Reply re-design and blockquotes (#3926)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ajaxy committed Nov 5, 2023
1 parent f894010 commit 330bc42
Show file tree
Hide file tree
Showing 127 changed files with 2,408 additions and 1,355 deletions.
19 changes: 7 additions & 12 deletions dev/icons.scss.hbs
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
@use "sass:map";
${{ name }}-font: "{{ name }}";

@font-face {
font-family: ${{ name }}-font;
src: {{{ fontSrc }}};
font-weight: normal;
font-style: normal;
font-display: block;
}

.icon-char::before {
font-family: Roboto, "Helvetica Neue", sans-serif;
Expand All @@ -17,9 +8,7 @@ ${{ name }}-font: "{{ name }}";
display: block;
}

{{# if selector }}{{ selector }}::before {
{{ else }}{{ tag }}.{{prefix}} {
{{/ if }}
@mixin icon {
/* use !important to prevent issues with browser extensions that change fonts */
/* stylelint-disable-next-line font-family-no-missing-generic-family-keyword */
font-family: "{{ name }}" !important;
Expand All @@ -35,6 +24,12 @@ ${{ name }}-font: "{{ name }}";
-moz-osx-font-smoothing: grayscale;
}

{{# if selector }}{{ selector }}::before {
{{ else }}{{ tag }}.{{prefix}} {
{{/ if }}
@include icon;
}

${{ name }}-map: (
{{# each codepoints }}
"{{ @key }}": "\\{{ codepoint this }}",
Expand Down
4 changes: 4 additions & 0 deletions src/api/gramjs/apiBuilders/appConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ export interface GramJsAppConfig extends LimitsConfig {
story_expire_period: number;
story_viewers_expire_period: number;
stories_changelog_user_id?: number;
peer_colors: Record<string, string[]>;
dark_peer_colors: Record<string, string[]>;
}

function buildEmojiSounds(appConfig: GramJsAppConfig) {
Expand Down Expand Up @@ -117,5 +119,7 @@ export function buildAppConfig(json: GramJs.TypeJSONValue, hash: number): ApiApp
storyExpirePeriod: appConfig.story_expire_period ?? STORY_EXPIRE_PERIOD,
storyViewersExpirePeriod: appConfig.story_viewers_expire_period ?? STORY_VIEWERS_EXPIRE_PERIOD,
storyChangelogUserId: appConfig.stories_changelog_user_id?.toString() ?? SERVICE_NOTIFICATIONS_USER_ID,
peerColors: appConfig.peer_colors,
darkPeerColors: appConfig.dark_peer_colors,
};
}
1 change: 0 additions & 1 deletion src/api/gramjs/apiBuilders/bots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ export function buildBotSwitchWebview(switchWebview?: GramJs.InlineBotWebView) {
export function buildApiAttachBot(bot: GramJs.AttachMenuBot): ApiAttachBot {
return {
id: bot.botId.toString(),
hasSettings: bot.hasSettings,
shouldRequestWriteAccess: bot.requestWriteAccess,
shortName: bot.shortName,
isForAttachMenu: bot.showInAttachMenu!,
Expand Down
6 changes: 5 additions & 1 deletion src/api/gramjs/apiBuilders/chats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ function buildApiChatFieldsFromPeerEntity(
const areStoriesHidden = Boolean('storiesHidden' in peerEntity && peerEntity.storiesHidden);
const maxStoryId = 'storiesMaxId' in peerEntity ? peerEntity.storiesMaxId : undefined;
const storiesUnavailable = Boolean('storiesUnavailable' in peerEntity && peerEntity.storiesUnavailable);
const color = 'color' in peerEntity ? peerEntity.color : undefined;
const backgroundEmojiId = 'backgroundEmojiId' in peerEntity ? peerEntity.backgroundEmojiId?.toString() : undefined;

return {
isMin,
Expand All @@ -66,7 +68,7 @@ function buildApiChatFieldsFromPeerEntity(
...('verified' in peerEntity && { isVerified: peerEntity.verified }),
...('callActive' in peerEntity && { isCallActive: peerEntity.callActive }),
...('callNotEmpty' in peerEntity && { isCallNotEmpty: peerEntity.callNotEmpty }),
...('date' in peerEntity && { joinDate: peerEntity.date }),
...('date' in peerEntity && { creationDate: peerEntity.date }),
...('participantsCount' in peerEntity && peerEntity.participantsCount !== undefined && {
membersCount: peerEntity.participantsCount,
}),
Expand All @@ -77,6 +79,8 @@ function buildApiChatFieldsFromPeerEntity(
...buildApiChatRestrictions(peerEntity),
...buildApiChatMigrationInfo(peerEntity),
fakeType: isScam ? 'scam' : (isFake ? 'fake' : undefined),
color,
backgroundEmojiId,
isJoinToSend,
isJoinRequest,
isForum,
Expand Down
6 changes: 3 additions & 3 deletions src/api/gramjs/apiBuilders/messageContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import type {
ApiGame,
ApiInvoice,
ApiLocation,
ApiMessage,
ApiMessageExtendedMediaPreview,
ApiMessageStoryData,
ApiPhoto,
Expand All @@ -19,6 +18,7 @@ import type {
ApiWebDocument,
ApiWebPage,
ApiWebPageStoryData,
MediaContent,
} from '../../types';
import type { UniversalMessage } from './messages';

Expand All @@ -38,7 +38,7 @@ import { buildStickerFromDocument } from './symbols';
export function buildMessageContent(
mtpMessage: UniversalMessage | GramJs.UpdateServiceNotification,
) {
let content: ApiMessage['content'] = {};
let content: MediaContent = {};

if (mtpMessage.media) {
content = {
Expand Down Expand Up @@ -69,7 +69,7 @@ export function buildMessageTextContent(
};
}

export function buildMessageMediaContent(media: GramJs.TypeMessageMedia): ApiMessage['content'] | undefined {
export function buildMessageMediaContent(media: GramJs.TypeMessageMedia): MediaContent | undefined {
if ('ttlSeconds' in media && media.ttlSeconds) {
return undefined;
}
Expand Down
138 changes: 88 additions & 50 deletions src/api/gramjs/apiBuilders/messages.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
import { Api as GramJs } from '../../../lib/gramjs';

import type { ApiDraft } from '../../../global/types';
import type {
ApiAction,
ApiAttachment,
ApiChat,
ApiContact,
ApiGroupCall,
ApiInputMessageReplyInfo,
ApiInputReplyInfo,
ApiKeyboardButton,
ApiMessage,
ApiMessageEntity,
ApiMessageForwardInfo,
ApiNewPoll,
ApiPeer,
ApiPhoto,
ApiReplyInfo,
ApiReplyKeyboard,
ApiSponsoredMessage,
ApiSticker,
ApiStory,
ApiStorySkipped,
ApiThreadInfo,
ApiTypeReplyTo,
ApiVideo,
MediaContent,
PhoneCallAction,
} from '../../types';
import {
Expand Down Expand Up @@ -49,7 +53,7 @@ import { buildApiCallDiscardReason } from './calls';
import {
buildApiPhoto,
} from './common';
import { buildMessageContent, buildMessageTextContent } from './messageContent';
import { buildMessageContent, buildMessageMediaContent, buildMessageTextContent } from './messageContent';
import { buildApiPeerId, getApiChatIdFromMtpPeer, isPeerUser } from './peers';
import { buildMessageReactions } from './reactions';

Expand Down Expand Up @@ -171,23 +175,6 @@ export function buildApiMessageWithChatId(
const isInvoiceMedia = mtpMessage.media instanceof GramJs.MessageMediaInvoice
&& Boolean(mtpMessage.media.extendedMedia);

let replyToMsgId: number | undefined;
let replyToTopId: number | undefined;
let replyToStoryUserId: string | undefined;
let replyToStoryId: number | undefined;
let forumTopic: boolean | undefined;
let replyToPeerId: GramJs.TypePeer | undefined;
if (mtpMessage.replyTo instanceof GramJs.MessageReplyHeader) {
replyToMsgId = mtpMessage.replyTo.replyToMsgId;
replyToTopId = mtpMessage.replyTo.replyToTopId;
forumTopic = mtpMessage.replyTo.forumTopic;
replyToPeerId = mtpMessage.replyTo.replyToPeerId;
}
if (mtpMessage.replyTo instanceof GramJs.MessageReplyStoryHeader) {
replyToStoryUserId = buildApiPeerId(mtpMessage.replyTo.userId, 'user');
replyToStoryId = mtpMessage.replyTo.storyId;
}

const isEdited = mtpMessage.editDate && !mtpMessage.editHide;
const {
inlineButtons, keyboardButtons, keyboardPlaceholder, isKeyboardSingleUse, isKeyboardSelective,
Expand Down Expand Up @@ -218,12 +205,8 @@ export function buildApiMessageWithChatId(
isPinned: mtpMessage.pinned,
reactions: mtpMessage.reactions && buildMessageReactions(mtpMessage.reactions),
emojiOnlyCount,
...(replyToMsgId && { replyToMessageId: replyToMsgId }),
...(forumTopic && { isTopicReply: true }),
...(replyToPeerId && { replyToChatId: getApiChatIdFromMtpPeer(replyToPeerId) }),
...(replyToTopId && { replyToTopMessageId: replyToTopId }),
...(mtpMessage.replyTo && { replyInfo: buildApiReplyInfo(mtpMessage.replyTo) }),
...(forwardInfo && { forwardInfo }),
...(replyToStoryUserId && { replyToStoryUserId, replyToStoryId }),
...(isEdited && { isEdited }),
...(mtpMessage.editDate && { editDate: mtpMessage.editDate }),
...(isMediaUnread && { isMediaUnread }),
Expand All @@ -246,18 +229,26 @@ export function buildApiMessageWithChatId(
};
}

export function buildMessageDraft(draft: GramJs.TypeDraftMessage) {
export function buildMessageDraft(draft: GramJs.TypeDraftMessage): ApiDraft | undefined {
if (draft instanceof GramJs.DraftMessageEmpty) {
return undefined;
}

const {
message, entities, replyToMsgId, date,
message, entities, replyTo, date,
} = draft;

const replyInfo = replyTo instanceof GramJs.InputReplyToMessage ? {
type: 'message',
replyToMsgId: replyTo.replyToMsgId,
replyToTopId: replyTo.topMsgId,
replyToPeerId: replyTo.replyToPeerId && getApiChatIdFromMtpPeer(replyTo.replyToPeerId),
quoteText: replyTo.quoteText ? buildMessageTextContent(replyTo.quoteText, replyTo.quoteEntities) : undefined,
} satisfies ApiInputMessageReplyInfo : undefined;

return {
formattedText: message ? buildMessageTextContent(message, entities) : undefined,
replyingToId: replyToMsgId,
text: message ? buildMessageTextContent(message, entities) : undefined,
replyInfo,
date,
};
}
Expand All @@ -280,6 +271,44 @@ function buildApiMessageForwardInfo(fwdFrom: GramJs.MessageFwdHeader, isChatWith
};
}

function buildApiReplyInfo(replyHeader: GramJs.TypeMessageReplyHeader): ApiReplyInfo | undefined {
if (replyHeader instanceof GramJs.MessageReplyStoryHeader) {
return {
type: 'story',
userId: replyHeader.userId.toString(),
storyId: replyHeader.storyId,
};
}

if (replyHeader instanceof GramJs.MessageReplyHeader) {
const {
replyFrom,
replyToMsgId,
replyToTopId,
replyMedia,
replyToPeerId,
forumTopic,
quote,
quoteText,
quoteEntities,
} = replyHeader;

return {
type: 'message',
replyToMsgId,
replyToTopId,
isForumTopic: forumTopic,
replyFrom: replyFrom && buildApiMessageForwardInfo(replyFrom),
replyToPeerId: replyToPeerId && getApiChatIdFromMtpPeer(replyToPeerId),
replyMedia: replyMedia && buildMessageMediaContent(replyMedia),
isQuote: quote,
quoteText: quoteText ? buildMessageTextContent(quoteText, quoteEntities) : undefined,
};
}

return undefined;
}

function buildAction(
action: GramJs.TypeMessageAction,
senderId: string | undefined,
Expand Down Expand Up @@ -682,7 +711,7 @@ export function buildLocalMessage(
chat: ApiChat,
text?: string,
entities?: ApiMessageEntity[],
replyingTo?: ApiTypeReplyTo,
replyInfo?: ApiInputReplyInfo,
attachment?: ApiAttachment,
sticker?: ApiSticker,
gif?: ApiVideo,
Expand All @@ -696,21 +725,8 @@ export function buildLocalMessage(
const localId = getNextLocalMessageId(chat.lastMessage?.id);
const media = attachment && buildUploadingMedia(attachment);
const isChannel = chat.type === 'chatTypeChannel';
const isForum = chat.isForum;

let replyToMessageId: number | undefined;
let replyingToTopId: number | undefined;
let replyToStoryUserId: string | undefined;
let replyToStoryId: number | undefined;
if (replyingTo) {
if ('replyingTo' in replyingTo) {
replyToMessageId = replyingTo.replyingTo;
replyingToTopId = replyingTo.replyingToTopId;
} else {
replyToStoryUserId = replyingTo.userId;
replyToStoryId = replyingTo.storyId;
}
}

const resultReplyInfo = replyInfo && buildReplyInfo(replyInfo, chat.isForum);

const message = {
id: localId,
Expand All @@ -732,10 +748,7 @@ export function buildLocalMessage(
date: scheduledAt || Math.round(Date.now() / 1000) + getServerTimeOffset(),
isOutgoing: !isChannel,
senderId: sendAs?.id || currentUserId,
...(replyToMessageId && { replyToMessageId }),
...(replyingToTopId && { replyToTopMessageId: replyingToTopId }),
...((replyToMessageId || replyingToTopId) && isForum && { isTopicReply: true }),
...(replyToStoryUserId && { replyToStoryUserId, replyToStoryId }),
replyInfo: resultReplyInfo,
...(groupedId && {
groupedId,
...(media && (media.photo || media.video) && { isInAlbum: true }),
Expand Down Expand Up @@ -796,6 +809,12 @@ export function buildLocalForwardedMessage({
text: !shouldHideText ? strippedText : undefined,
};

const replyInfo: ApiReplyInfo | undefined = toThreadId ? {
type: 'message',
replyToTopId: toThreadId,
isForumTopic: toChat.isForum || undefined,
} : undefined;

return {
id: localId,
chatId: toChat.id,
Expand All @@ -807,7 +826,7 @@ export function buildLocalForwardedMessage({
groupedId,
isInAlbum,
isForwardingAllowed: true,
replyToTopMessageId: toThreadId,
replyInfo,
...(toThreadId && toChat?.isForum && { isTopicReply: true }),

...(emojiOnlyCount && { emojiOnlyCount }),
Expand All @@ -826,9 +845,28 @@ export function buildLocalForwardedMessage({
};
}

function buildReplyInfo(inputInfo: ApiInputReplyInfo, isForum?: boolean): ApiReplyInfo {
if (inputInfo.type === 'story') {
return {
type: 'story',
userId: inputInfo.userId,
storyId: inputInfo.storyId,
};
}

return {
type: 'message',
replyToMsgId: inputInfo.replyToMsgId,
replyToTopId: inputInfo.replyToTopId,
replyToPeerId: inputInfo.replyToPeerId,
quoteText: inputInfo.quoteText,
isForumTopic: isForum && inputInfo.replyToTopId ? true : undefined,
};
}

function buildUploadingMedia(
attachment: ApiAttachment,
): ApiMessage['content'] {
): MediaContent {
const {
filename: fileName,
blobUrl,
Expand Down
Loading

0 comments on commit 330bc42

Please sign in to comment.