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

View File

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

View File

@ -8,6 +8,7 @@ import {
PUBLIC_POSTS_SEARCH_DEFAULT_TOTAL_DAILY,
} from '../../../config';
import { selectIsCurrentUserPremium } from '../../../global/selectors';
import buildClassName from '../../../util/buildClassName';
import { formatStarsAsIcon } from '../../../util/localization/format';
import { getServerTime } from '../../../util/serverTime';
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 Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import Loading from '../../ui/Loading';
import TextTimer from '../../ui/TextTimer';
import Transition from '../../ui/Transition';
@ -28,6 +30,7 @@ type OwnProps = {
searchQuery?: string;
searchFlood?: ApiSearchPostsFlood;
onSearch: () => void;
isLoading?: boolean;
};
type StateProps = {
@ -41,6 +44,7 @@ const PublicPostsSearchLauncher = ({
searchQuery,
searchFlood,
onSearch,
isLoading,
isCurrentUserPremium,
starsBalance,
}: OwnProps & StateProps) => {
@ -213,20 +217,52 @@ const PublicPostsSearchLauncher = ({
);
};
if (!isCurrentUserPremium) {
return renderPremiumRequired();
}
const serverTime = getServerTime();
const shouldRenderPaidScreen = searchFlood?.remains === 0
|| (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 (
<Transition
name="fade"
activeKey={shouldRenderPaidScreen ? 0 : 1}
activeKey={getActiveKey()}
>
{shouldRenderPaidScreen ? renderLimitReached() : renderSearchButton()}
{renderContent()}
</Transition>
);
};