108 lines
3.4 KiB
JavaScript
108 lines
3.4 KiB
JavaScript
import { useMemo } from "react";
|
||
import PostOnFeed from "../../pages/PostOnFeed";
|
||
import AdSlot from "../AdSlot";
|
||
import { withAds } from "../../utils/withAds";
|
||
|
||
const AD_EVERY = 10;
|
||
|
||
export default function FeedContent({
|
||
loading,
|
||
cityLoading,
|
||
citySearchActive,
|
||
error,
|
||
filteredAds,
|
||
activeNav,
|
||
searchPrompt,
|
||
liked,
|
||
likeCountAdj,
|
||
onLike,
|
||
onEdit,
|
||
onDelete,
|
||
onMarkFound,
|
||
onImageClick,
|
||
onLocationClick,
|
||
onAuthRequired,
|
||
showAds = false,
|
||
t,
|
||
}) {
|
||
// Реклама вставляется только на главной ленте (showAds). useMemo — чтобы
|
||
// при ре-рендерах (виждет-обновления, лайки и т.п.) позиции слотов не
|
||
// пересчитывались и уже загруженные объявления не терялись.
|
||
const feedItems = useMemo(
|
||
() => withAds(filteredAds, showAds ? AD_EVERY : 0),
|
||
[filteredAds, showAds]
|
||
);
|
||
if (loading || (citySearchActive && cityLoading)) {
|
||
return (
|
||
<div className="f-center">
|
||
<div className="f-spinner-wrap">
|
||
<div className="f-spinner" />
|
||
{t('feed.loading')}
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
if (error) {
|
||
return (
|
||
<div className="f-center">
|
||
<div className="f-center-icon">⚠️</div>
|
||
<div className="f-center-title">{t('feed.loadError')}</div>
|
||
<div className="f-center-sub">{error}</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
if (searchPrompt) {
|
||
return (
|
||
<div className="f-center">
|
||
<div className="f-center-icon">🔍</div>
|
||
<div className="f-center-title">{t('feed.searchPromptTitle')}</div>
|
||
<div className="f-center-sub">{t('feed.searchPromptSub')}</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
if (!filteredAds.length) {
|
||
const emptyMsg = activeNav === "myads"
|
||
? { title: t('feed.emptyMyAdsTitle'), sub: t('feed.emptyMyAdsSub') }
|
||
: activeNav === "favorites"
|
||
? { title: t('feed.emptyFavoritesTitle'), sub: t('feed.emptyFavoritesSub'), icon: "❤️" }
|
||
: citySearchActive
|
||
? { title: t('feed.emptyCityTitle'), sub: t('feed.emptyCitySub') }
|
||
: { title: t('feed.emptyAllTitle'), sub: t('feed.emptyAllSub') };
|
||
|
||
return (
|
||
<div className="f-center">
|
||
<div className="f-center-icon">{emptyMsg.icon || "🔍"}</div>
|
||
<div className="f-center-title">{emptyMsg.title}</div>
|
||
<div className="f-center-sub" dangerouslySetInnerHTML={{ __html: emptyMsg.sub }} />
|
||
</div>
|
||
);
|
||
}
|
||
|
||
return (
|
||
<>
|
||
{feedItems.map((item) =>
|
||
item.kind === "ad" ? (
|
||
<AdSlot key={item.key} />
|
||
) : (
|
||
<PostOnFeed
|
||
key={item.data.id}
|
||
ad={item.data}
|
||
liked={liked.has(item.data.id)}
|
||
likeCountAdj={likeCountAdj[item.data.id] || 0}
|
||
onLike={onLike}
|
||
onEdit={activeNav === "myads" ? onEdit : undefined}
|
||
onDelete={activeNav === "myads" ? onDelete : undefined}
|
||
onMarkFound={activeNav === "myads" ? onMarkFound : undefined}
|
||
isOwner={activeNav === "myads"}
|
||
onImageClick={onImageClick}
|
||
onLocationClick={onLocationClick}
|
||
onAuthRequired={onAuthRequired}
|
||
/>
|
||
)
|
||
)}
|
||
</>
|
||
);
|
||
} |