Public Posts Results: Add loading state (#6121)

This commit is contained in:
Alexander Zinchuk 2025-08-15 18:25:41 +02:00
parent 922fc7da35
commit 5815da5eae
3 changed files with 52 additions and 10 deletions

View File

@ -31,6 +31,7 @@ type StateProps = {
searchFlood?: ApiSearchPostsFlood; searchFlood?: ApiSearchPostsFlood;
shouldShowSearchLauncher?: boolean; shouldShowSearchLauncher?: boolean;
isNothingFound?: boolean; isNothingFound?: boolean;
isLoading?: boolean;
}; };
const runThrottled = throttle((cb) => cb(), 500, true); const runThrottled = throttle((cb) => cb(), 500, true);
@ -42,6 +43,7 @@ const PublicPostsResults = ({
searchFlood, searchFlood,
shouldShowSearchLauncher, shouldShowSearchLauncher,
isNothingFound, isNothingFound,
isLoading,
}: OwnProps & StateProps) => { }: OwnProps & StateProps) => {
const { searchMessagesGlobal } = getActions(); const { searchMessagesGlobal } = getActions();
@ -103,13 +105,14 @@ const PublicPostsResults = ({
return ( return (
<Transition <Transition
name={lang.isRtl ? 'slideOptimizedRtl' : 'slideOptimized'} name={lang.isRtl ? 'slideOptimizedRtl' : 'slideOptimized'}
activeKey={shouldShowSearchLauncher ? 0 : 1} activeKey={shouldShowSearchLauncher || isLoading ? 0 : 1}
> >
{shouldShowSearchLauncher ? ( {shouldShowSearchLauncher || isLoading ? (
<PublicPostsSearchLauncher <PublicPostsSearchLauncher
searchQuery={searchQuery} searchQuery={searchQuery}
searchFlood={searchFlood} searchFlood={searchFlood}
onSearch={handleSearch} onSearch={handleSearch}
isLoading={isLoading}
/> />
) : ( ) : (
<div className="LeftSearch--content"> <div className="LeftSearch--content">
@ -145,11 +148,12 @@ const PublicPostsResults = ({
export default memo(withGlobal<OwnProps>( export default memo(withGlobal<OwnProps>(
(global): StateProps => { (global): StateProps => {
const { messages: { byChatId: globalMessagesByChatId } } = global; const { messages: { byChatId: globalMessagesByChatId } } = global;
const { resultsByType, searchFlood } = selectTabState(global).globalSearch; const { resultsByType, searchFlood, fetchingStatus } = selectTabState(global).globalSearch;
const publicPostsResult = resultsByType?.publicPosts; const publicPostsResult = resultsByType?.publicPosts;
const { foundIds } = publicPostsResult || {}; const { foundIds } = publicPostsResult || {};
const shouldShowSearchLauncher = !publicPostsResult; const isLoading = Boolean(fetchingStatus?.publicPosts && !publicPostsResult);
const shouldShowSearchLauncher = !publicPostsResult && !isLoading;
const isNothingFound = publicPostsResult && !foundIds?.length; const isNothingFound = publicPostsResult && !foundIds?.length;
return { return {
@ -158,6 +162,7 @@ export default memo(withGlobal<OwnProps>(
searchFlood, searchFlood,
shouldShowSearchLauncher, shouldShowSearchLauncher,
isNothingFound, isNothingFound,
isLoading,
}; };
}, },
)(PublicPostsResults)); )(PublicPostsResults));

View File

@ -18,6 +18,7 @@
text-align: center; text-align: center;
} }
.loadingScreen,
.searchButtonContent { .searchButtonContent {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@ -8,6 +8,7 @@ import {
PUBLIC_POSTS_SEARCH_DEFAULT_TOTAL_DAILY, PUBLIC_POSTS_SEARCH_DEFAULT_TOTAL_DAILY,
} from '../../../config'; } from '../../../config';
import { selectIsCurrentUserPremium } from '../../../global/selectors'; import { selectIsCurrentUserPremium } from '../../../global/selectors';
import buildClassName from '../../../util/buildClassName';
import { formatStarsAsIcon } from '../../../util/localization/format'; import { formatStarsAsIcon } from '../../../util/localization/format';
import { getServerTime } from '../../../util/serverTime'; import { getServerTime } from '../../../util/serverTime';
import { LOCAL_TGS_PREVIEW_URLS, LOCAL_TGS_URLS } from '../../common/helpers/animatedAssets'; import { LOCAL_TGS_PREVIEW_URLS, LOCAL_TGS_URLS } from '../../common/helpers/animatedAssets';
@ -19,6 +20,7 @@ import useLastCallback from '../../../hooks/useLastCallback';
import AnimatedIconWithPreview from '../../common/AnimatedIconWithPreview'; import AnimatedIconWithPreview from '../../common/AnimatedIconWithPreview';
import Icon from '../../common/icons/Icon'; import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button'; import Button from '../../ui/Button';
import Loading from '../../ui/Loading';
import TextTimer from '../../ui/TextTimer'; import TextTimer from '../../ui/TextTimer';
import Transition from '../../ui/Transition'; import Transition from '../../ui/Transition';
@ -28,6 +30,7 @@ type OwnProps = {
searchQuery?: string; searchQuery?: string;
searchFlood?: ApiSearchPostsFlood; searchFlood?: ApiSearchPostsFlood;
onSearch: () => void; onSearch: () => void;
isLoading?: boolean;
}; };
type StateProps = { type StateProps = {
@ -41,6 +44,7 @@ const PublicPostsSearchLauncher = ({
searchQuery, searchQuery,
searchFlood, searchFlood,
onSearch, onSearch,
isLoading,
isCurrentUserPremium, isCurrentUserPremium,
starsBalance, starsBalance,
}: OwnProps & StateProps) => { }: OwnProps & StateProps) => {
@ -213,20 +217,52 @@ const PublicPostsSearchLauncher = ({
); );
}; };
if (!isCurrentUserPremium) {
return renderPremiumRequired();
}
const serverTime = getServerTime(); const serverTime = getServerTime();
const shouldRenderPaidScreen = searchFlood?.remains === 0 const shouldRenderPaidScreen = searchFlood?.remains === 0
|| (searchFlood?.waitTill && searchFlood.waitTill > serverTime); || (searchFlood?.waitTill && searchFlood.waitTill > serverTime);
const renderLoading = () => {
return (
<div className={styles.container}>
<div className={buildClassName(styles.content, styles.loadingScreen)}>
<Loading />
</div>
</div>
);
};
const getActiveKey = () => {
if (!isCurrentUserPremium) {
return 3;
}
if (isLoading) {
return 2;
}
if (shouldRenderPaidScreen) {
return 0;
}
return 1;
};
const renderContent = () => {
if (!isCurrentUserPremium) {
return renderPremiumRequired();
}
if (isLoading) {
return renderLoading();
}
if (shouldRenderPaidScreen) {
return renderLimitReached();
}
return renderSearchButton();
};
return ( return (
<Transition <Transition
name="fade" name="fade"
activeKey={shouldRenderPaidScreen ? 0 : 1} activeKey={getActiveKey()}
> >
{shouldRenderPaidScreen ? renderLimitReached() : renderSearchButton()} {renderContent()}
</Transition> </Transition>
); );
}; };