Paid Reaction: UI fixes (#5103)

This commit is contained in:
zubiden 2024-11-02 21:11:00 +04:00 committed by Alexander Zinchuk
parent 36eab14839
commit a2f5c135cf
9 changed files with 21 additions and 17 deletions

View File

@ -731,6 +731,7 @@ export interface ApiReactionCount {
reaction: ApiReactionWithPaid; reaction: ApiReactionWithPaid;
localAmount?: number; localAmount?: number;
localIsPrivate?: boolean; localIsPrivate?: boolean;
localPreviousChosenOrder?: number;
} }
export interface ApiAvailableReaction { export interface ApiAvailableReaction {

Binary file not shown.

View File

@ -147,9 +147,9 @@
} }
@font-face { @font-face {
font-family: 'Roboto Round'; font-family: 'Numbers Rounded';
src: url('Roboto-Round-Regular.woff2') format('woff2'); src: url('Numbers-Rounded.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; unicode-range: U+0030-0039, U+002B, U+002D;
} }
@font-face { @font-face {

View File

@ -1,11 +1,11 @@
import type { ApiError, ApiReactionEmoji } from '../../../api/types'; import type { ApiError, ApiReaction, ApiReactionEmoji } from '../../../api/types';
import type { ActionReturnType } from '../../types'; import type { ActionReturnType } from '../../types';
import { ApiMediaFormat } from '../../../api/types'; import { ApiMediaFormat } from '../../../api/types';
import { GENERAL_REFETCH_INTERVAL } from '../../../config'; import { GENERAL_REFETCH_INTERVAL } from '../../../config';
import { getCurrentTabId } from '../../../util/establishMultitabRole'; import { getCurrentTabId } from '../../../util/establishMultitabRole';
import { import {
buildCollectionByCallback, buildCollectionByKey, omit, unique, buildCollectionByCallback, buildCollectionByKey, omit, partition, unique,
} from '../../../util/iteratees'; } from '../../../util/iteratees';
import { getMessageKey } from '../../../util/keys/messageKey'; import { getMessageKey } from '../../../util/keys/messageKey';
import * as mediaLoader from '../../../util/mediaLoader'; import * as mediaLoader from '../../../util/mediaLoader';
@ -210,7 +210,9 @@ addActionHandler('toggleReaction', async (global, actions, payload): Promise<voi
? userReactions.filter((userReaction) => !isSameReaction(userReaction, reaction)) : [...userReactions, reaction]; ? userReactions.filter((userReaction) => !isSameReaction(userReaction, reaction)) : [...userReactions, reaction];
const limit = selectMaxUserReactions(global); const limit = selectMaxUserReactions(global);
const reactions = newUserReactions.slice(-limit); const [paidReactions, regularReactions] = partition(newUserReactions, (r) => r.type === 'paid');
const trimmedRegularReactions = regularReactions.slice(-limit) as ApiReaction[];
const localReactions = [...paidReactions, ...trimmedRegularReactions];
const messageKey = getMessageKey(message); const messageKey = getMessageKey(message);
if (selectPerformanceSettingsValue(global, 'reactionEffects')) { if (selectPerformanceSettingsValue(global, 'reactionEffects')) {
@ -221,14 +223,14 @@ addActionHandler('toggleReaction', async (global, actions, payload): Promise<voi
} }
} }
global = addMessageReaction(global, message, reactions); global = addMessageReaction(global, message, localReactions);
setGlobal(global); setGlobal(global);
try { try {
await callApi('sendReaction', { await callApi('sendReaction', {
chat, chat,
messageId, messageId,
reactions, reactions: trimmedRegularReactions,
shouldAddToRecent, shouldAddToRecent,
}); });

View File

@ -115,6 +115,7 @@ addActionHandler('resetLocalPaidReactions', (global, actions, payload): ActionRe
return { return {
...reaction, ...reaction,
localAmount: undefined, localAmount: undefined,
chosenOrder: reaction.localPreviousChosenOrder,
}; };
} }
return reaction; return reaction;

View File

@ -2,7 +2,6 @@ import type {
ApiAvailableReaction, ApiAvailableReaction,
ApiChatReactions, ApiChatReactions,
ApiMessage, ApiMessage,
ApiReaction,
ApiReactionCount, ApiReactionCount,
ApiReactionKey, ApiReactionKey,
ApiReactions, ApiReactions,
@ -83,18 +82,17 @@ export function sortReactions<T extends ApiAvailableReaction | ApiReactionWithPa
}); });
} }
export function getUserReactions(message: ApiMessage): ApiReaction[] { export function getUserReactions(message: ApiMessage): ApiReactionWithPaid[] {
return message.reactions?.results?.filter((r): r is Required<ApiReactionCount> => isReactionChosen(r)) return message.reactions?.results?.filter((r): r is Required<ApiReactionCount> => isReactionChosen(r))
.sort((a, b) => a.chosenOrder - b.chosenOrder) .sort((a, b) => a.chosenOrder - b.chosenOrder)
.map((r) => r.reaction) .map((r) => r.reaction) || [];
.filter((r): r is ApiReaction => r.type !== 'paid') || [];
} }
export function isReactionChosen(reaction: ApiReactionCount) { export function isReactionChosen(reaction: ApiReactionCount) {
return reaction.chosenOrder !== undefined; return reaction.chosenOrder !== undefined;
} }
export function updateReactionCount(reactionCount: ApiReactionCount[], newReactions: ApiReaction[]) { export function updateReactionCount(reactionCount: ApiReactionCount[], newReactions: ApiReactionWithPaid[]) {
const results = reactionCount.map((current) => ( const results = reactionCount.map((current) => (
isReactionChosen(current) ? { isReactionChosen(current) ? {
...current, ...current,
@ -136,6 +134,7 @@ export function addPaidReaction(
localAmount: (current.localAmount || 0) + count, localAmount: (current.localAmount || 0) + count,
chosenOrder: -1, chosenOrder: -1,
localIsPrivate: isAnonymous !== undefined ? isAnonymous : current.localIsPrivate, localIsPrivate: isAnonymous !== undefined ? isAnonymous : current.localIsPrivate,
localPreviousChosenOrder: current.chosenOrder,
}); });
return; return;
} }

View File

@ -1,4 +1,4 @@
import type { ApiChat, ApiMessage, ApiReaction } from '../../api/types'; import type { ApiChat, ApiMessage, ApiReactionWithPaid } from '../../api/types';
import type { GlobalState } from '../types'; import type { GlobalState } from '../types';
import { MIN_SCREEN_WIDTH_FOR_STATIC_LEFT_COLUMN, MIN_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN } from '../../config'; import { MIN_SCREEN_WIDTH_FOR_STATIC_LEFT_COLUMN, MIN_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN } from '../../config';
@ -40,7 +40,7 @@ export function subtractXForEmojiInteraction(global: GlobalState, x: number) {
} }
export function addMessageReaction<T extends GlobalState>( export function addMessageReaction<T extends GlobalState>(
global: T, message: ApiMessage, userReactions: ApiReaction[], global: T, message: ApiMessage, userReactions: ApiReactionWithPaid[],
): T { ): T {
const isInSavedMessages = selectIsChatWithSelf(global, message.chatId); const isInSavedMessages = selectIsChatWithSelf(global, message.chatId);
const currentReactions = message.reactions || { results: [], areTags: isInSavedMessages }; const currentReactions = message.reactions || { results: [], areTags: isInSavedMessages };
@ -57,6 +57,7 @@ export function addMessageReaction<T extends GlobalState>(
userReactions.forEach((reaction) => { userReactions.forEach((reaction) => {
const { currentUserId } = global; const { currentUserId } = global;
if (reaction.type === 'paid') return;
recentReactions.unshift({ recentReactions.unshift({
peerId: currentSendAs?.id || currentUserId!, peerId: currentSendAs?.id || currentUserId!,
reaction, reaction,

View File

@ -33,8 +33,8 @@ body {
Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
--font-family-monospace: "Cascadia Mono", "Roboto Mono", "Droid Sans Mono", 'SF Mono', "Menlo", "Ubuntu Mono", --font-family-monospace: "Cascadia Mono", "Roboto Mono", "Droid Sans Mono", 'SF Mono', "Menlo", "Ubuntu Mono",
"Consolas", monospace; "Consolas", monospace;
--font-family-rounded: -ui-rounded, "Roboto Round"; --font-family-rounded: -ui-rounded, "Numbers Rounded", "Roboto", "Helvetica Neue", sans-serif;
--font-family-condensed: -ui-rounded, "Roboto Condensed"; --font-family-condensed: "Roboto Condensed", "Roboto", "Helvetica Neue", sans-serif;
@media (max-width: 600px) { @media (max-width: 600px) {
height: calc(var(--vh, 1vh) * 100); height: calc(var(--vh, 1vh) * 100);