Reactions: Support limit in channels and groups (#4784)
This commit is contained in:
parent
16c442b9cf
commit
f3743bd556
@ -7,6 +7,7 @@ import type { ApiAppConfig } from '../../types';
|
||||
|
||||
import {
|
||||
DEFAULT_LIMITS,
|
||||
MAX_UNIQUE_REACTIONS,
|
||||
SERVICE_NOTIFICATIONS_USER_ID,
|
||||
STORY_EXPIRE_PERIOD,
|
||||
STORY_VIEWERS_EXPIRE_PERIOD,
|
||||
@ -116,7 +117,7 @@ export function buildAppConfig(json: GramJs.TypeJSONValue, hash: number): ApiApp
|
||||
readDateExpiresAt: appConfig.pm_read_date_expire_period,
|
||||
autologinDomains: appConfig.autologin_domains || [],
|
||||
urlAuthDomains: appConfig.url_auth_domains || [],
|
||||
maxUniqueReactions: appConfig.reactions_uniq_max,
|
||||
maxUniqueReactions: appConfig.reactions_uniq_max ?? MAX_UNIQUE_REACTIONS,
|
||||
premiumBotUsername: appConfig.premium_bot_username,
|
||||
premiumInvoiceSlug: appConfig.premium_invoice_slug,
|
||||
premiumPromoOrder: appConfig.premium_promo_order as ApiPremiumSection[],
|
||||
|
||||
@ -514,6 +514,7 @@ async function getFullChatInfo(chatId: string): Promise<FullChatData | undefined
|
||||
requestsPending,
|
||||
chatPhoto,
|
||||
translationsDisabled,
|
||||
reactionsLimit,
|
||||
} = result.fullChat;
|
||||
|
||||
if (chatPhoto) {
|
||||
@ -538,6 +539,7 @@ async function getFullChatInfo(chatId: string): Promise<FullChatData | undefined
|
||||
inviteLink,
|
||||
groupCallId: call?.id.toString(),
|
||||
enabledReactions: buildApiChatReactions(availableReactions),
|
||||
reactionsLimit,
|
||||
requestsPending,
|
||||
recentRequesterIds: recentRequesters?.map((userId) => buildApiPeerId(userId, 'user')),
|
||||
isTranslationDisabled: translationsDisabled,
|
||||
@ -588,6 +590,7 @@ async function getFullChannelInfo(
|
||||
call,
|
||||
botInfo,
|
||||
availableReactions,
|
||||
reactionsLimit,
|
||||
defaultSendAs,
|
||||
requestsPending,
|
||||
recentRequesters,
|
||||
@ -670,6 +673,7 @@ async function getFullChannelInfo(
|
||||
linkedChatId: linkedChatId ? buildApiPeerId(linkedChatId, 'channel') : undefined,
|
||||
botCommands,
|
||||
enabledReactions: buildApiChatReactions(availableReactions),
|
||||
reactionsLimit,
|
||||
sendAsId: defaultSendAs ? getApiChatIdFromMtpPeer(defaultSendAs) : undefined,
|
||||
requestsPending,
|
||||
recentRequesterIds: recentRequesters?.map((userId) => buildApiPeerId(userId, 'user')),
|
||||
@ -1568,13 +1572,14 @@ export async function importChatInvite({ hash }: { hash: string }) {
|
||||
}
|
||||
|
||||
export function setChatEnabledReactions({
|
||||
chat, enabledReactions,
|
||||
chat, enabledReactions, reactionsLimit,
|
||||
}: {
|
||||
chat: ApiChat; enabledReactions?: ApiChatReactions;
|
||||
chat: ApiChat; enabledReactions?: ApiChatReactions; reactionsLimit?: number;
|
||||
}) {
|
||||
return invokeRequest(new GramJs.messages.SetChatAvailableReactions({
|
||||
peer: buildInputPeer(chat.id, chat.accessHash),
|
||||
availableReactions: buildInputChatReactions(enabledReactions),
|
||||
reactionsLimit,
|
||||
}), {
|
||||
shouldReturnTrue: true,
|
||||
});
|
||||
|
||||
@ -123,6 +123,7 @@ export interface ApiChatFullInfo {
|
||||
linkedChatId?: string;
|
||||
botCommands?: ApiBotCommand[];
|
||||
enabledReactions?: ApiChatReactions;
|
||||
reactionsLimit?: number;
|
||||
sendAsId?: string;
|
||||
canViewStatistics?: boolean;
|
||||
recentRequesterIds?: string[];
|
||||
|
||||
@ -124,7 +124,7 @@ type StateProps = {
|
||||
canShowSeenBy?: boolean;
|
||||
enabledReactions?: ApiChatReactions;
|
||||
canScheduleUntilOnline?: boolean;
|
||||
maxUniqueReactions?: number;
|
||||
reactionsLimit?: number;
|
||||
canPlayAnimatedEmojis?: boolean;
|
||||
isReactionPickerOpen?: boolean;
|
||||
isInSavedMessages?: boolean;
|
||||
@ -161,7 +161,7 @@ const ContextMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
canShowReactionList,
|
||||
canEdit,
|
||||
enabledReactions,
|
||||
maxUniqueReactions,
|
||||
reactionsLimit,
|
||||
isPrivate,
|
||||
isCurrentUserPremium,
|
||||
canForward,
|
||||
@ -576,7 +576,7 @@ const ContextMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
canBuyPremium={canBuyPremium}
|
||||
isOpen={isMenuOpen}
|
||||
enabledReactions={enabledReactions}
|
||||
maxUniqueReactions={maxUniqueReactions}
|
||||
reactionsLimit={reactionsLimit}
|
||||
anchor={anchor}
|
||||
targetHref={targetHref}
|
||||
canShowReactionsCount={canShowReactionsCount}
|
||||
@ -674,9 +674,15 @@ export default memo(withGlobal<OwnProps>(
|
||||
|
||||
const activeDownloads = selectActiveDownloads(global);
|
||||
const chat = selectChat(global, message.chatId);
|
||||
const isPrivate = chat && isUserId(chat.id);
|
||||
const chatFullInfo = !isPrivate ? selectChatFullInfo(global, message.chatId) : undefined;
|
||||
|
||||
const {
|
||||
seenByExpiresAt, seenByMaxChatMembers, maxUniqueReactions, readDateExpiresAt,
|
||||
} = global.appConfig || {};
|
||||
|
||||
const reactionsLimit = chatFullInfo?.reactionsLimit || maxUniqueReactions;
|
||||
|
||||
const {
|
||||
noOptions,
|
||||
canReply,
|
||||
@ -697,7 +703,6 @@ export default memo(withGlobal<OwnProps>(
|
||||
canClosePoll,
|
||||
} = (threadId && selectAllowedMessageActions(global, message, threadId)) || {};
|
||||
|
||||
const isPrivate = chat && isUserId(chat.id);
|
||||
const userStatus = isPrivate ? selectUserStatus(global, chat.id) : undefined;
|
||||
const isOwn = isOwnMessage(message);
|
||||
const isMessageUnread = selectIsMessageUnread(global, message);
|
||||
@ -731,7 +736,6 @@ export default memo(withGlobal<OwnProps>(
|
||||
&& chat.membersCount <= seenByMaxChatMembers
|
||||
&& message.date > Date.now() / 1000 - seenByExpiresAt);
|
||||
const isAction = isActionMessage(message);
|
||||
const chatFullInfo = !isPrivate ? selectChatFullInfo(global, message.chatId) : undefined;
|
||||
const canShowReactionsCount = !isLocal && !isChannel && !isScheduled && !isAction && !isPrivate && message.reactions
|
||||
&& !areReactionsEmpty(message.reactions) && message.reactions.canSeeList;
|
||||
const isProtected = selectIsMessageProtected(global, message);
|
||||
@ -781,7 +785,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
canLoadReadDate,
|
||||
shouldRenderShowWhen,
|
||||
enabledReactions: chat?.isForbidden ? undefined : chatFullInfo?.enabledReactions,
|
||||
maxUniqueReactions,
|
||||
reactionsLimit,
|
||||
isPrivate,
|
||||
isCurrentUserPremium,
|
||||
hasFullInfo: Boolean(chatFullInfo),
|
||||
|
||||
@ -52,7 +52,7 @@ type OwnProps = {
|
||||
message: ApiMessage | ApiSponsoredMessage;
|
||||
canSendNow?: boolean;
|
||||
enabledReactions?: ApiChatReactions;
|
||||
maxUniqueReactions?: number;
|
||||
reactionsLimit?: number;
|
||||
canReschedule?: boolean;
|
||||
canReply?: boolean;
|
||||
canQuote?: boolean;
|
||||
@ -140,7 +140,7 @@ const MessageContextMenu: FC<OwnProps> = ({
|
||||
isPrivate,
|
||||
isCurrentUserPremium,
|
||||
enabledReactions,
|
||||
maxUniqueReactions,
|
||||
reactionsLimit,
|
||||
anchor,
|
||||
targetHref,
|
||||
canSendNow,
|
||||
@ -364,7 +364,7 @@ const MessageContextMenu: FC<OwnProps> = ({
|
||||
allAvailableReactions={availableReactions}
|
||||
defaultTagReactions={defaultTagReactions}
|
||||
currentReactions={!isSponsoredMessage ? message.reactions?.results : undefined}
|
||||
maxUniqueReactions={maxUniqueReactions}
|
||||
reactionsLimit={reactionsLimit}
|
||||
onToggleReaction={onToggleReaction!}
|
||||
isPrivate={isPrivate}
|
||||
isReady={isReady}
|
||||
|
||||
@ -30,7 +30,7 @@ type OwnProps = {
|
||||
effectReactions?: ApiReaction[];
|
||||
allAvailableReactions?: ApiAvailableReaction[];
|
||||
currentReactions?: ApiReactionCount[];
|
||||
maxUniqueReactions?: number;
|
||||
reactionsLimit?: number;
|
||||
isReady?: boolean;
|
||||
canBuyPremium?: boolean;
|
||||
isCurrentUserPremium?: boolean;
|
||||
@ -54,7 +54,7 @@ const ReactionSelector: FC<OwnProps> = ({
|
||||
defaultTagReactions,
|
||||
enabledReactions,
|
||||
currentReactions,
|
||||
maxUniqueReactions,
|
||||
reactionsLimit,
|
||||
isPrivate,
|
||||
isReady,
|
||||
canPlayAnimatedEmojis,
|
||||
@ -75,8 +75,8 @@ const ReactionSelector: FC<OwnProps> = ({
|
||||
|
||||
const areReactionsLocked = isInSavedMessages && !isCurrentUserPremium && !isInStoryViewer;
|
||||
|
||||
const shouldUseCurrentReactions = Boolean(maxUniqueReactions
|
||||
&& currentReactions && currentReactions.length >= maxUniqueReactions);
|
||||
const shouldUseCurrentReactions = Boolean(reactionsLimit
|
||||
&& currentReactions && currentReactions.length >= reactionsLimit);
|
||||
|
||||
const availableReactions = useMemo(() => {
|
||||
const reactions = (() => {
|
||||
@ -86,6 +86,7 @@ const ReactionSelector: FC<OwnProps> = ({
|
||||
if (enabledReactions?.type === 'some') return enabledReactions.allowed;
|
||||
return allAvailableReactions?.map((reaction) => reaction.reaction);
|
||||
})();
|
||||
|
||||
const filteredReactions = reactions?.map((reaction) => {
|
||||
const isCustomReaction = 'documentId' in reaction;
|
||||
const availableReaction = allAvailableReactions?.find((r) => isSameReaction(r.reaction, reaction));
|
||||
@ -106,6 +107,7 @@ const ReactionSelector: FC<OwnProps> = ({
|
||||
}, [
|
||||
allAvailableReactions, currentReactions, defaultTagReactions, enabledReactions, isInSavedMessages, isPrivate,
|
||||
topReactions, isForEffects, effectReactions, shouldUseCurrentReactions,
|
||||
|
||||
]);
|
||||
|
||||
const reactionsToRender = useMemo(() => {
|
||||
|
||||
@ -9,7 +9,10 @@ import type {
|
||||
ApiAvailableReaction, ApiChat, ApiChatReactions, ApiReaction,
|
||||
} from '../../../api/types';
|
||||
|
||||
import { isSameReaction } from '../../../global/helpers';
|
||||
import {
|
||||
MAX_UNIQUE_REACTIONS,
|
||||
} from '../../../config';
|
||||
import { isChatChannel, isSameReaction } from '../../../global/helpers';
|
||||
import { selectChat, selectChatFullInfo } from '../../../global/selectors';
|
||||
|
||||
import useHistoryBack from '../../../hooks/useHistoryBack';
|
||||
@ -19,6 +22,7 @@ import ReactionStaticEmoji from '../../common/ReactionStaticEmoji';
|
||||
import Checkbox from '../../ui/Checkbox';
|
||||
import FloatingActionButton from '../../ui/FloatingActionButton';
|
||||
import RadioGroup from '../../ui/RadioGroup';
|
||||
import RangeSlider from '../../ui/RangeSlider';
|
||||
import Spinner from '../../ui/Spinner';
|
||||
|
||||
type OwnProps = {
|
||||
@ -31,6 +35,9 @@ type StateProps = {
|
||||
chat?: ApiChat;
|
||||
availableReactions?: ApiAvailableReaction[];
|
||||
enabledReactions?: ApiChatReactions;
|
||||
maxUniqueReactions: number;
|
||||
reactionsLimit?: number;
|
||||
isChannel?: boolean;
|
||||
};
|
||||
|
||||
const ManageReactions: FC<OwnProps & StateProps> = ({
|
||||
@ -39,6 +46,9 @@ const ManageReactions: FC<OwnProps & StateProps> = ({
|
||||
chat,
|
||||
isActive,
|
||||
onClose,
|
||||
maxUniqueReactions,
|
||||
reactionsLimit,
|
||||
isChannel,
|
||||
}) => {
|
||||
const { setChatEnabledReactions } = getActions();
|
||||
|
||||
@ -47,6 +57,8 @@ const ManageReactions: FC<OwnProps & StateProps> = ({
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [localEnabledReactions, setLocalEnabledReactions] = useState<ApiChatReactions | undefined>(enabledReactions);
|
||||
|
||||
const [localReactionsLimit, setLocalReactionsLimit] = useState(reactionsLimit);
|
||||
|
||||
useHistoryBack({
|
||||
isActive,
|
||||
onBack: onClose,
|
||||
@ -70,33 +82,80 @@ const ManageReactions: FC<OwnProps & StateProps> = ({
|
||||
setChatEnabledReactions({
|
||||
chatId: chat.id,
|
||||
enabledReactions: localEnabledReactions,
|
||||
reactionsLimit: localReactionsLimit,
|
||||
});
|
||||
}, [chat, localEnabledReactions, setChatEnabledReactions]);
|
||||
}, [chat, localEnabledReactions, setChatEnabledReactions, localReactionsLimit]);
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoading(false);
|
||||
setIsTouched(false);
|
||||
setLocalEnabledReactions(enabledReactions);
|
||||
}, [enabledReactions]);
|
||||
setLocalReactionsLimit(reactionsLimit);
|
||||
}, [enabledReactions, reactionsLimit]);
|
||||
|
||||
const availableActiveReactions = useMemo<ApiAvailableReaction[] | undefined>(
|
||||
() => availableReactions?.filter(({ isInactive }) => !isInactive),
|
||||
[availableReactions],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (localReactionsLimit !== undefined && localReactionsLimit !== reactionsLimit) {
|
||||
setIsTouched(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (localEnabledReactions?.type === 'some') {
|
||||
const isReactionsDisabled = enabledReactions?.type !== 'all' && enabledReactions?.type !== 'some';
|
||||
|
||||
if (isReactionsDisabled && localEnabledReactions.allowed.length === 0) {
|
||||
setIsTouched(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (localEnabledReactions?.type !== enabledReactions?.type) {
|
||||
setIsTouched(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (localEnabledReactions?.type === 'some' && enabledReactions?.type === 'some') {
|
||||
const localAllowedReactions = localEnabledReactions.allowed;
|
||||
const enabledAllowedReactions = enabledReactions?.allowed;
|
||||
|
||||
if (localAllowedReactions.length !== enabledAllowedReactions.length
|
||||
|| localAllowedReactions.reverse().some(
|
||||
(localReaction) => !enabledAllowedReactions.find(
|
||||
(enabledReaction) => isSameReaction(localReaction, enabledReaction),
|
||||
),
|
||||
)) {
|
||||
setIsTouched(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setIsTouched(false);
|
||||
}, [
|
||||
localReactionsLimit,
|
||||
reactionsLimit,
|
||||
localEnabledReactions,
|
||||
enabledReactions,
|
||||
]);
|
||||
|
||||
const handleReactionsOptionChange = useCallback((value: string) => {
|
||||
if (value === 'all') {
|
||||
setLocalEnabledReactions({ type: 'all' });
|
||||
setLocalReactionsLimit(reactionsLimit);
|
||||
} else if (value === 'some') {
|
||||
setLocalEnabledReactions({
|
||||
type: 'some',
|
||||
allowed: enabledReactions?.type === 'some' ? enabledReactions.allowed : [],
|
||||
});
|
||||
setLocalReactionsLimit(reactionsLimit);
|
||||
} else {
|
||||
setLocalEnabledReactions(undefined);
|
||||
setLocalReactionsLimit(undefined);
|
||||
}
|
||||
setIsTouched(true);
|
||||
}, [enabledReactions]);
|
||||
}, [enabledReactions, reactionsLimit]);
|
||||
|
||||
const handleReactionChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
if (!chat || !availableActiveReactions) return;
|
||||
@ -116,12 +175,40 @@ const ManageReactions: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
}
|
||||
}
|
||||
setIsTouched(true);
|
||||
}, [availableActiveReactions, chat, localEnabledReactions]);
|
||||
|
||||
const handleReactionsLimitChange = useCallback((value: number) => {
|
||||
setLocalReactionsLimit(value);
|
||||
}, []);
|
||||
|
||||
const renderReactionsMaxCountValue = useCallback((value: number) => {
|
||||
return lang('PeerInfo.AllowedReactions.MaxCountValue', value);
|
||||
}, [lang]);
|
||||
|
||||
const shouldShowReactionsLimit = isChannel
|
||||
&& (localEnabledReactions?.type === 'all' || localEnabledReactions?.type === 'some');
|
||||
|
||||
return (
|
||||
<div className="Management">
|
||||
<div className="custom-scroll">
|
||||
{ localReactionsLimit && shouldShowReactionsLimit && (
|
||||
<div className="section">
|
||||
<h3 className="section-heading">
|
||||
{lang('MaximumReactionsHeader')}
|
||||
</h3>
|
||||
<RangeSlider
|
||||
min={1}
|
||||
max={maxUniqueReactions}
|
||||
value={localReactionsLimit}
|
||||
onChange={handleReactionsLimitChange}
|
||||
renderValue={renderReactionsMaxCountValue}
|
||||
isCenteredLayout
|
||||
/>
|
||||
<p className="section-info mt-4">
|
||||
{lang('ChannelReactions.MaxCount.Info')}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
<div className="section">
|
||||
<h3 className="section-heading">
|
||||
{lang('AvailableReactions')}
|
||||
@ -141,7 +228,7 @@ const ManageReactions: FC<OwnProps & StateProps> = ({
|
||||
{localEnabledReactions?.type === 'some' && (
|
||||
<div className="section">
|
||||
<h3 className="section-heading">
|
||||
{lang('AvailableReactions')}
|
||||
{lang('OnlyAllowThisReactions')}
|
||||
</h3>
|
||||
{availableActiveReactions?.map(({ reaction, title }) => (
|
||||
<div className="ListItem">
|
||||
@ -181,11 +268,19 @@ const ManageReactions: FC<OwnProps & StateProps> = ({
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
(global, { chatId }): StateProps => {
|
||||
const chat = selectChat(global, chatId)!;
|
||||
const { maxUniqueReactions = MAX_UNIQUE_REACTIONS } = global.appConfig || {};
|
||||
|
||||
const chatFullInfo = selectChatFullInfo(global, chatId);
|
||||
const reactionsLimit = chatFullInfo?.reactionsLimit || maxUniqueReactions;
|
||||
const isChannel = isChatChannel(chat);
|
||||
|
||||
return {
|
||||
enabledReactions: selectChatFullInfo(global, chatId)?.enabledReactions,
|
||||
enabledReactions: chatFullInfo?.enabledReactions,
|
||||
availableReactions: global.reactions.availableReactions,
|
||||
chat,
|
||||
maxUniqueReactions,
|
||||
reactionsLimit,
|
||||
isChannel,
|
||||
};
|
||||
},
|
||||
(global, { chatId }) => {
|
||||
|
||||
@ -135,6 +135,10 @@
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.RangeSlider {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.radio-group {
|
||||
margin-top: 2rem;
|
||||
|
||||
|
||||
@ -30,12 +30,19 @@
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.625rem;
|
||||
|
||||
.value-min,
|
||||
.value-max,
|
||||
.value {
|
||||
flex-shrink: 0;
|
||||
margin-left: 1rem;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.value-min,
|
||||
.value-max {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&[dir="rtl"] {
|
||||
.value {
|
||||
margin-left: 0;
|
||||
@ -90,7 +97,8 @@
|
||||
|
||||
// Apply custom styles
|
||||
input[type="range"] {
|
||||
// Note that while we're repeating code here, that's necessary as you can't comma-separate these type of selectors.
|
||||
// Note that while we're repeating code here, that's
|
||||
// necessary as you can't comma-separate these type of selectors.
|
||||
// Browsers will drop the entire selector if it doesn't understand a part of it.
|
||||
&::-webkit-slider-thumb {
|
||||
@include thumb-styles();
|
||||
|
||||
@ -20,6 +20,7 @@ type OwnProps = {
|
||||
className?: string;
|
||||
renderValue?: (value: number) => string;
|
||||
onChange: (value: number) => void;
|
||||
isCenteredLayout?: boolean;
|
||||
};
|
||||
|
||||
const RangeSlider: FC<OwnProps> = ({
|
||||
@ -34,6 +35,7 @@ const RangeSlider: FC<OwnProps> = ({
|
||||
className,
|
||||
renderValue,
|
||||
onChange,
|
||||
isCenteredLayout,
|
||||
}) => {
|
||||
const lang = useOldLang();
|
||||
const handleChange = useCallback((event: ChangeEvent<HTMLInputElement>) => {
|
||||
@ -56,16 +58,38 @@ const RangeSlider: FC<OwnProps> = ({
|
||||
}
|
||||
}, [options, value, max, min, step]);
|
||||
|
||||
return (
|
||||
<div className={mainClassName}>
|
||||
{label && (
|
||||
function renderTopRow() {
|
||||
if (isCenteredLayout) {
|
||||
return (
|
||||
<div className="slider-top-row" dir={lang.isRtl ? 'rtl' : undefined}>
|
||||
<span className="label" dir="auto">{label}</span>
|
||||
{!options && (
|
||||
<span className="value" dir="auto">{renderValue ? renderValue(value) : value}</span>
|
||||
<>
|
||||
<span className="value-min" dir="auto">{min}</span>
|
||||
<span className="label" dir="auto">{renderValue ? renderValue(value) : value}</span>
|
||||
<span className="value-max" dir="auto">{max}</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
);
|
||||
}
|
||||
|
||||
if (!label) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="slider-top-row" dir={lang.isRtl ? 'rtl' : undefined}>
|
||||
<span className="label" dir="auto">{label}</span>
|
||||
{!options && (
|
||||
<span className="value" dir="auto">{renderValue ? renderValue(value) : value}</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={mainClassName}>
|
||||
{renderTopRow()}
|
||||
<div className="slider-main">
|
||||
<div
|
||||
className="slider-fill-track"
|
||||
|
||||
@ -339,6 +339,7 @@ export const PEER_COLOR_BG_OPACITY = '1a';
|
||||
export const PEER_COLOR_BG_ACTIVE_OPACITY = '2b';
|
||||
export const PEER_COLOR_GRADIENT_STEP = 5; // px
|
||||
export const MAX_UPLOAD_FILEPART_SIZE = 524288;
|
||||
export const MAX_UNIQUE_REACTIONS = 11;
|
||||
|
||||
// Group calls
|
||||
export const GROUP_CALL_VOLUME_MULTIPLIER = 100;
|
||||
|
||||
@ -1953,13 +1953,16 @@ addActionHandler('toggleIsProtected', (global, actions, payload): ActionReturnTy
|
||||
});
|
||||
|
||||
addActionHandler('setChatEnabledReactions', async (global, actions, payload): Promise<void> => {
|
||||
const { chatId, enabledReactions, tabId = getCurrentTabId() } = payload;
|
||||
const {
|
||||
chatId, enabledReactions, reactionsLimit, tabId = getCurrentTabId(),
|
||||
} = payload;
|
||||
const chat = selectChat(global, chatId);
|
||||
if (!chat) return;
|
||||
|
||||
await callApi('setChatEnabledReactions', {
|
||||
chat,
|
||||
enabledReactions,
|
||||
reactionsLimit,
|
||||
});
|
||||
|
||||
global = getGlobal();
|
||||
|
||||
@ -2335,6 +2335,7 @@ export interface ActionPayloads {
|
||||
setChatEnabledReactions: {
|
||||
chatId: string;
|
||||
enabledReactions?: ApiChatReactions;
|
||||
reactionsLimit?: number;
|
||||
} & WithTabId;
|
||||
|
||||
startActiveReaction: {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user