Channels: Remove join message from pinned list (#5546)

This commit is contained in:
zubiden 2025-02-13 14:27:32 +01:00 committed by Alexander Zinchuk
parent 0237180cff
commit 792f6be0f7
5 changed files with 43 additions and 32 deletions

View File

@ -261,7 +261,7 @@ const MessageList: FC<OwnProps & StateProps> = ({
} }
const { shouldAppendJoinMessage, shouldAppendJoinMessageAfterCurrent } = (() => { const { shouldAppendJoinMessage, shouldAppendJoinMessageAfterCurrent } = (() => {
if (!channelJoinInfo) return undefined; if (!channelJoinInfo || type !== 'thread') return undefined;
if (prevMessage if (prevMessage
&& prevMessage.date < channelJoinInfo.joinedDate && channelJoinInfo.joinedDate <= message.date) { && prevMessage.date < channelJoinInfo.joinedDate && channelJoinInfo.joinedDate <= message.date) {
return { shouldAppendJoinMessage: true, shouldAppendJoinMessageAfterCurrent: false }; return { shouldAppendJoinMessage: true, shouldAppendJoinMessageAfterCurrent: false };

View File

@ -3,14 +3,16 @@ import React, {
} from '../../../lib/teact/teact'; } from '../../../lib/teact/teact';
import { getActions, getGlobal, withGlobal } from '../../../global'; import { getActions, getGlobal, withGlobal } from '../../../global';
import type { ApiChat } from '../../../api/types'; import type { ApiChat, ApiChatFullInfo } from '../../../api/types';
import { import {
selectChat, selectChat,
selectChatFullInfo,
selectIsCurrentUserPremium, selectIsCurrentUserPremium,
selectSimilarChannelIds, selectSimilarChannelIds,
} from '../../../global/selectors'; } from '../../../global/selectors';
import buildClassName from '../../../util/buildClassName'; import buildClassName from '../../../util/buildClassName';
import { getServerTime } from '../../../util/serverTime';
import { formatIntegerCompact } from '../../../util/textFormat'; import { formatIntegerCompact } from '../../../util/textFormat';
import useTimeout from '../../../hooks/schedulers/useTimeout'; import useTimeout from '../../../hooks/schedulers/useTimeout';
@ -31,6 +33,7 @@ const DEFAULT_BADGE_COLOR = '#3C3C4399';
const SHOW_CHANNELS_NUMBER = 10; const SHOW_CHANNELS_NUMBER = 10;
const MIN_SKELETON_DELAY = 300; const MIN_SKELETON_DELAY = 300;
const MAX_SKELETON_DELAY = 2000; const MAX_SKELETON_DELAY = 2000;
const AUTO_EXPAND_TIME = 10; // Seconds from joining
type OwnProps = { type OwnProps = {
chatId: string; chatId: string;
@ -38,17 +41,19 @@ type OwnProps = {
type StateProps = { type StateProps = {
similarChannelIds?: string[]; similarChannelIds?: string[];
shouldShowInChat?: boolean; isExpanded?: boolean;
count: number; count?: number;
isCurrentUserPremium: boolean; isCurrentUserPremium: boolean;
channelJoinInfo?: ApiChatFullInfo['joinInfo'];
}; };
const SimilarChannels = ({ const SimilarChannels = ({
chatId, chatId,
similarChannelIds, similarChannelIds,
shouldShowInChat, isExpanded,
count, count,
isCurrentUserPremium, isCurrentUserPremium,
channelJoinInfo,
}: StateProps & OwnProps) => { }: StateProps & OwnProps) => {
const lang = useOldLang(); const lang = useOldLang();
const { toggleChannelRecommendations, loadChannelRecommendations } = getActions(); const { toggleChannelRecommendations, loadChannelRecommendations } = getActions();
@ -65,49 +70,58 @@ const SimilarChannels = ({
return similarChannelIds.map((id) => selectChat(global, id)).filter(Boolean); return similarChannelIds.map((id) => selectChat(global, id)).filter(Boolean);
}, [similarChannelIds]); }, [similarChannelIds]);
// Show skeleton while loading similar channels // Show skeleton while loading similar channels
const [shoulRenderSkeleton, setShoulRenderSkeleton] = useState(!similarChannelIds); const [shouldRenderSkeleton, setShouldRenderSkeleton] = useState(false);
const firstSimilarChannels = useMemo(() => similarChannels?.slice(0, SHOW_CHANNELS_NUMBER), [similarChannels]); const firstSimilarChannels = useMemo(() => similarChannels?.slice(0, SHOW_CHANNELS_NUMBER), [similarChannels]);
const areSimilarChannelsPresent = Boolean(firstSimilarChannels?.length); const areSimilarChannelsPresent = Boolean(firstSimilarChannels?.length);
useHorizontalScroll(ref, !areSimilarChannelsPresent || !shouldShowInChat || shoulRenderSkeleton, true);
const isAnimating = isHiding || isShowing; const isAnimating = isHiding || isShowing;
const shouldRenderChannels = Boolean( const shouldRenderChannels = Boolean(
!shoulRenderSkeleton !shouldRenderSkeleton
&& (shouldShowInChat || isAnimating) && (isExpanded || isAnimating)
&& areSimilarChannelsPresent, && areSimilarChannelsPresent,
); );
useHorizontalScroll(ref, !shouldRenderChannels, true);
useEffect(() => { useEffect(() => {
if (!similarChannelIds) { if (!similarChannelIds) {
loadChannelRecommendations({ chatId }); loadChannelRecommendations({ chatId });
} }
}, [chatId, similarChannelIds]); }, [chatId, similarChannelIds]);
useTimeout(() => setShoulRenderSkeleton(false), MAX_SKELETON_DELAY); useTimeout(() => setShouldRenderSkeleton(false), MAX_SKELETON_DELAY);
useEffect(() => { useEffect(() => {
if (shoulRenderSkeleton && similarChannels && shouldShowInChat) { if (shouldRenderSkeleton && similarChannels && isExpanded) {
const id = setTimeout(() => { const id = setTimeout(() => {
setShoulRenderSkeleton(false); setShouldRenderSkeleton(false);
}, MIN_SKELETON_DELAY); }, MIN_SKELETON_DELAY);
return () => clearTimeout(id); return () => clearTimeout(id);
} }
return undefined; return undefined;
}, [similarChannels, shouldShowInChat, shoulRenderSkeleton]); }, [similarChannels, isExpanded, shouldRenderSkeleton]);
const handleToggle = useLastCallback(() => { const handleToggle = useLastCallback(() => {
toggleChannelRecommendations({ chatId }); toggleChannelRecommendations({ chatId });
if (shouldShowInChat) { if (isExpanded) {
markNotShowing(); markNotShowing();
markHiding(); markHiding();
} else { } else {
markShowing(); markShowing();
markNotHiding(); markNotHiding();
setShouldRenderSkeleton(!similarChannelIds);
} }
}); });
useEffect(() => {
if (!channelJoinInfo?.joinedDate || isExpanded) return;
if (getServerTime() - channelJoinInfo.joinedDate <= AUTO_EXPAND_TIME) {
handleToggle();
}
}, [channelJoinInfo, isExpanded]);
return ( return (
<div className={buildClassName(styles.root)}> <div className={buildClassName(styles.root)}>
<div className="join-text"> <div className="join-text">
@ -118,7 +132,7 @@ const SimilarChannels = ({
{lang('ChannelJoined')} {lang('ChannelJoined')}
</span> </span>
</div> </div>
{shoulRenderSkeleton && <Skeleton className={styles.skeleton} />} {shouldRenderSkeleton && <Skeleton className={styles.skeleton} />}
{shouldRenderChannels && ( {shouldRenderChannels && (
<div <div
className={buildClassName( className={buildClassName(
@ -160,7 +174,7 @@ const SimilarChannels = ({
<MoreChannels <MoreChannels
channel={channel} channel={channel}
chatId={chatId} chatId={chatId}
channelsCount={count - SHOW_CHANNELS_NUMBER + 1} channelsCount={count! - SHOW_CHANNELS_NUMBER + 1}
isCurrentUserPremium={isCurrentUserPremium} isCurrentUserPremium={isCurrentUserPremium}
/> />
) : ( ) : (
@ -239,14 +253,16 @@ function MoreChannels({
export default memo( export default memo(
withGlobal<OwnProps>((global, { chatId }): StateProps => { withGlobal<OwnProps>((global, { chatId }): StateProps => {
const { similarChannelIds, shouldShowInChat, count } = selectSimilarChannelIds(global, chatId) || {}; const { similarChannelIds, isExpanded, count } = selectSimilarChannelIds(global, chatId) || {};
const isCurrentUserPremium = selectIsCurrentUserPremium(global); const isCurrentUserPremium = selectIsCurrentUserPremium(global);
const chatFullInfo = selectChatFullInfo(global, chatId);
return { return {
similarChannelIds, similarChannelIds,
shouldShowInChat, isExpanded,
count, count,
isCurrentUserPremium, isCurrentUserPremium,
channelJoinInfo: chatFullInfo?.joinInfo,
}; };
})(SimilarChannels), })(SimilarChannels),
); );

View File

@ -61,7 +61,6 @@ import {
addChats, addChats,
addMessages, addMessages,
addSimilarBots, addSimilarBots,
addSimilarChannels,
addUsers, addUsers,
addUserStatuses, addUserStatuses,
deleteChatMessages, deleteChatMessages,
@ -73,6 +72,7 @@ import {
replaceChatListIds, replaceChatListIds,
replaceChatListLoadingParameters, replaceChatListLoadingParameters,
replaceMessages, replaceMessages,
replaceSimilarChannels,
replaceThreadParam, replaceThreadParam,
replaceUserStatuses, replaceUserStatuses,
toggleSimilarChannels, toggleSimilarChannels,
@ -2691,7 +2691,7 @@ addActionHandler('loadChannelRecommendations', async (global, actions, payload):
const chatsById = buildCollectionByKey(similarChannels, 'id'); const chatsById = buildCollectionByKey(similarChannels, 'id');
global = getGlobal(); global = getGlobal();
global = addSimilarChannels(global, chatId || GLOBAL_SUGGESTED_CHANNELS_ID, Object.keys(chatsById), count); global = replaceSimilarChannels(global, chatId || GLOBAL_SUGGESTED_CHANNELS_ID, Object.keys(chatsById), count);
setGlobal(global); setGlobal(global);
}); });

View File

@ -420,12 +420,11 @@ export function addChatMembers<T extends GlobalState>(global: T, chat: ApiChat,
}); });
} }
export function addSimilarChannels<T extends GlobalState>( export function replaceSimilarChannels<T extends GlobalState>(
global: T, global: T,
chatId: string, chatId: string,
similarChannelIds: string[], similarChannelIds: string[],
count?: number, count?: number,
shouldShowInChat = true,
) { ) {
return { return {
...global, ...global,
@ -436,7 +435,6 @@ export function addSimilarChannels<T extends GlobalState>(
[chatId]: { [chatId]: {
similarChannelIds, similarChannelIds,
count: count || similarChannelIds.length, count: count || similarChannelIds.length,
shouldShowInChat,
}, },
}, },
}, },
@ -457,7 +455,7 @@ export function toggleSimilarChannels<T extends GlobalState>(
...global.chats.similarChannelsById, ...global.chats.similarChannelsById,
[chatId]: { [chatId]: {
...similarChannels, ...similarChannels,
shouldShowInChat: !similarChannels.shouldShowInChat, isExpanded: !similarChannels?.isExpanded,
}, },
}, },
}, },

View File

@ -215,14 +215,11 @@ export type GlobalState = {
forDiscussionIds?: string[]; forDiscussionIds?: string[];
// Obtained from GetFullChat / GetFullChannel // Obtained from GetFullChat / GetFullChannel
fullInfoById: Record<string, ApiChatFullInfo>; fullInfoById: Record<string, ApiChatFullInfo>;
similarChannelsById: Record< similarChannelsById: Partial<Record<string, {
string, isExpanded: boolean;
{ similarChannelIds?: string[];
shouldShowInChat: boolean; count?: number;
similarChannelIds: string[]; }>>;
count: number;
}
>;
similarBotsById: Record<string, SimilarBotsInfo>; similarBotsById: Record<string, SimilarBotsInfo>;
}; };