2023-07-20 16:36:39 +02:00

103 lines
3.1 KiB
TypeScript

import type { GlobalState } from '../types';
import type { ApiChat, ApiMessage, ApiReaction } from '../../api/types';
import { MIN_SCREEN_WIDTH_FOR_STATIC_LEFT_COLUMN, MIN_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN } from '../../config';
import {
MIN_LEFT_COLUMN_WIDTH,
SIDE_COLUMN_MAX_WIDTH,
} from '../../components/middle/helpers/calculateMiddleFooterTransforms';
import windowSize from '../../util/windowSize';
import { updateChat } from './chats';
import { isSameReaction, isReactionChosen } from '../helpers';
import { updateChatMessage } from './messages';
import { selectSendAs, selectTabState } from '../selectors';
import { getIsMobile } from '../../hooks/useAppLayout';
function getLeftColumnWidth(windowWidth: number) {
if (windowWidth > MIN_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN) {
return Math.min(
Math.max(windowWidth * 0.25, MIN_LEFT_COLUMN_WIDTH),
windowWidth * 0.33,
);
}
if (windowWidth > MIN_SCREEN_WIDTH_FOR_STATIC_LEFT_COLUMN) {
return Math.min(
Math.max(windowWidth * 0.33, MIN_LEFT_COLUMN_WIDTH),
windowWidth * 0.4,
);
}
return SIDE_COLUMN_MAX_WIDTH;
}
export function subtractXForEmojiInteraction(global: GlobalState, x: number) {
const tabState = selectTabState(global);
return x - ((tabState.isLeftColumnShown && !getIsMobile())
? global.leftColumnWidth || getLeftColumnWidth(windowSize.get().width)
: 0);
}
export function addMessageReaction<T extends GlobalState>(
global: T, message: ApiMessage, userReactions: ApiReaction[],
): T {
const currentReactions = message.reactions || { results: [] };
const currentSendAs = selectSendAs(global, message.chatId);
// Update UI without waiting for server response
const results = currentReactions.results.map((current) => (
isReactionChosen(current) ? {
...current,
chosenOrder: undefined,
count: current.count - 1,
} : current
)).filter(({ count }) => count > 0);
userReactions.forEach((reaction, i) => {
const existingIndex = results.findIndex((r) => isSameReaction(r.reaction, reaction));
if (existingIndex > -1) {
results[existingIndex] = {
...results[existingIndex],
chosenOrder: i,
count: results[existingIndex].count + 1,
};
} else {
results.push({
reaction,
chosenOrder: i,
count: 1,
});
}
});
let { recentReactions = [] } = currentReactions;
if (recentReactions.length) {
recentReactions = recentReactions.filter(({ isOwn, peerId }) => !isOwn && peerId !== global.currentUserId);
}
userReactions.forEach((reaction) => {
const { currentUserId } = global;
recentReactions.unshift({
peerId: currentSendAs?.id || currentUserId!,
reaction,
addedDate: Math.floor(Date.now() / 1000),
isOwn: true,
});
});
return updateChatMessage(global, message.chatId, message.id, {
reactions: {
...currentReactions,
results,
recentReactions,
},
});
}
export function updateUnreadReactions<T extends GlobalState>(
global: T, chatId: string, update: Pick<ApiChat, 'unreadReactionsCount' | 'unreadReactions'>,
): T {
return updateChat(global, chatId, update, undefined, true);
}