Various fixes (#5260)

This commit is contained in:
zubiden 2024-11-27 20:34:28 +04:00 committed by Alexander Zinchuk
parent 0ac49997e5
commit 9dca147164
11 changed files with 49 additions and 29 deletions

View File

@ -116,7 +116,7 @@ const LeftMainHeader: FC<OwnProps & StateProps> = ({
const oldLang = useOldLang(); const oldLang = useOldLang();
const lang = useLang(); const lang = useLang();
const { isMobile } = useAppLayout(); const { isMobile, isDesktop } = useAppLayout();
const [isBotMenuOpen, markBotMenuOpen, unmarkBotMenuOpen] = useFlag(); const [isBotMenuOpen, markBotMenuOpen, unmarkBotMenuOpen] = useFlag();
@ -189,7 +189,7 @@ const LeftMainHeader: FC<OwnProps & StateProps> = ({
lockScreen(); lockScreen();
}); });
const isSearchFocused = ( const isSearchFocused = (!isDesktop && !isMessageListOpen) && (
Boolean(globalSearchChatId) Boolean(globalSearchChatId)
|| content === LeftColumnContent.GlobalSearch || content === LeftColumnContent.GlobalSearch
|| content === LeftColumnContent.Contacts || content === LeftColumnContent.Contacts

View File

@ -71,6 +71,10 @@ const SettingsExperimental: FC<OwnProps & StateProps> = ({
requestWave({ startX: e.clientX, startY: e.clientY }); requestWave({ startX: e.clientX, startY: e.clientY });
}); });
const handleRequestConfetti = useLastCallback(() => {
requestConfetti({ withStars: true });
});
const handleSnap = useLastCallback(() => { const handleSnap = useLastCallback(() => {
const button = snapButtonRef.current; const button = snapButtonRef.current;
if (!button) return; if (!button) return;
@ -98,8 +102,7 @@ const SettingsExperimental: FC<OwnProps & StateProps> = ({
</div> </div>
<div className="settings-item"> <div className="settings-item">
<ListItem <ListItem
// eslint-disable-next-line react/jsx-no-bind onClick={handleRequestConfetti}
onClick={() => requestConfetti({ withStars: true })}
icon="animations" icon="animations"
> >
<div className="title">Launch some confetti!</div> <div className="title">Launch some confetti!</div>

View File

@ -24,13 +24,13 @@ import {
} from '../../global/helpers'; } from '../../global/helpers';
import { import {
selectBot, selectBot,
selectCanGift,
selectCanManage, selectCanManage,
selectCanTranslateChat, selectCanTranslateChat,
selectChat, selectChat,
selectChatFullInfo, selectChatFullInfo,
selectCurrentMessageList, selectCurrentMessageList,
selectIsChatWithSelf, selectIsChatWithSelf,
selectIsPremiumPurchaseBlocked,
selectIsRightColumnShown, selectIsRightColumnShown,
selectNotifyExceptions, selectNotifyExceptions,
selectNotifySettings, selectNotifySettings,
@ -743,7 +743,7 @@ export default memo(withGlobal<OwnProps>(
const userFullInfo = isPrivate ? selectUserFullInfo(global, chatId) : undefined; const userFullInfo = isPrivate ? selectUserFullInfo(global, chatId) : undefined;
const chatFullInfo = !isPrivate ? selectChatFullInfo(global, chatId) : undefined; const chatFullInfo = !isPrivate ? selectChatFullInfo(global, chatId) : undefined;
const fullInfo = userFullInfo || chatFullInfo; const fullInfo = userFullInfo || chatFullInfo;
const canGift = !selectIsPremiumPurchaseBlocked(global) && !isChatWithSelf && isPrivate; const canGift = selectCanGift(global, chatId);
const topic = selectTopic(global, chatId, threadId); const topic = selectTopic(global, chatId, threadId);
const canCreateTopic = chat.isForum && ( const canCreateTopic = chat.isForum && (

View File

@ -39,7 +39,7 @@ export default function useHeaderPane<RefType extends HTMLElement = HTMLDivEleme
withResizeObserver?: boolean; withResizeObserver?: boolean;
onStateChange?: (state: PaneState) => void; onStateChange?: (state: PaneState) => void;
}) { }) {
const [shouldRender, setShouldRender] = useState(true); const [shouldRender, setShouldRender] = useState(isOpen);
// eslint-disable-next-line no-null/no-null // eslint-disable-next-line no-null/no-null
const localRef = useRef<RefType>(null); const localRef = useRef<RefType>(null);
const ref = providedRef || localRef; const ref = providedRef || localRef;

View File

@ -772,6 +772,7 @@ const Message: FC<OwnProps & StateProps> = ({
hasThread: hasThread && !noComments, hasThread: hasThread && !noComments,
forceSenderName, forceSenderName,
hasCommentCounter: hasThread && repliesThreadInfo.messagesCount > 0, hasCommentCounter: hasThread && repliesThreadInfo.messagesCount > 0,
hasCommentButton: withCommentButton,
hasActionButton: canForward || canFocus, hasActionButton: canForward || canFocus,
hasReactions, hasReactions,
isGeoLiveActive: location?.mediaType === 'geoLive' && !isGeoLiveExpired(message), isGeoLiveActive: location?.mediaType === 'geoLive' && !isGeoLiveExpired(message),

View File

@ -17,6 +17,7 @@ export function buildContentClassName(
hasThread, hasThread,
forceSenderName, forceSenderName,
hasCommentCounter, hasCommentCounter,
hasCommentButton,
hasActionButton, hasActionButton,
hasReactions, hasReactions,
isGeoLiveActive, isGeoLiveActive,
@ -32,6 +33,7 @@ export function buildContentClassName(
hasThread?: boolean; hasThread?: boolean;
forceSenderName?: boolean; forceSenderName?: boolean;
hasCommentCounter?: boolean; hasCommentCounter?: boolean;
hasCommentButton?: boolean;
hasActionButton?: boolean; hasActionButton?: boolean;
hasReactions?: boolean; hasReactions?: boolean;
isGeoLiveActive?: boolean; isGeoLiveActive?: boolean;
@ -190,7 +192,7 @@ export function buildContentClassName(
classNames.push('has-fact-check'); classNames.push('has-fact-check');
} }
if (isLastInGroup && !hasInlineKeyboard && (photo || !isMediaWithNoText || (location && asForwarded))) { if (isLastInGroup && !hasInlineKeyboard && (photo || !isMediaWithNoText || hasCommentButton)) {
classNames.push('has-appendix'); classNames.push('has-appendix');
} }
} }

View File

@ -2,12 +2,13 @@ import type { FC } from '../../../lib/teact/teact';
import React, { memo, useState } from '../../../lib/teact/teact'; import React, { memo, useState } from '../../../lib/teact/teact';
import { getActions, withGlobal } from '../../../global'; import { getActions, withGlobal } from '../../../global';
import type { ApiChat, ApiUser } from '../../../api/types'; import type { ApiPeer } from '../../../api/types';
import { import {
getChatTitle, getUserFirstOrLastName, getUserFullName, isChatBasicGroup, getChatTitle, getUserFirstOrLastName, getUserFullName, isChatBasicGroup,
} from '../../../global/helpers'; } from '../../../global/helpers';
import { selectChat, selectUser } from '../../../global/selectors'; import { isApiPeerChat, isApiPeerUser } from '../../../global/helpers/peers';
import { selectPeer } from '../../../global/selectors';
import buildClassName from '../../../util/buildClassName'; import buildClassName from '../../../util/buildClassName';
import useCurrentOrPrev from '../../../hooks/useCurrentOrPrev'; import useCurrentOrPrev from '../../../hooks/useCurrentOrPrev';
@ -35,8 +36,7 @@ type OwnProps = {
type StateProps = { type StateProps = {
currentUserId?: string; currentUserId?: string;
chat?: ApiChat; peer?: ApiPeer;
user?: ApiUser;
}; };
const ChatReportPane: FC<OwnProps & StateProps> = ({ const ChatReportPane: FC<OwnProps & StateProps> = ({
@ -46,8 +46,7 @@ const ChatReportPane: FC<OwnProps & StateProps> = ({
canReportSpam, canReportSpam,
canAddContact, canAddContact,
canBlockContact, canBlockContact,
chat, peer,
user,
currentUserId, currentUserId,
onPaneStateChange, onPaneStateChange,
}) => { }) => {
@ -67,6 +66,10 @@ const ChatReportPane: FC<OwnProps & StateProps> = ({
const [isBlockUserModalOpen, openBlockUserModal, closeBlockUserModal] = useFlag(); const [isBlockUserModalOpen, openBlockUserModal, closeBlockUserModal] = useFlag();
const [shouldReportSpam, setShouldReportSpam] = useState<boolean>(true); const [shouldReportSpam, setShouldReportSpam] = useState<boolean>(true);
const [shouldDeleteChat, setShouldDeleteChat] = useState<boolean>(true); const [shouldDeleteChat, setShouldDeleteChat] = useState<boolean>(true);
const renderingPeer = useCurrentOrPrev(peer);
const chat = renderingPeer && isApiPeerChat(renderingPeer) ? renderingPeer : undefined;
const user = renderingPeer && isApiPeerUser(renderingPeer) ? renderingPeer : undefined;
const isBasicGroup = chat && isChatBasicGroup(chat); const isBasicGroup = chat && isChatBasicGroup(chat);
const renderingCanAddContact = useCurrentOrPrev(canAddContact); const renderingCanAddContact = useCurrentOrPrev(canAddContact);
@ -109,7 +112,7 @@ const ChatReportPane: FC<OwnProps & StateProps> = ({
const hasAnyButton = canAddContact || canBlockContact || canReportSpam; const hasAnyButton = canAddContact || canBlockContact || canReportSpam;
const isRendering = Boolean(hasAnyButton && (chat || user)); const isRendering = Boolean(hasAnyButton && peer);
const { ref, shouldRender } = useHeaderPane({ const { ref, shouldRender } = useHeaderPane({
isOpen: isRendering, isOpen: isRendering,
@ -202,7 +205,6 @@ const ChatReportPane: FC<OwnProps & StateProps> = ({
export default memo(withGlobal<OwnProps>( export default memo(withGlobal<OwnProps>(
(global, { chatId }): StateProps => ({ (global, { chatId }): StateProps => ({
currentUserId: global.currentUserId, currentUserId: global.currentUserId,
chat: selectChat(global, chatId), peer: selectPeer(global, chatId),
user: selectUser(global, chatId),
}), }),
)(ChatReportPane)); )(ChatReportPane));

View File

@ -129,6 +129,7 @@ const MiddleSearch: FC<StateProps> = ({
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
// eslint-disable-next-line no-null/no-null // eslint-disable-next-line no-null/no-null
const containerRef = useRef<HTMLDivElement>(null); const containerRef = useRef<HTMLDivElement>(null);
const shouldCancelSearchRef = useRef(false);
const { isMobile } = useAppLayout(); const { isMobile } = useAppLayout();
const oldLang = useOldLang(); const oldLang = useOldLang();
@ -215,14 +216,10 @@ const MiddleSearch: FC<StateProps> = ({
}; };
}, []); }, []);
// Focus message // Reset focus on query result
useEffect(() => { useEffect(() => {
if (foundIds?.length) { setFocusedIndex(-1);
setFocusedIndex(0); }, [lastSearchQuery]);
} else {
setFocusedIndex(-1);
}
}, [searchType, focusMessage, foundIds, threadId]);
// Disable native up/down buttons on iOS // Disable native up/down buttons on iOS
useLayoutEffect(() => { useLayoutEffect(() => {
@ -309,10 +306,15 @@ const MiddleSearch: FC<StateProps> = ({
return; return;
} }
runDebouncedForSearch(() => performMiddleSearch({ chatId, threadId, query })); runDebouncedForSearch(() => {
if (shouldCancelSearchRef.current) return;
performMiddleSearch({ chatId, threadId, query });
});
}); });
const handleQueryChange = useLastCallback((newQuery: string) => { const handleQueryChange = useLastCallback((newQuery: string) => {
shouldCancelSearchRef.current = false;
if (newQuery.startsWith('#') && !isHashtagQuery) { if (newQuery.startsWith('#') && !isHashtagQuery) {
updateMiddleSearch({ chatId: chat!.id, threadId, update: { isHashtag: true } }); updateMiddleSearch({ chatId: chat!.id, threadId, update: { isHashtag: true } });
setQuery(newQuery.slice(1)); setQuery(newQuery.slice(1));
@ -325,6 +327,7 @@ const MiddleSearch: FC<StateProps> = ({
if (!newQuery) { if (!newQuery) {
setIsLoading(false); setIsLoading(false);
resetMiddleSearch(); resetMiddleSearch();
shouldCancelSearchRef.current = true;
} }
}); });
@ -721,7 +724,7 @@ const MiddleSearch: FC<StateProps> = ({
<div className={styles.counter}> <div className={styles.counter}>
{hasQueryData && ( {hasQueryData && (
foundIds?.length ? ( foundIds?.length ? (
oldLang('Of', [focusedIndex + 1, totalCount]) oldLang('Of', [Math.max(focusedIndex + 1, 1), totalCount])
) : foundIds && !foundIds.length && ( ) : foundIds && !foundIds.length && (
oldLang('NoResult') oldLang('NoResult')
) )

View File

@ -3,7 +3,6 @@
width: 22rem; width: 22rem;
max-width: 100vw; max-width: 100vw;
margin: 4.25rem auto 0.25rem; margin: 4.25rem auto 0.25rem;
margin-top: calc(4.25rem + var(--middle-header-panes-height));
z-index: var(--z-notification); z-index: var(--z-notification);
& ~ & { & ~ & {

View File

@ -134,7 +134,7 @@ addActionHandler('performMiddleSearch', async (global, actions, payload): Promis
currentSearch = selectCurrentMiddleSearch(global, tabId); currentSearch = selectCurrentMiddleSearch(global, tabId);
const hasTagChanged = currentSearch?.savedTag && !isSameReaction(savedTag, currentSearch.savedTag); const hasTagChanged = currentSearch?.savedTag && !isSameReaction(savedTag, currentSearch.savedTag);
const hasSearchChanged = currentSearch?.fetchingQuery && currentSearch.fetchingQuery !== query; const hasSearchChanged = currentSearch?.fetchingQuery !== query;
if (!currentSearch || hasSearchChanged || hasTagChanged) { if (!currentSearch || hasSearchChanged || hasTagChanged) {
return; return;
} }

View File

@ -3,6 +3,7 @@ import type {
} from '../../api/types'; } from '../../api/types';
import type { GlobalState } from '../types'; import type { GlobalState } from '../types';
import { SERVICE_NOTIFICATIONS_USER_ID } from '../../config';
import { isUserBot } from '../helpers'; import { isUserBot } from '../helpers';
export function selectUser<T extends GlobalState>(global: T, userId: string): ApiUser | undefined { export function selectUser<T extends GlobalState>(global: T, userId: string): ApiUser | undefined {
@ -41,7 +42,9 @@ export function selectIsGiveawayGiftsPurchaseAvailable<T extends GlobalState>(gl
return global.appConfig?.isGiveawayGiftsPurchaseAvailable ?? true; return global.appConfig?.isGiveawayGiftsPurchaseAvailable ?? true;
} }
// Slow, not to be used in `withGlobal` /**
* Slow, not to be used in `withGlobal`
*/
export function selectUserByPhoneNumber<T extends GlobalState>(global: T, phoneNumber: string) { export function selectUserByPhoneNumber<T extends GlobalState>(global: T, phoneNumber: string) {
const phoneNumberCleaned = phoneNumber.replace(/[^0-9]/g, ''); const phoneNumberCleaned = phoneNumber.replace(/[^0-9]/g, '');
@ -56,3 +59,10 @@ export function selectBot<T extends GlobalState>(global: T, userId: string): Api
return user; return user;
} }
export function selectCanGift<T extends GlobalState>(global: T, userId: string) {
const bot = selectBot(global, userId);
const user = selectUser(global, userId);
return !selectIsPremiumPurchaseBlocked(global) && !bot && !user?.isSelf && userId !== SERVICE_NOTIFICATIONS_USER_ID;
}