TelegramPWA/src/global/helpers/reactions.ts
2023-07-20 16:36:39 +02:00

85 lines
2.6 KiB
TypeScript

import type {
ApiChatReactions,
ApiMessage,
ApiReaction,
ApiReactions,
ApiReactionCount,
ApiAvailableReaction,
} from '../../api/types';
import type { GlobalState } from '../types';
export function getMessageRecentReaction(message: Partial<ApiMessage>) {
return message.isOutgoing ? message.reactions?.recentReactions?.[0] : undefined;
}
export function checkIfHasUnreadReactions(global: GlobalState, reactions: ApiReactions) {
const { currentUserId } = global;
return reactions?.recentReactions?.some(
({ isUnread, isOwn, peerId }) => isUnread && !isOwn && currentUserId !== peerId,
);
}
export function areReactionsEmpty(reactions: ApiReactions) {
return !reactions.results.some(({ count }) => count > 0);
}
export function isSameReaction(first?: ApiReaction, second?: ApiReaction) {
if (!first || !second) {
return false;
}
if ('emoticon' in first && 'emoticon' in second) {
return first.emoticon === second.emoticon;
}
if ('documentId' in first && 'documentId' in second) {
return first.documentId === second.documentId;
}
return false;
}
export function canSendReaction(reaction: ApiReaction, chatReactions: ApiChatReactions) {
if (chatReactions.type === 'all') {
return 'emoticon' in reaction || chatReactions.areCustomAllowed;
}
if (chatReactions.type === 'some') {
return chatReactions.allowed.some((r) => isSameReaction(r, reaction));
}
return false;
}
export function sortReactions<T extends ApiAvailableReaction | ApiReaction>(
reactions: T[],
topReactions?: ApiReaction[],
): T[] {
return reactions.slice().sort((left, right) => {
const reactionOne = left ? ('reaction' in left ? left.reaction : left) as ApiReaction : undefined;
const reactionTwo = right ? ('reaction' in right ? right.reaction : right) as ApiReaction : undefined;
const indexOne = topReactions?.findIndex((reaction) => isSameReaction(reaction, reactionOne)) || 0;
const indexTwo = topReactions?.findIndex((reaction) => isSameReaction(reaction, reactionTwo)) || 0;
return (
(indexOne > -1 ? indexOne : Infinity) - (indexTwo > -1 ? indexTwo : Infinity)
);
});
}
export function getUserReactions(message: ApiMessage): ApiReaction[] {
return message.reactions?.results?.filter((r): r is Required<ApiReactionCount> => isReactionChosen(r))
.sort((a, b) => a.chosenOrder - b.chosenOrder)
.map((r) => r.reaction) || [];
}
export function getReactionUniqueKey(reaction: ApiReaction) {
if ('emoticon' in reaction) {
return reaction.emoticon;
}
return reaction.documentId;
}
export function isReactionChosen(reaction: ApiReactionCount) {
return reaction.chosenOrder !== undefined;
}