Global Search: Implement Channels tab (#4549)
This commit is contained in:
parent
6b60fb4759
commit
dd6bc51b59
@ -1998,12 +1998,9 @@ export function setViewForumAsMessages({ chat, isEnabled }: { chat: ApiChat; isE
|
||||
});
|
||||
}
|
||||
|
||||
export async function fetchChannelRecommendations({ chat }: { chat: ApiChat }) {
|
||||
const { id, accessHash } = chat;
|
||||
const channel = buildInputEntity(id, accessHash);
|
||||
|
||||
export async function fetchChannelRecommendations({ chat }: { chat?: ApiChat }) {
|
||||
const result = await invokeRequest(new GramJs.channels.GetChannelRecommendations({
|
||||
channel: channel as GramJs.InputChannel,
|
||||
channel: chat && buildInputEntity(chat.id, chat.accessHash) as GramJs.InputChannel,
|
||||
}));
|
||||
if (!result) {
|
||||
return undefined;
|
||||
@ -2011,12 +2008,13 @@ export async function fetchChannelRecommendations({ chat }: { chat: ApiChat }) {
|
||||
|
||||
updateLocalDb(result);
|
||||
|
||||
const similarChannels = result?.chats
|
||||
.map((c) => buildApiChatFromPreview(c))
|
||||
.filter(Boolean);
|
||||
|
||||
return {
|
||||
similarChannels: result?.chats
|
||||
.map((_chat) => buildApiChatFromPreview(_chat))
|
||||
.filter(Boolean),
|
||||
count:
|
||||
result instanceof GramJs.messages.ChatsSlice ? result.count : undefined,
|
||||
similarChannels,
|
||||
count: result instanceof GramJs.messages.ChatsSlice ? result.count : similarChannels.length,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -1232,6 +1232,7 @@ export async function searchMessagesGlobal({
|
||||
q: query,
|
||||
offsetRate,
|
||||
offsetPeer: new GramJs.InputPeerEmpty(),
|
||||
broadcastsOnly: type === 'channels' || undefined,
|
||||
limit,
|
||||
filter,
|
||||
folderId: ALL_FOLDER_ID,
|
||||
|
||||
@ -786,7 +786,7 @@ export type ApiReplyKeyboard = {
|
||||
};
|
||||
|
||||
export type ApiMessageSearchType = 'text' | 'media' | 'documents' | 'links' | 'audio' | 'voice' | 'profilePhoto';
|
||||
export type ApiGlobalMessageSearchType = 'text' | 'media' | 'documents' | 'links' | 'audio' | 'voice';
|
||||
export type ApiGlobalMessageSearchType = 'text' | 'channels' | 'media' | 'documents' | 'links' | 'audio' | 'voice';
|
||||
|
||||
export type ApiReportReason = 'spam' | 'violence' | 'pornography' | 'childAbuse'
|
||||
| 'copyright' | 'geoIrrelevant' | 'fake' | 'illegalDrugs' | 'personalDetails' | 'other';
|
||||
|
||||
@ -4,15 +4,16 @@ import React, {
|
||||
} from '../../../lib/teact/teact';
|
||||
import { getActions, getGlobal, withGlobal } from '../../../global';
|
||||
|
||||
import type { ApiChat, ApiMessage } from '../../../api/types';
|
||||
import type { ApiMessage } from '../../../api/types';
|
||||
import { LoadMoreDirection } from '../../../types';
|
||||
|
||||
import { ALL_FOLDER_ID } from '../../../config';
|
||||
import { ALL_FOLDER_ID, GLOBAL_SUGGESTED_CHANNELS_ID } from '../../../config';
|
||||
import {
|
||||
filterChatsByName,
|
||||
filterUsersByName,
|
||||
isChatChannel,
|
||||
} from '../../../global/helpers';
|
||||
import { selectTabState } from '../../../global/selectors';
|
||||
import { selectSimilarChannelIds, selectTabState } from '../../../global/selectors';
|
||||
import { getOrderedIds } from '../../../util/folderManager';
|
||||
import { unique } from '../../../util/iteratees';
|
||||
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
||||
@ -21,6 +22,7 @@ import { renderMessageSummary } from '../../common/helpers/renderMessageText';
|
||||
import sortChatIds from '../../common/helpers/sortChatIds';
|
||||
|
||||
import useAppLayout from '../../../hooks/useAppLayout';
|
||||
import useEffectOnce from '../../../hooks/useEffectOnce';
|
||||
import useHorizontalScroll from '../../../hooks/useHorizontalScroll';
|
||||
import useLang from '../../../hooks/useLang';
|
||||
|
||||
@ -37,6 +39,7 @@ export type OwnProps = {
|
||||
searchQuery?: string;
|
||||
dateSearchQuery?: string;
|
||||
searchDate?: number;
|
||||
isChannelList?: boolean;
|
||||
onReset: () => void;
|
||||
onSearchDateSelect: (value: Date) => void;
|
||||
};
|
||||
@ -50,8 +53,8 @@ type StateProps = {
|
||||
globalUserIds?: string[];
|
||||
foundIds?: string[];
|
||||
globalMessagesByChatId?: Record<string, { byId: Record<number, ApiMessage> }>;
|
||||
chatsById: Record<string, ApiChat>;
|
||||
fetchingStatus?: { chats?: boolean; messages?: boolean };
|
||||
suggestedChannelIds?: string[];
|
||||
};
|
||||
|
||||
const MIN_QUERY_LENGTH_FOR_GLOBAL_SEARCH = 4;
|
||||
@ -60,6 +63,7 @@ const LESS_LIST_ITEMS_AMOUNT = 5;
|
||||
const runThrottled = throttle((cb) => cb(), 500, false);
|
||||
|
||||
const ChatResults: FC<OwnProps & StateProps> = ({
|
||||
isChannelList,
|
||||
searchQuery,
|
||||
searchDate,
|
||||
dateSearchQuery,
|
||||
@ -71,13 +75,13 @@ const ChatResults: FC<OwnProps & StateProps> = ({
|
||||
globalUserIds,
|
||||
foundIds,
|
||||
globalMessagesByChatId,
|
||||
chatsById,
|
||||
fetchingStatus,
|
||||
suggestedChannelIds,
|
||||
onReset,
|
||||
onSearchDateSelect,
|
||||
}) => {
|
||||
const {
|
||||
openChat, addRecentlyFoundChatId, searchMessagesGlobal, setGlobalSearchChatId,
|
||||
openChat, addRecentlyFoundChatId, searchMessagesGlobal, setGlobalSearchChatId, loadChannelRecommendations,
|
||||
} = getActions();
|
||||
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
@ -89,11 +93,15 @@ const ChatResults: FC<OwnProps & StateProps> = ({
|
||||
const [shouldShowMoreLocal, setShouldShowMoreLocal] = useState<boolean>(false);
|
||||
const [shouldShowMoreGlobal, setShouldShowMoreGlobal] = useState<boolean>(false);
|
||||
|
||||
useEffectOnce(() => {
|
||||
if (isChannelList) loadChannelRecommendations({});
|
||||
});
|
||||
|
||||
const handleLoadMore = useCallback(({ direction }: { direction: LoadMoreDirection }) => {
|
||||
if (direction === LoadMoreDirection.Backwards) {
|
||||
runThrottled(() => {
|
||||
searchMessagesGlobal({
|
||||
type: 'text',
|
||||
type: isChannelList ? 'channels' : 'text',
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -120,21 +128,32 @@ const ChatResults: FC<OwnProps & StateProps> = ({
|
||||
}, [setGlobalSearchChatId]);
|
||||
|
||||
const localResults = useMemo(() => {
|
||||
if (!searchQuery || (searchQuery.startsWith('@') && searchQuery.length < 2)) {
|
||||
if (!isChannelList && (!searchQuery || (searchQuery.startsWith('@') && searchQuery.length < 2))) {
|
||||
return MEMO_EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
// No need for expensive global updates, so we avoid them
|
||||
const usersById = getGlobal().users.byId;
|
||||
const chatsById = getGlobal().chats.byId;
|
||||
|
||||
const orderedChatIds = getOrderedIds(ALL_FOLDER_ID) ?? [];
|
||||
const filteredChatIds = orderedChatIds.filter((id) => {
|
||||
if (!isChannelList) return true;
|
||||
const chat = chatsById[id];
|
||||
return chat && isChatChannel(chat);
|
||||
});
|
||||
const localChatIds = filterChatsByName(lang, filteredChatIds, chatsById, searchQuery, currentUserId);
|
||||
|
||||
if (isChannelList) return localChatIds;
|
||||
|
||||
const contactIdsWithMe = [
|
||||
...(currentUserId ? [currentUserId] : []),
|
||||
...(contactIds || []),
|
||||
];
|
||||
// No need for expensive global updates on users, so we avoid them
|
||||
const usersById = getGlobal().users.byId;
|
||||
|
||||
const localContactIds = filterUsersByName(
|
||||
contactIdsWithMe, usersById, searchQuery, currentUserId, lang('SavedMessages'),
|
||||
);
|
||||
const orderedChatIds = getOrderedIds(ALL_FOLDER_ID) ?? [];
|
||||
const localChatIds = filterChatsByName(lang, orderedChatIds, chatsById, searchQuery, currentUserId);
|
||||
|
||||
const localPeerIds = unique([
|
||||
...localContactIds,
|
||||
@ -150,20 +169,27 @@ const ChatResults: FC<OwnProps & StateProps> = ({
|
||||
...sortChatIds(localPeerIds, undefined, currentUserId ? [currentUserId] : undefined),
|
||||
...sortChatIds(accountPeerIds),
|
||||
];
|
||||
}, [searchQuery, currentUserId, contactIds, lang, accountChatIds, accountUserIds, chatsById]);
|
||||
}, [searchQuery, lang, currentUserId, contactIds, accountChatIds, accountUserIds, isChannelList]);
|
||||
|
||||
useHorizontalScroll(chatSelectionRef, !localResults.length, true);
|
||||
useHorizontalScroll(chatSelectionRef, !localResults.length || isChannelList, true);
|
||||
|
||||
const globalResults = useMemo(() => {
|
||||
if (!searchQuery || searchQuery.length < MIN_QUERY_LENGTH_FOR_GLOBAL_SEARCH || !globalChatIds || !globalUserIds) {
|
||||
return MEMO_EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
return sortChatIds(
|
||||
unique([...globalChatIds, ...globalUserIds]),
|
||||
true,
|
||||
);
|
||||
}, [globalChatIds, globalUserIds, searchQuery]);
|
||||
// No need for expensive global updates, so we avoid them
|
||||
const chatsById = getGlobal().chats.byId;
|
||||
|
||||
const ids = unique([...globalChatIds, ...globalUserIds]);
|
||||
const filteredIds = ids.filter((id) => {
|
||||
if (!isChannelList) return true;
|
||||
const chat = chatsById[id];
|
||||
return chat && isChatChannel(chat);
|
||||
});
|
||||
|
||||
return sortChatIds(filteredIds, true);
|
||||
}, [globalChatIds, globalUserIds, isChannelList, searchQuery]);
|
||||
|
||||
const foundMessages = useMemo(() => {
|
||||
if ((!searchQuery && !searchDate) || !foundIds || foundIds.length === 0) {
|
||||
@ -188,6 +214,8 @@ const ChatResults: FC<OwnProps & StateProps> = ({
|
||||
}, [shouldShowMoreGlobal]);
|
||||
|
||||
function renderFoundMessage(message: ApiMessage) {
|
||||
const chatsById = getGlobal().chats.byId;
|
||||
|
||||
const text = renderMessageSummary(lang, message);
|
||||
const chat = chatsById[message.chatId];
|
||||
|
||||
@ -207,7 +235,7 @@ const ChatResults: FC<OwnProps & StateProps> = ({
|
||||
const nothingFound = fetchingStatus && !fetchingStatus.chats && !fetchingStatus.messages
|
||||
&& !localResults.length && !globalResults.length && !foundMessages.length;
|
||||
|
||||
if (!searchQuery && !searchDate) {
|
||||
if (!searchQuery && !searchDate && !isChannelList) {
|
||||
return <RecentContacts onReset={onReset} />;
|
||||
}
|
||||
|
||||
@ -234,7 +262,7 @@ const ChatResults: FC<OwnProps & StateProps> = ({
|
||||
description={lang('ChatList.Search.NoResultsDescription')}
|
||||
/>
|
||||
)}
|
||||
{Boolean(localResults.length) && (
|
||||
{Boolean(localResults.length) && !isChannelList && (
|
||||
<div
|
||||
className="chat-selection no-scrollbar"
|
||||
dir={lang.isRtl ? 'rtl' : undefined}
|
||||
@ -257,7 +285,7 @@ const ChatResults: FC<OwnProps & StateProps> = ({
|
||||
{lang(shouldShowMoreLocal ? 'ChatList.Search.ShowLess' : 'ChatList.Search.ShowMore')}
|
||||
</Link>
|
||||
)}
|
||||
{lang('DialogList.SearchSectionDialogs')}
|
||||
{lang(isChannelList ? 'SearchMyChannels' : 'DialogList.SearchSectionDialogs')}
|
||||
</h3>
|
||||
{localResults.map((id, index) => {
|
||||
if (!shouldShowMoreLocal && index >= LESS_LIST_ITEMS_AMOUNT) {
|
||||
@ -298,6 +326,22 @@ const ChatResults: FC<OwnProps & StateProps> = ({
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
{Boolean(suggestedChannelIds?.length) && !searchQuery && (
|
||||
<div className="search-section">
|
||||
<h3 className="section-heading" dir={lang.isRtl ? 'auto' : undefined}>
|
||||
{lang('SearchRecommendedChannels')}
|
||||
</h3>
|
||||
{suggestedChannelIds.map((id) => {
|
||||
return (
|
||||
<LeftSearchResultChat
|
||||
chatId={id}
|
||||
withUsername
|
||||
onClick={handleChatClick}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
{Boolean(foundMessages.length) && (
|
||||
<div className="search-section">
|
||||
<h3 className="section-heading" dir={lang.isRtl ? 'auto' : undefined}>{lang('SearchMessages')}</h3>
|
||||
@ -309,18 +353,14 @@ const ChatResults: FC<OwnProps & StateProps> = ({
|
||||
};
|
||||
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
(global): StateProps => {
|
||||
const { byId: chatsById } = global.chats;
|
||||
|
||||
(global, { isChannelList }): StateProps => {
|
||||
const { userIds: contactIds } = global.contactList || {};
|
||||
const {
|
||||
currentUserId, messages,
|
||||
} = global;
|
||||
|
||||
if (!contactIds) {
|
||||
return {
|
||||
chatsById,
|
||||
};
|
||||
return {};
|
||||
}
|
||||
|
||||
const {
|
||||
@ -329,7 +369,8 @@ export default memo(withGlobal<OwnProps>(
|
||||
const { chatIds: globalChatIds, userIds: globalUserIds } = globalResults || {};
|
||||
const { chatIds: accountChatIds, userIds: accountUserIds } = localResults || {};
|
||||
const { byChatId: globalMessagesByChatId } = messages;
|
||||
const foundIds = resultsByType?.text?.foundIds;
|
||||
const foundIds = resultsByType?.[isChannelList ? 'channels' : 'text']?.foundIds;
|
||||
const { similarChannelIds } = selectSimilarChannelIds(global, GLOBAL_SUGGESTED_CHANNELS_ID) || {};
|
||||
|
||||
return {
|
||||
currentUserId,
|
||||
@ -340,8 +381,8 @@ export default memo(withGlobal<OwnProps>(
|
||||
globalUserIds,
|
||||
foundIds,
|
||||
globalMessagesByChatId,
|
||||
chatsById,
|
||||
fetchingStatus,
|
||||
suggestedChannelIds: similarChannelIds,
|
||||
};
|
||||
},
|
||||
)(ChatResults));
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import type { FC } from '../../../lib/teact/teact';
|
||||
import React, {
|
||||
memo, useCallback, useMemo, useRef,
|
||||
memo,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from '../../../lib/teact/teact';
|
||||
import { getActions, withGlobal } from '../../../global';
|
||||
@ -13,6 +15,7 @@ import { parseDateString } from '../../../util/date/dateFormat';
|
||||
import useHistoryBack from '../../../hooks/useHistoryBack';
|
||||
import useKeyboardListNavigation from '../../../hooks/useKeyboardListNavigation';
|
||||
import useLang from '../../../hooks/useLang';
|
||||
import useLastCallback from '../../../hooks/useLastCallback';
|
||||
|
||||
import TabList from '../../ui/TabList';
|
||||
import Transition from '../../ui/Transition';
|
||||
@ -39,6 +42,7 @@ type StateProps = {
|
||||
|
||||
const TABS = [
|
||||
{ type: GlobalSearchContent.ChatList, title: 'SearchAllChatsShort' },
|
||||
{ type: GlobalSearchContent.ChannelList, title: 'ChannelsTab' },
|
||||
{ type: GlobalSearchContent.Media, title: 'SharedMediaTab2' },
|
||||
{ type: GlobalSearchContent.Links, title: 'SharedLinksTab2' },
|
||||
{ type: GlobalSearchContent.Files, title: 'SharedFilesTab2' },
|
||||
@ -48,11 +52,9 @@ const TABS = [
|
||||
|
||||
const CHAT_TABS = [
|
||||
{ type: GlobalSearchContent.ChatList, title: 'All Messages' },
|
||||
...TABS.slice(1),
|
||||
...TABS.slice(2), // Skip ChatList and ChannelList, replaced with All Messages
|
||||
];
|
||||
|
||||
const TRANSITION_RENDER_COUNT = Object.keys(GlobalSearchContent).length / 2;
|
||||
|
||||
const LeftSearch: FC<OwnProps & StateProps> = ({
|
||||
searchQuery,
|
||||
searchDate,
|
||||
@ -70,15 +72,17 @@ const LeftSearch: FC<OwnProps & StateProps> = ({
|
||||
const [activeTab, setActiveTab] = useState(currentContent);
|
||||
const dateSearchQuery = useMemo(() => parseDateString(searchQuery), [searchQuery]);
|
||||
|
||||
const handleSwitchTab = useCallback((index: number) => {
|
||||
const tab = TABS[index];
|
||||
const tabs = chatId ? CHAT_TABS : TABS;
|
||||
|
||||
const handleSwitchTab = useLastCallback((index: number) => {
|
||||
const tab = tabs[index];
|
||||
setGlobalSearchContent({ content: tab.type });
|
||||
setActiveTab(index);
|
||||
}, [setGlobalSearchContent]);
|
||||
});
|
||||
|
||||
const handleSearchDateSelect = useCallback((value: Date) => {
|
||||
const handleSearchDateSelect = useLastCallback((value: Date) => {
|
||||
setGlobalSearchDate({ date: value.getTime() / 1000 });
|
||||
}, [setGlobalSearchDate]);
|
||||
});
|
||||
|
||||
useHistoryBack({
|
||||
isActive,
|
||||
@ -91,15 +95,16 @@ const LeftSearch: FC<OwnProps & StateProps> = ({
|
||||
|
||||
return (
|
||||
<div className="LeftSearch" ref={containerRef} onKeyDown={handleKeyDown}>
|
||||
<TabList activeTab={activeTab} tabs={chatId ? CHAT_TABS : TABS} onSwitchTab={handleSwitchTab} />
|
||||
<TabList activeTab={activeTab} tabs={tabs} onSwitchTab={handleSwitchTab} />
|
||||
<Transition
|
||||
name={lang.isRtl ? 'slideOptimizedRtl' : 'slideOptimized'}
|
||||
renderCount={TRANSITION_RENDER_COUNT}
|
||||
renderCount={tabs.length}
|
||||
activeKey={currentContent}
|
||||
>
|
||||
{(() => {
|
||||
switch (currentContent) {
|
||||
case GlobalSearchContent.ChatList:
|
||||
case GlobalSearchContent.ChannelList:
|
||||
if (chatId) {
|
||||
return (
|
||||
<ChatMessageResults
|
||||
@ -112,6 +117,7 @@ const LeftSearch: FC<OwnProps & StateProps> = ({
|
||||
}
|
||||
return (
|
||||
<ChatResults
|
||||
isChannelList={currentContent === GlobalSearchContent.ChannelList}
|
||||
searchQuery={searchQuery}
|
||||
searchDate={searchDate}
|
||||
dateSearchQuery={dateSearchQuery}
|
||||
|
||||
@ -197,7 +197,7 @@ const Profile: FC<OwnProps & StateProps> = ({
|
||||
loadPeerPinnedStories,
|
||||
loadStoriesArchive,
|
||||
openPremiumModal,
|
||||
fetchChannelRecommendations,
|
||||
loadChannelRecommendations,
|
||||
} = getActions();
|
||||
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
@ -257,7 +257,7 @@ const Profile: FC<OwnProps & StateProps> = ({
|
||||
|
||||
useEffect(() => {
|
||||
if (isChannel && !similarChannels) {
|
||||
fetchChannelRecommendations({ chatId });
|
||||
loadChannelRecommendations({ chatId });
|
||||
}
|
||||
}, [chatId, isChannel, similarChannels]);
|
||||
|
||||
|
||||
@ -93,6 +93,8 @@ export const STORY_VIEWS_MIN_SEARCH = 15;
|
||||
export const STORY_MIN_REACTIONS_SORT = 10;
|
||||
export const STORY_VIEWS_MIN_CONTACTS_FILTER = 20;
|
||||
|
||||
export const GLOBAL_SUGGESTED_CHANNELS_ID = 'global';
|
||||
|
||||
// As in Telegram for Android
|
||||
// https://github.com/DrKLO/Telegram/blob/51e9947527/TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java#L7799
|
||||
export const TOP_REACTIONS_LIMIT = 100;
|
||||
|
||||
@ -21,6 +21,7 @@ import {
|
||||
CHAT_LIST_LOAD_SLICE,
|
||||
DEBUG,
|
||||
GLOBAL_STATE_CACHE_ARCHIVED_CHAT_LIST_LIMIT,
|
||||
GLOBAL_SUGGESTED_CHANNELS_ID,
|
||||
RE_TG_LINK,
|
||||
SAVED_FOLDER_ID,
|
||||
SERVICE_NOTIFICATIONS_USER_ID,
|
||||
@ -105,6 +106,7 @@ import {
|
||||
selectIsChatPinned,
|
||||
selectIsChatWithSelf,
|
||||
selectLastServiceNotification,
|
||||
selectSimilarChannelIds,
|
||||
selectStickerSet,
|
||||
selectSupportChat,
|
||||
selectTabState,
|
||||
@ -2615,25 +2617,34 @@ addActionHandler('setViewForumAsMessages', (global, actions, payload): ActionRet
|
||||
void callApi('setViewForumAsMessages', { chat, isEnabled });
|
||||
});
|
||||
|
||||
addActionHandler('fetchChannelRecommendations', async (global, actions, payload): Promise<void> => {
|
||||
addActionHandler('loadChannelRecommendations', async (global, actions, payload): Promise<void> => {
|
||||
const { chatId } = payload;
|
||||
const chat = selectChat(global, chatId);
|
||||
const chat = chatId ? selectChat(global, chatId) : undefined;
|
||||
|
||||
if (!chat) {
|
||||
if (chatId && !chat) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { similarChannels, count } = await callApi('fetchChannelRecommendations', {
|
||||
if (!chatId) {
|
||||
const similarChannelIds = selectSimilarChannelIds(global, GLOBAL_SUGGESTED_CHANNELS_ID);
|
||||
if (similarChannelIds) return; // Already cached
|
||||
}
|
||||
|
||||
const result = await callApi('fetchChannelRecommendations', {
|
||||
chat,
|
||||
}) || {};
|
||||
});
|
||||
|
||||
if (!similarChannels) {
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { similarChannels, count } = result;
|
||||
|
||||
const chatsById = buildCollectionByKey(similarChannels, 'id');
|
||||
|
||||
global = getGlobal();
|
||||
global = addChats(global, buildCollectionByKey(similarChannels, 'id'));
|
||||
global = addSimilarChannels(global, chatId, similarChannels.map((channel) => channel.id), count);
|
||||
global = addChats(global, chatsById);
|
||||
global = addSimilarChannels(global, chatId || GLOBAL_SUGGESTED_CHANNELS_ID, Object.keys(chatsById), count);
|
||||
setGlobal(global);
|
||||
});
|
||||
|
||||
|
||||
@ -95,7 +95,7 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
||||
const listType = selectChatListType(global, update.id);
|
||||
const chat = selectChat(global, update.id);
|
||||
if (chat && isChatChannel(chat)) {
|
||||
actions.fetchChannelRecommendations({ chatId: chat.id });
|
||||
actions.loadChannelRecommendations({ chatId: chat.id });
|
||||
const lastMessageId = selectChatLastMessageId(global, chat.id);
|
||||
const localMessage = buildLocalMessage(chat, lastMessageId);
|
||||
localMessage.content.action = {
|
||||
|
||||
@ -184,7 +184,10 @@ export function addChats<T extends GlobalState>(global: T, newById: Record<strin
|
||||
const existingChat = byId[id];
|
||||
const newChat = newById[id];
|
||||
|
||||
if (existingChat && !existingChat.isMin && (newChat.isMin || existingChat.accessHash === newChat.accessHash)) {
|
||||
const membersCountChanged = !existingChat?.membersCount && newChat.membersCount;
|
||||
|
||||
if (existingChat && !existingChat.isMin && !membersCountChanged
|
||||
&& (newChat.isMin || existingChat.accessHash === newChat.accessHash)) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
|
||||
@ -1931,8 +1931,8 @@ export interface ActionPayloads {
|
||||
fetchChat: {
|
||||
chatId: string;
|
||||
};
|
||||
fetchChannelRecommendations: {
|
||||
chatId: string;
|
||||
loadChannelRecommendations: {
|
||||
chatId?: string;
|
||||
};
|
||||
toggleChannelRecommendations: {
|
||||
chatId: string;
|
||||
|
||||
@ -276,6 +276,7 @@ export enum LeftColumnContent {
|
||||
|
||||
export enum GlobalSearchContent {
|
||||
ChatList,
|
||||
ChannelList,
|
||||
Media,
|
||||
Links,
|
||||
Files,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user