User: Add 'Block' option to menu (#3877)

This commit is contained in:
Alexander Zinchuk 2023-09-25 13:00:12 +02:00
parent bcb1a7ae26
commit 548430bd2e
3 changed files with 86 additions and 17 deletions

View File

@ -57,6 +57,7 @@ interface StateProps {
isRightColumnShown?: boolean;
canStartBot?: boolean;
canRestartBot?: boolean;
canUnblock?: boolean;
canSubscribe?: boolean;
canSearch?: boolean;
canCall?: boolean;
@ -88,6 +89,7 @@ const HeaderActions: FC<OwnProps & StateProps> = ({
isChannel,
canStartBot,
canRestartBot,
canUnblock,
canSubscribe,
canSearch,
canCall,
@ -124,6 +126,7 @@ const HeaderActions: FC<OwnProps & StateProps> = ({
togglePeerTranslations,
openChatLanguageModal,
setSettingOption,
unblockUser,
} = getActions();
// eslint-disable-next-line no-null/no-null
const menuButtonRef = useRef<HTMLButtonElement>(null);
@ -162,6 +165,10 @@ const HeaderActions: FC<OwnProps & StateProps> = ({
restartBot({ chatId });
});
const handleUnblock = useLastCallback(() => {
unblockUser({ userId: chatId });
});
const handleTranslateClick = useLastCallback(() => {
if (isTranslating) {
requestChatTranslation({ chatId, toLanguageCode: undefined });
@ -341,6 +348,16 @@ const HeaderActions: FC<OwnProps & StateProps> = ({
{lang('BotRestart')}
</Button>
)}
{canExpandActions && canUnblock && (
<Button
size="tiny"
ripple
fluid
onClick={handleUnblock}
>
{lang('Unblock')}
</Button>
)}
{canSearch && (
<Button
round
@ -403,7 +420,6 @@ const HeaderActions: FC<OwnProps & StateProps> = ({
withExtraActions={isMobile || !canExpandActions}
isChannel={isChannel}
canStartBot={canStartBot}
canRestartBot={canRestartBot}
canSubscribe={canSubscribe}
canSearch={canSearch}
canCall={canCall}
@ -434,6 +450,7 @@ export default memo(withGlobal<OwnProps>(
const isChannel = Boolean(chat && isChatChannel(chat));
const language = selectLanguageCode(global);
const translationLanguage = selectTranslationLanguage(global);
const isPrivate = isUserId(chatId);
const { doNotTranslate } = global.settings.byKey;
if (!chat || chat.isRestricted || selectIsInSelectMode(global)) {
@ -446,16 +463,18 @@ export default memo(withGlobal<OwnProps>(
}
const bot = selectBot(global, chatId);
const chatFullInfo = !isUserId(chatId) ? selectChatFullInfo(global, chatId) : undefined;
const userFullInfo = isUserId(chatId) ? selectUserFullInfo(global, chatId) : undefined;
const chatFullInfo = !isPrivate ? selectChatFullInfo(global, chatId) : undefined;
const userFullInfo = isPrivate ? selectUserFullInfo(global, chatId) : undefined;
const fullInfo = chatFullInfo || userFullInfo;
const isChatWithSelf = selectIsChatWithSelf(global, chatId);
const isMainThread = messageListType === 'thread' && threadId === MAIN_THREAD_ID;
const isDiscussionThread = messageListType === 'thread' && threadId !== MAIN_THREAD_ID;
const isRightColumnShown = selectIsRightColumnShown(global, isMobile);
const canRestartBot = Boolean(bot && selectIsUserBlocked(global, bot.id));
const isUserBlocked = isPrivate ? selectIsUserBlocked(global, chatId) : false;
const canRestartBot = Boolean(bot && isUserBlocked);
const canStartBot = !canRestartBot && Boolean(selectIsChatBotNotStarted(global, chatId));
const canUnblock = isUserBlocked && !bot;
const canSubscribe = Boolean(
(isMainThread || chat.isForum) && (isChannel || isChatSuperGroup(chat)) && chat.isNotJoined,
);
@ -499,6 +518,7 @@ export default memo(withGlobal<OwnProps>(
language,
doNotTranslate,
detectedChatLanguage: chat.detectedLanguage,
canUnblock,
};
},
)(HeaderActions));

View File

@ -76,7 +76,6 @@ export type OwnProps = {
anchor: IAnchorPosition;
isChannel?: boolean;
canStartBot?: boolean;
canRestartBot?: boolean;
canSubscribe?: boolean;
canSearch?: boolean;
canCall?: boolean;
@ -114,6 +113,8 @@ type StateProps = {
isRightColumnShown?: boolean;
canManage?: boolean;
canTranslate?: boolean;
isBlocked?: boolean;
isBot?: boolean;
};
const CLOSE_MENU_ANIMATION_DURATION = 200;
@ -131,7 +132,6 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
isForum,
isChatInfoShown,
canStartBot,
canRestartBot,
canSubscribe,
canSearch,
canCall,
@ -154,6 +154,8 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
canManage,
isRightColumnShown,
canTranslate,
isBlocked,
isBot,
onJoinRequestsClick,
onSubscribeChannel,
onSearchClick,
@ -179,6 +181,8 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
openChat,
toggleManagement,
togglePeerTranslations,
blockUser,
unblockUser,
} = getActions();
const { isMobile } = useAppLayout();
@ -343,6 +347,16 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
closeMenu();
});
const handleBlock = useLastCallback(() => {
blockUser({ userId: chatId });
closeMenu();
});
const handleUnblock = useLastCallback(() => {
unblockUser({ userId: chatId });
closeMenu();
});
useEffect(() => {
disableScrolling();
@ -459,14 +473,6 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
{lang('BotStart')}
</MenuItem>
)}
{withExtraActions && canRestartBot && (
<MenuItem
icon="bots"
onClick={handleRestartBot}
>
{lang('BotRestart')}
</MenuItem>
)}
{withExtraActions && canSubscribe && (
<MenuItem
icon={isChannel ? 'channel' : 'group'}
@ -573,6 +579,22 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
{lang('GiftPremium')}
</MenuItem>
)}
{isBot && (
<MenuItem
icon={isBlocked ? 'bots' : 'hand-stop'}
onClick={isBlocked ? handleRestartBot : handleBlock}
>
{isBlocked ? lang('BotRestart') : lang('Bot.Stop')}
</MenuItem>
)}
{isPrivate && !isBot && (
<MenuItem
icon={isBlocked ? 'user' : 'hand-stop'}
onClick={isBlocked ? handleUnblock : handleBlock}
>
{isBlocked ? lang('Unblock') : lang('BlockUser')}
</MenuItem>
)}
{canLeave && (
<>
<MenuSeparator />
@ -666,6 +688,8 @@ export default memo(withGlobal<OwnProps>(
canManage,
isRightColumnShown: selectIsRightColumnShown(global),
canTranslate,
isBlocked: userFullInfo?.isBlocked,
isBot: Boolean(chatBot),
};
},
)(HeaderMenuContainer));

View File

@ -144,6 +144,7 @@ type StateProps = {
pinnedIds?: number[];
topMessageId?: number;
canUnpin?: boolean;
canUnblock?: boolean;
};
function isImage(item: DataTransferItem) {
@ -198,6 +199,7 @@ function MiddleColumn({
pinnedIds,
topMessageId,
canUnpin,
canUnblock,
}: OwnProps & StateProps) {
const {
openChat,
@ -214,6 +216,7 @@ function MiddleColumn({
loadFullChat,
setLeftColumnWidth,
resetLeftColumnWidth,
unblockUser,
} = getActions();
const { width: windowWidth } = useWindowSize();
@ -251,8 +254,10 @@ function MiddleColumn({
const renderingCanSubscribe = usePrevDuringAnimation(canSubscribe, closeAnimationDuration);
const renderingCanStartBot = usePrevDuringAnimation(canStartBot, closeAnimationDuration);
const renderingCanRestartBot = usePrevDuringAnimation(canRestartBot, closeAnimationDuration);
const renderingCanUnblock = usePrevDuringAnimation(canUnblock, closeAnimationDuration);
const renderingCanPost = usePrevDuringAnimation(canPost, closeAnimationDuration)
&& !renderingCanRestartBot && !renderingCanStartBot && !renderingCanSubscribe && chatId !== TMP_CHAT_ID;
&& !renderingCanRestartBot && !renderingCanStartBot && !renderingCanSubscribe && !renderingCanUnblock
&& chatId !== TMP_CHAT_ID;
const renderingHasTools = usePrevDuringAnimation(hasTools, closeAnimationDuration);
const renderingIsFabShown = usePrevDuringAnimation(isFabShown, closeAnimationDuration) && chatId !== TMP_CHAT_ID;
const renderingIsChannel = usePrevDuringAnimation(isChannel, closeAnimationDuration);
@ -399,6 +404,10 @@ function MiddleColumn({
restartBot({ chatId: chatId! });
});
const handleUnblock = useLastCallback(() => {
unblockUser({ userId: chatId! });
});
const customBackgroundValue = useCustomBackground(theme, customBackground);
const className = buildClassName(
@ -460,7 +469,7 @@ function MiddleColumn({
);
const withMessageListBottomShift = Boolean(
renderingCanRestartBot || renderingCanSubscribe || renderingShouldSendJoinRequest || renderingCanStartBot
|| isPinnedMessageList,
|| isPinnedMessageList || renderingCanUnblock,
);
const withExtraShift = Boolean(isMessagingDisabled || isSelectModeActive || isPinnedMessageList);
@ -622,6 +631,19 @@ function MiddleColumn({
</Button>
</div>
)}
{isMobile && renderingCanUnblock && (
<div className="middle-column-footer-button-container" dir={lang.isRtl ? 'rtl' : undefined}>
<Button
size="tiny"
fluid
ripple
className="join-subscribe-button"
onClick={handleUnblock}
>
{lang('Unblock')}
</Button>
</div>
)}
<MessageSelectToolbar
messageListType={renderingMessageListType}
isActive={isSelectModeActive}
@ -723,8 +745,10 @@ export default memo(withGlobal<OwnProps>(
);
const shouldJoinToSend = Boolean(chat?.isNotJoined && chat.isJoinToSend);
const shouldSendJoinRequest = Boolean(chat?.isNotJoined && chat.isJoinRequest);
const canRestartBot = Boolean(bot && selectIsUserBlocked(global, bot.id));
const isUserBlocked = isPrivate ? selectIsUserBlocked(global, chatId) : false;
const canRestartBot = Boolean(bot && isUserBlocked);
const canStartBot = !canRestartBot && isBotNotStarted;
const canUnblock = isUserBlocked && !bot;
const shouldLoadFullChat = Boolean(
chat && isChatGroup(chat) && !selectChatFullInfo(global, chat.id),
);
@ -778,6 +802,7 @@ export default memo(withGlobal<OwnProps>(
pinnedIds,
topMessageId,
canUnpin,
canUnblock,
};
},
)(MiddleColumn));