275 lines
6.4 KiB
TypeScript
275 lines
6.4 KiB
TypeScript
import { addReducer, getGlobal, setGlobal } from '../../../lib/teact/teactn';
|
|
import { callApi } from '../../../api/gramjs';
|
|
import * as mediaLoader from '../../../util/mediaLoader';
|
|
import { ApiAppConfig, ApiMediaFormat } from '../../../api/types';
|
|
import {
|
|
selectChat,
|
|
selectChatMessage,
|
|
selectDefaultReaction,
|
|
selectLocalAnimatedEmojiEffectByName,
|
|
} from '../../selectors';
|
|
import { addMessageReaction, subtractXForEmojiInteraction } from '../../reducers/reactions';
|
|
import { addUsers, updateChatMessage } from '../../reducers';
|
|
import { buildCollectionByKey, omit } from '../../../util/iteratees';
|
|
import { ANIMATION_LEVEL_MAX } from '../../../config';
|
|
|
|
addReducer('loadAvailableReactions', () => {
|
|
(async () => {
|
|
const result = await callApi('getAvailableReactions');
|
|
|
|
if (!result) {
|
|
return;
|
|
}
|
|
|
|
// Preload animations
|
|
result.forEach((availableReaction) => {
|
|
if (availableReaction.aroundAnimation) {
|
|
mediaLoader.fetch(`sticker${availableReaction.aroundAnimation.id}`, ApiMediaFormat.Lottie);
|
|
}
|
|
if (availableReaction.centerIcon) {
|
|
mediaLoader.fetch(`sticker${availableReaction.centerIcon.id}`, ApiMediaFormat.Lottie);
|
|
}
|
|
});
|
|
|
|
setGlobal({
|
|
...getGlobal(),
|
|
availableReactions: result,
|
|
});
|
|
})();
|
|
});
|
|
|
|
addReducer('interactWithAnimatedEmoji', (global, actions, payload) => {
|
|
const {
|
|
emoji, x, y, localEffect, startSize, isReversed,
|
|
} = payload!;
|
|
|
|
return {
|
|
...global,
|
|
activeEmojiInteraction: {
|
|
animatedEffect: emoji || localEffect,
|
|
x: subtractXForEmojiInteraction(global, x),
|
|
y,
|
|
startSize,
|
|
isReversed,
|
|
},
|
|
};
|
|
});
|
|
|
|
addReducer('sendEmojiInteraction', (global, actions, payload) => {
|
|
const {
|
|
messageId, chatId, emoji, interactions, localEffect,
|
|
x, y, startX, startY, startSize,
|
|
} = payload!;
|
|
|
|
const chat = selectChat(global, chatId);
|
|
|
|
if (!chat || (!emoji && !localEffect) || chatId === global.currentUserId) {
|
|
return undefined;
|
|
}
|
|
|
|
void callApi('sendEmojiInteraction', {
|
|
chat,
|
|
messageId,
|
|
emoticon: emoji || selectLocalAnimatedEmojiEffectByName(localEffect),
|
|
timestamps: interactions,
|
|
});
|
|
|
|
if (!global.activeEmojiInteraction) return undefined;
|
|
|
|
return {
|
|
...global,
|
|
activeEmojiInteraction: {
|
|
...global.activeEmojiInteraction,
|
|
endX: subtractXForEmojiInteraction(global, x),
|
|
endY: y,
|
|
...(startX && { x: subtractXForEmojiInteraction(global, startX) }),
|
|
...(startY && { y: startY }),
|
|
...(startSize && { startSize }),
|
|
},
|
|
};
|
|
});
|
|
|
|
addReducer('sendDefaultReaction', (global, actions, payload) => {
|
|
const {
|
|
chatId, messageId, x, y,
|
|
} = payload;
|
|
const reaction = selectDefaultReaction(global, chatId);
|
|
|
|
if (!reaction) return;
|
|
|
|
actions.sendReaction({
|
|
chatId,
|
|
messageId,
|
|
reaction,
|
|
x,
|
|
y,
|
|
});
|
|
});
|
|
|
|
addReducer('sendReaction', (global, actions, payload) => {
|
|
const {
|
|
chatId, messageId,
|
|
}: { messageId: number; chatId: string } = payload;
|
|
|
|
let { reaction } = payload;
|
|
|
|
const chat = selectChat(global, chatId);
|
|
const message = selectChatMessage(global, chatId, messageId);
|
|
|
|
if (!chat || !message) {
|
|
return undefined;
|
|
}
|
|
|
|
if (message.reactions?.results?.some((l) => l.reaction === reaction && l.isChosen)) {
|
|
reaction = undefined;
|
|
}
|
|
|
|
void callApi('sendReaction', { chat, messageId, reaction });
|
|
|
|
const { animationLevel } = global.settings.byKey;
|
|
|
|
if (animationLevel === ANIMATION_LEVEL_MAX) {
|
|
global = {
|
|
...global,
|
|
activeReactions: {
|
|
...(reaction ? global.activeReactions : omit(global.activeReactions, [messageId])),
|
|
...(reaction && {
|
|
[messageId]: {
|
|
reaction,
|
|
messageId,
|
|
},
|
|
}),
|
|
},
|
|
};
|
|
}
|
|
|
|
return addMessageReaction(global, chatId, messageId, reaction);
|
|
});
|
|
|
|
addReducer('openChat', (global) => {
|
|
return {
|
|
...global,
|
|
activeReactions: {},
|
|
};
|
|
});
|
|
|
|
addReducer('stopActiveReaction', (global, actions, payload) => {
|
|
const { messageId, reaction } = payload;
|
|
|
|
if (global.activeReactions[messageId]?.reaction !== reaction) {
|
|
return global;
|
|
}
|
|
|
|
return {
|
|
...global,
|
|
activeReactions: omit(global.activeReactions, [messageId]),
|
|
};
|
|
});
|
|
|
|
addReducer('setDefaultReaction', (global, actions, payload) => {
|
|
const { reaction } = payload;
|
|
|
|
(async () => {
|
|
const result = await callApi('setDefaultReaction', { reaction });
|
|
|
|
if (!result) {
|
|
return;
|
|
}
|
|
|
|
global = getGlobal();
|
|
setGlobal({
|
|
...global,
|
|
appConfig: {
|
|
...global.appConfig,
|
|
defaultReaction: reaction,
|
|
} as ApiAppConfig,
|
|
});
|
|
})();
|
|
});
|
|
|
|
addReducer('stopActiveEmojiInteraction', (global) => {
|
|
return {
|
|
...global,
|
|
activeEmojiInteraction: undefined,
|
|
};
|
|
});
|
|
|
|
addReducer('loadReactors', (global, actions, payload) => {
|
|
const { chatId, messageId, reaction } = payload;
|
|
const chat = selectChat(global, chatId);
|
|
const message = selectChatMessage(global, chatId, messageId);
|
|
if (!chat || !message) {
|
|
return;
|
|
}
|
|
|
|
const offset = message.reactors?.nextOffset;
|
|
|
|
(async () => {
|
|
const result = await callApi('fetchMessageReactionsList', {
|
|
reaction,
|
|
chat,
|
|
messageId,
|
|
offset,
|
|
});
|
|
|
|
if (!result) {
|
|
return;
|
|
}
|
|
|
|
global = getGlobal();
|
|
if (result.users?.length) {
|
|
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
|
}
|
|
|
|
const { nextOffset, count, reactions } = result;
|
|
|
|
setGlobal(updateChatMessage(global, chatId, messageId, {
|
|
reactors: {
|
|
nextOffset,
|
|
count,
|
|
reactions: [
|
|
...(message.reactors?.reactions || []),
|
|
...reactions,
|
|
],
|
|
},
|
|
}));
|
|
})();
|
|
});
|
|
|
|
addReducer('loadMessageReactions', (global, actions, payload) => {
|
|
const { ids, chatId } = payload;
|
|
|
|
const chat = selectChat(global, chatId);
|
|
|
|
if (!chat) {
|
|
return;
|
|
}
|
|
|
|
callApi('fetchMessageReactions', { ids, chat });
|
|
});
|
|
|
|
addReducer('sendWatchingEmojiInteraction', (global, actions, payload) => {
|
|
const {
|
|
chatId, emoticon, x, y, startSize, isReversed,
|
|
} = payload;
|
|
|
|
const chat = selectChat(global, chatId);
|
|
|
|
if (!chat || !global.activeEmojiInteraction || chatId === global.currentUserId) {
|
|
return undefined;
|
|
}
|
|
|
|
callApi('sendWatchingEmojiInteraction', { chat, emoticon });
|
|
|
|
return {
|
|
...global,
|
|
activeEmojiInteraction: {
|
|
...global.activeEmojiInteraction,
|
|
x: subtractXForEmojiInteraction(global, x),
|
|
y,
|
|
startSize,
|
|
isReversed,
|
|
},
|
|
};
|
|
});
|