From 890cee4366e4bee251a925f4e46854ccc754012a Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Mon, 15 Jul 2024 15:51:50 +0200 Subject: [PATCH] Story: Block reply for non-premium users if messaging is restricted (#4732) --- src/components/common/Composer.scss | 47 ++++++- src/components/common/Composer.tsx | 115 ++++++++++-------- .../middle/composer/MessageInput.tsx | 36 ++++-- 3 files changed, 137 insertions(+), 61 deletions(-) diff --git a/src/components/common/Composer.scss b/src/components/common/Composer.scss index 7e4f7a4b7..44a01b98a 100644 --- a/src/components/common/Composer.scss +++ b/src/components/common/Composer.scss @@ -343,6 +343,9 @@ &.with-story-tweaks { border-radius: var(--border-radius-default-small); border-bottom-right-radius: 0; + &.is-need-premium { + border-bottom-right-radius: var(--border-radius-default-small); + } box-shadow: none; } @@ -754,9 +757,12 @@ .input-scroller { min-height: var(--base-height, 3.5rem); max-height: 10rem; - margin-right: calc((var(--margin-for-scrollbar) + 1rem) * -1); + &.is-need-premium { + margin-right: 0.5rem; + } + &:has(.form-control:focus) { border-color: var(--color-primary); } @@ -764,17 +770,52 @@ .input-scroller-content { margin-right: calc(var(--margin-for-scrollbar) + 0.5rem); + &.is-need-premium { + margin-right: 0; + } } .placeholder-text { top: auto; - bottom: 1.0625rem; left: 0.875rem; } + + .unlock-button { + &:hover, + &.active { + background: var(--color-chat-hover); + } + + color: var(--color-text); + width: auto; + height: auto; + + padding-top: 0.125rem; + padding-bottom: 0.125rem; + padding-right: 0.4375rem; + padding-left: 0.4375rem; + + margin-left: 0.4375rem; + + text-transform: lowercase; + } +} + +#caption-input-text .placeholder-text { + bottom: 1.0625rem; } #story-input-text .placeholder-text { - bottom: 0.875rem; + top: calc((var(--base-height, 3.5rem) - var(--composer-text-size, 1rem) * 1.3125) / 2); + + @media (max-width: 600px) { + top: calc((2.875rem - var(--composer-text-size, 1rem) * 1.3125) / 2); + } + + &.is-need-premium { + pointer-events: auto; + } + left: 0.875rem; } diff --git a/src/components/common/Composer.tsx b/src/components/common/Composer.tsx index 36824c493..cb84aa9fc 100644 --- a/src/components/common/Composer.tsx +++ b/src/components/common/Composer.tsx @@ -257,6 +257,7 @@ type StateProps = canSendQuickReplies?: boolean; webPagePreview?: ApiWebPage; noWebPage?: boolean; + isContactRequirePremium?: boolean; effect?: ApiAvailableEffect; effectReactions?: ApiReaction[]; areEffectsSupported?: boolean; @@ -370,6 +371,7 @@ const Composer: FC = ({ onForward, webPagePreview, noWebPage, + isContactRequirePremium, effect, effectReactions, areEffectsSupported, @@ -490,8 +492,11 @@ const Composer: FC = ({ [chat, chatFullInfo, isChatWithBot, isInStoryViewer], ); + const isNeedPremium = isContactRequirePremium && isInStoryViewer; + const isSendTextBlocked = isNeedPremium || !canSendPlainText; + const hasWebPagePreview = !hasAttachments && canAttachEmbedLinks && !noWebPage && Boolean(webPagePreview); - const isComposerBlocked = !canSendPlainText && !editingMessage; + const isComposerBlocked = isSendTextBlocked && !editingMessage; useEffect(() => { if (!hasWebPagePreview) { @@ -1601,7 +1606,7 @@ const Composer: FC = ({ editingMessage={editingMessage} /> )} - {shouldRenderReactionSelector && ( + {shouldRenderReactionSelector && !isNeedPremium && ( = ({ onClick={handleBotCommandSelect} onClose={closeChatCommandTooltip} /> -
- - - - - - - - - - - - - +
+ {!isNeedPremium && ( + + + + + + + + + + + + + + )} {isInMessageList && ( <> = ({ )} )} - {(!isComposerBlocked || canSendGifs || canSendStickers) && ( + {((!isComposerBlocked || canSendGifs || canSendStickers) && !isNeedPremium) && ( = ({ ? '' : (!isComposerBlocked ? (botKeyboardPlaceholder || inputPlaceholder || lang(placeholderForForumAsMessages || 'Message')) - : lang('Chat.PlaceholderTextNotAllowed')) + : isInStoryViewer ? lang('StoryRepliesLocked') : lang('Chat.PlaceholderTextNotAllowed')) } timedPlaceholderDate={timedPlaceholderDate} timedPlaceholderLangKey={timedPlaceholderLangKey} @@ -1839,6 +1849,7 @@ const Composer: FC = ({ onSuppressedFocus={closeSymbolMenu} onFocus={markInputHasFocus} onBlur={unmarkInputHasFocus} + isNeedPremium={isNeedPremium} /> {isInMessageList && ( <> @@ -1875,28 +1886,30 @@ const Composer: FC = ({ {formatVoiceRecordDuration(currentRecordTime - startRecordTimeRef.current!)} )} - + {!isNeedPremium && ( + + )} {isInMessageList && Boolean(botKeyboardMessageId) && ( ( const noWebPage = selectNoWebPage(global, chatId, threadId); + const isContactRequirePremium = selectUserFullInfo(global, chatId)?.isContactRequirePremium; const areEffectsSupported = isChatWithUser && !isChatWithBot && !isInScheduledList && !isChatWithSelf && type !== 'story' && chatId !== SERVICE_NOTIFICATIONS_USER_ID; const canPlayEffect = selectPerformanceSettingsValue(global, 'stickerEffects'); @@ -2203,6 +2217,7 @@ export default memo(withGlobal( canSendQuickReplies, noWebPage, webPagePreview: selectTabState(global).webPagePreview, + isContactRequirePremium, effect, effectReactions, areEffectsSupported, diff --git a/src/components/middle/composer/MessageInput.tsx b/src/components/middle/composer/MessageInput.tsx index a50d8115d..4c728315d 100644 --- a/src/components/middle/composer/MessageInput.tsx +++ b/src/components/middle/composer/MessageInput.tsx @@ -33,6 +33,7 @@ import useLastCallback from '../../../hooks/useLastCallback'; import useOldLang from '../../../hooks/useOldLang'; import useInputCustomEmojis from './hooks/useInputCustomEmojis'; +import Button from '../../ui/Button'; import TextTimer from '../../ui/TextTimer'; import TextFormatter from './TextFormatter.async'; @@ -72,6 +73,7 @@ type OwnProps = { captionLimit?: number; onFocus?: NoneToVoidFunction; onBlur?: NoneToVoidFunction; + isNeedPremium?: boolean; }; type StateProps = { @@ -137,11 +139,13 @@ const MessageInput: FC = ({ onScroll, onFocus, onBlur, + isNeedPremium, }) => { const { editLastMessage, replyToNextMessage, showAllowedMessageTypesNotification, + openPremiumModal, } = getActions(); // eslint-disable-next-line no-null/no-null @@ -257,7 +261,7 @@ const MessageInput: FC = ({ const chatIdRef = useRef(chatId); chatIdRef.current = chatId; const focusInput = useLastCallback(() => { - if (!inputRef.current) { + if (!inputRef.current || isNeedPremium) { return; } @@ -450,10 +454,12 @@ const MessageInput: FC = ({ } function handleClick() { - if (isAttachmentModalInput || canSendPlainText) return; + if (isAttachmentModalInput || canSendPlainText || (isStoryInput && isNeedPremium)) return; showAllowedMessageTypesNotification({ chatId }); } + const handleOpenPremiumModal = useLastCallback(() => openPremiumModal()); + useEffect(() => { if (IS_TOUCH_ENV) { return; @@ -553,14 +559,16 @@ const MessageInput: FC = ({ shouldSuppressFocus && 'focus-disabled', ); + const inputScrollerContentClass = buildClassName('input-scroller-content', isNeedPremium && 'is-need-premium'); + return (
-
+
= ({ onContextMenu={IS_ANDROID ? handleAndroidContextMenu : undefined} onTouchCancel={IS_ANDROID ? processSelectionWithTimeout : undefined} aria-label={placeholder} - onFocus={onFocus} - onBlur={onBlur} + onFocus={!isNeedPremium ? onFocus : undefined} + onBlur={!isNeedPremium ? onBlur : undefined} /> {!forcedPlaceholder && ( @@ -592,6 +601,11 @@ const MessageInput: FC = ({ {shouldDisplayTimer ? ( ) : placeholder} + {isStoryInput && isNeedPremium && ( + + )} )} @@ -599,8 +613,14 @@ const MessageInput: FC = ({
-
-
+
+