import React, { memo, useEffect, useMemo, useRef, useState, } from '../../../lib/teact/teact'; import { getActions, getGlobal, withGlobal } from '../../../global'; import type { ApiChat } from '../../../api/types'; import { selectChat, selectIsCurrentUserPremium, selectSimilarChannelIds, } from '../../../global/selectors'; import buildClassName from '../../../util/buildClassName'; import { formatIntegerCompact } from '../../../util/textFormat'; import useTimeout from '../../../hooks/schedulers/useTimeout'; import useAverageColor from '../../../hooks/useAverageColor'; import useFlag from '../../../hooks/useFlag'; import useHorizontalScroll from '../../../hooks/useHorizontalScroll'; import useLastCallback from '../../../hooks/useLastCallback'; import useOldLang from '../../../hooks/useOldLang'; import Avatar from '../../common/Avatar'; import Icon from '../../common/icons/Icon'; import Button from '../../ui/Button'; import Skeleton from '../../ui/placeholder/Skeleton'; import styles from './SimilarChannels.module.scss'; const DEFAULT_BADGE_COLOR = '#3C3C4399'; const SHOW_CHANNELS_NUMBER = 10; const MIN_SKELETON_DELAY = 300; const MAX_SKELETON_DELAY = 2000; type OwnProps = { chatId: string; }; type StateProps = { similarChannelIds?: string[]; shouldShowInChat?: boolean; count: number; isCurrentUserPremium: boolean; }; const SimilarChannels = ({ chatId, similarChannelIds, shouldShowInChat, count, isCurrentUserPremium, }: StateProps & OwnProps) => { const lang = useOldLang(); const { toggleChannelRecommendations, loadChannelRecommendations } = getActions(); const [isShowing, markShowing, markNotShowing] = useFlag(false); const [isHiding, markHiding, markNotHiding] = useFlag(false); // eslint-disable-next-line no-null/no-null const ref = useRef(null); const similarChannels = useMemo(() => { if (!similarChannelIds) { return undefined; } const global = getGlobal(); return similarChannelIds.map((id) => selectChat(global, id)).filter(Boolean); }, [similarChannelIds]); // Show skeleton while loading similar channels const [shoulRenderSkeleton, setShoulRenderSkeleton] = useState(!similarChannelIds); const firstSimilarChannels = useMemo(() => similarChannels?.slice(0, SHOW_CHANNELS_NUMBER), [similarChannels]); const areSimilarChannelsPresent = Boolean(firstSimilarChannels?.length); useHorizontalScroll(ref, !areSimilarChannelsPresent || !shouldShowInChat || shoulRenderSkeleton, true); const isAnimating = isHiding || isShowing; const shouldRenderChannels = Boolean( !shoulRenderSkeleton && (shouldShowInChat || isAnimating) && areSimilarChannelsPresent, ); useEffect(() => { if (!similarChannelIds) { loadChannelRecommendations({ chatId }); } }, [chatId, similarChannelIds]); useTimeout(() => setShoulRenderSkeleton(false), MAX_SKELETON_DELAY); useEffect(() => { if (shoulRenderSkeleton && similarChannels && shouldShowInChat) { const id = setTimeout(() => { setShoulRenderSkeleton(false); }, MIN_SKELETON_DELAY); return () => clearTimeout(id); } return undefined; }, [similarChannels, shouldShowInChat, shoulRenderSkeleton]); const handleToggle = useLastCallback(() => { toggleChannelRecommendations({ chatId }); if (shouldShowInChat) { markNotShowing(); markHiding(); } else { markShowing(); markNotHiding(); } }); return (
{lang('ChannelJoined')}
{shoulRenderSkeleton && } {shouldRenderChannels && (
{lang('SimilarChannels')}
{firstSimilarChannels?.map((channel, i) => { return i === SHOW_CHANNELS_NUMBER - 1 ? ( ) : ( ); })}
)}
); }; function SimilarChannel({ channel }: { channel: ApiChat }) { const { openChat } = getActions(); const color = useAverageColor(channel, DEFAULT_BADGE_COLOR); return (
openChat({ id: channel.id })}>
{formatIntegerCompact(channel?.membersCount || 0)}
{channel.title}
); } function MoreChannels({ channel, chatId, channelsCount, isCurrentUserPremium, }: { channel: ApiChat; chatId: string; channelsCount: number; isCurrentUserPremium: boolean; }) { const { openPremiumModal, openChatWithInfo } = getActions(); const lang = useOldLang(); const handleClickMore = () => { if (isCurrentUserPremium) { openChatWithInfo({ id: chatId, shouldReplaceHistory: true, profileTab: 'similarChannels', forceScrollProfileTab: true, }); } else { openPremiumModal(); } }; return (
handleClickMore()} >
{`+${channelsCount}`} {!isCurrentUserPremium && }
{lang('MoreSimilar')}
); } export default memo( withGlobal((global, { chatId }): StateProps => { const { similarChannelIds, shouldShowInChat, count } = selectSimilarChannelIds(global, chatId) || {}; const isCurrentUserPremium = selectIsCurrentUserPremium(global); return { similarChannelIds, shouldShowInChat, count, isCurrentUserPremium, }; })(SimilarChannels), );