Follow up gifts and stories collections (#6216)

This commit is contained in:
Alexander Zinchuk 2025-09-19 14:35:05 +02:00
parent 3146f58abc
commit d3b4c57aab
13 changed files with 61 additions and 43 deletions

View File

@ -23,14 +23,14 @@ type OwnProps = {
items: TabItem[]; items: TabItem[];
selectedItemId?: string; selectedItemId?: string;
className?: string; className?: string;
animationLevel?: AnimationLevel; animationLevel: AnimationLevel;
onItemSelect?: (itemId: string) => void; onItemSelect?: (itemId: string) => void;
}; };
const AnimatedTabList = ({ const AnimatedTabList = ({
items, items,
selectedItemId, selectedItemId,
animationLevel = 1, animationLevel,
onItemSelect, onItemSelect,
className, className,
}: OwnProps) => { }: OwnProps) => {

View File

@ -106,7 +106,7 @@
} }
.content { .content {
transition: transform 0.3s; transition: transform var(--layer-transition);
&.showContentPanel { &.showContentPanel {
transform: translateY(3rem); transform: translateY(3rem);
padding-bottom: 3.5rem !important; padding-bottom: 3.5rem !important;
@ -230,7 +230,7 @@
right: 0; right: 0;
left: 0; left: 0;
transition: transform 0.3s, opacity 0.3s; transition: transform var(--layer-transition), opacity 0.2s ease;
&.hiddenPanel { &.hiddenPanel {
transform: translateY(-100%); transform: translateY(-100%);

View File

@ -14,6 +14,7 @@ import type {
ApiUser, ApiUser,
ApiUserStatus, ApiUserStatus,
} from '../../api/types'; } from '../../api/types';
import type { ProfileCollectionKey } from '../../global/selectors/payments';
import type { TabState } from '../../global/types'; import type { TabState } from '../../global/types';
import type { AnimationLevel, ProfileState, ProfileTabType, SharedMediaType, ThemeKey, ThreadId } from '../../types'; import type { AnimationLevel, ProfileState, ProfileTabType, SharedMediaType, ThemeKey, ThreadId } from '../../types';
import type { RegularLangKey } from '../../types/language'; import type { RegularLangKey } from '../../types/language';
@ -21,6 +22,7 @@ import { MAIN_THREAD_ID } from '../../api/types';
import { AudioOrigin, MediaViewerOrigin, NewChatMembersProgress } from '../../types'; import { AudioOrigin, MediaViewerOrigin, NewChatMembersProgress } from '../../types';
import { MEMBERS_SLICE, PROFILE_SENSITIVE_AREA, SHARED_MEDIA_SLICE, SLIDE_TRANSITION_DURATION } from '../../config'; import { MEMBERS_SLICE, PROFILE_SENSITIVE_AREA, SHARED_MEDIA_SLICE, SLIDE_TRANSITION_DURATION } from '../../config';
import { selectActiveGiftsCollectionId } from '../../global/selectors/payments';
const CONTENT_PANEL_SHOW_DELAY = 300; const CONTENT_PANEL_SHOW_DELAY = 300;
import { import {
@ -57,6 +59,7 @@ import {
import { selectPremiumLimit } from '../../global/selectors/limits'; import { selectPremiumLimit } from '../../global/selectors/limits';
import { selectMessageDownloadableMedia } from '../../global/selectors/media'; import { selectMessageDownloadableMedia } from '../../global/selectors/media';
import { selectSharedSettings } from '../../global/selectors/sharedState'; import { selectSharedSettings } from '../../global/selectors/sharedState';
import { selectActiveStoriesCollectionId } from '../../global/selectors/stories';
import { areDeepEqual } from '../../util/areDeepEqual'; import { areDeepEqual } from '../../util/areDeepEqual';
import { IS_TOUCH_ENV } from '../../util/browser/windowEnvironment'; import { IS_TOUCH_ENV } from '../../util/browser/windowEnvironment';
import buildClassName from '../../util/buildClassName'; import buildClassName from '../../util/buildClassName';
@ -147,8 +150,8 @@ type StateProps = {
pinnedStoryIds?: number[]; pinnedStoryIds?: number[];
archiveStoryIds?: number[]; archiveStoryIds?: number[];
storyByIds?: Record<number, ApiTypeStory>; storyByIds?: Record<number, ApiTypeStory>;
selectedStoryAlbumId?: number; selectedStoryAlbumId: ProfileCollectionKey;
activeCollectionId?: number; activeCollectionId: ProfileCollectionKey;
giftsFilter?: any; giftsFilter?: any;
chatsById: Record<string, ApiChat>; chatsById: Record<string, ApiChat>;
usersById: Record<string, ApiUser>; usersById: Record<string, ApiUser>;
@ -613,10 +616,12 @@ const Profile: FC<OwnProps & StateProps> = ({
if (isFirstTab) { if (isFirstTab) {
renderingDelay = !isRightColumnShown ? HIDDEN_RENDER_DELAY : 0; renderingDelay = !isRightColumnShown ? HIDDEN_RENDER_DELAY : 0;
// @optimization Used to delay first render of secondary tabs while animating // @optimization Used to delay first render of secondary tabs while animating
} else if (!viewportIds && !botPreviewMedia) { } else if ((!viewportIds && !botPreviewMedia) || (!gifts?.length && resultType === 'gifts')) {
renderingDelay = SLIDE_TRANSITION_DURATION; renderingDelay = SLIDE_TRANSITION_DURATION;
} }
const canRenderContent = useAsyncRendering([chatId, threadId, resultType, renderingActiveTab], renderingDelay);
const canRenderContent = useAsyncRendering([chatId, threadId, resultType,
renderingActiveTab, activeCollectionId, selectedStoryAlbumId], renderingDelay);
function getMemberContextAction(memberId: string): MenuItemContextAction[] | undefined { function getMemberContextAction(memberId: string): MenuItemContextAction[] | undefined {
return memberId === currentUserId || !canDeleteMembers ? undefined : [{ return memberId === currentUserId || !canDeleteMembers ? undefined : [{
@ -986,10 +991,10 @@ const Profile: FC<OwnProps & StateProps> = ({
const shouldUseTransitionForContent = resultType === 'stories' || resultType === 'gifts'; const shouldUseTransitionForContent = resultType === 'stories' || resultType === 'gifts';
const contentTransitionKey = (() => { const contentTransitionKey = (() => {
if (resultType === 'stories') { if (resultType === 'stories') {
return selectedStoryAlbumId || 0; return selectedStoryAlbumId === 'all' ? 0 : selectedStoryAlbumId;
} }
if (resultType === 'gifts') { if (resultType === 'gifts') {
return activeCollectionId || 0; return activeCollectionId === 'all' ? 0 : activeCollectionId;
} }
return 0; return 0;
})(); })();
@ -1178,8 +1183,9 @@ export default memo(withGlobal<OwnProps>(
&& !isSavedDialog; && !isSavedDialog;
const peerStories = hasStoriesTab ? selectPeerStories(global, peer.id) : undefined; const peerStories = hasStoriesTab ? selectPeerStories(global, peer.id) : undefined;
const tabState = selectTabState(global); const tabState = selectTabState(global);
const { selectedStoryAlbumId, nextProfileTab, forceScrollProfileTab, savedGifts } = tabState; const { nextProfileTab, forceScrollProfileTab, savedGifts } = tabState;
const storyIds = selectedStoryAlbumId const selectedStoryAlbumId = selectActiveStoriesCollectionId(global);
const storyIds = selectedStoryAlbumId !== 'all'
? peerStories?.idsByAlbumId?.[selectedStoryAlbumId]?.ids ? peerStories?.idsByAlbumId?.[selectedStoryAlbumId]?.ids
: peerStories?.profileIds; : peerStories?.profileIds;
const pinnedStoryIds = peerStories?.pinnedIds; const pinnedStoryIds = peerStories?.pinnedIds;
@ -1187,8 +1193,8 @@ export default memo(withGlobal<OwnProps>(
const archiveStoryIds = peerStories?.archiveIds; const archiveStoryIds = peerStories?.archiveIds;
const hasGiftsTab = Boolean(peerFullInfo?.starGiftCount) && !isSavedDialog; const hasGiftsTab = Boolean(peerFullInfo?.starGiftCount) && !isSavedDialog;
const activeCollectionId = savedGifts.activeCollectionByPeerId[chatId]; const activeCollectionId = selectActiveGiftsCollectionId(global, chatId);
const peerGifts = savedGifts.collectionsByPeerId[chatId]?.[activeCollectionId || 'all']; const peerGifts = savedGifts.collectionsByPeerId[chatId]?.[activeCollectionId];
const storyAlbums = global.stories.albumsByPeerId?.[chatId]; const storyAlbums = global.stories.albumsByPeerId?.[chatId];
const giftCollections = global.starGiftCollections?.byPeerId?.[chatId]; const giftCollections = global.starGiftCollections?.byPeerId?.[chatId];

View File

@ -2,10 +2,11 @@ import { memo, useMemo } from '../../../lib/teact/teact';
import { getActions, withGlobal } from '../../../global'; import { getActions, withGlobal } from '../../../global';
import type { ApiStarGiftCollection } from '../../../api/types'; import type { ApiStarGiftCollection } from '../../../api/types';
import type { ProfileCollectionKey } from '../../../global/selectors/payments';
import type { AnimationLevel } from '../../../types'; import type { AnimationLevel } from '../../../types';
import type { TabItem } from '../../common/AnimatedTabList'; import type { TabItem } from '../../common/AnimatedTabList';
import { selectActiveCollectionId } from '../../../global/selectors'; import { selectActiveGiftsCollectionId } from '../../../global/selectors';
import { selectSharedSettings } from '../../../global/selectors/sharedState'; import { selectSharedSettings } from '../../../global/selectors/sharedState';
import buildClassName from '../../../util/buildClassName'; import buildClassName from '../../../util/buildClassName';
@ -15,7 +16,6 @@ import useLastCallback from '../../../hooks/useLastCallback';
import AnimatedTabList from '../../common/AnimatedTabList'; import AnimatedTabList from '../../common/AnimatedTabList';
import styles from './StarGiftCollectionList.module.scss'; import styles from './StarGiftCollectionList.module.scss';
type OwnProps = { type OwnProps = {
peerId: string; peerId: string;
className?: string; className?: string;
@ -23,8 +23,8 @@ type OwnProps = {
type StateProps = { type StateProps = {
collections?: ApiStarGiftCollection[]; collections?: ApiStarGiftCollection[];
activeCollectionId?: number; activeCollectionId: ProfileCollectionKey;
animationLevel?: AnimationLevel; animationLevel: AnimationLevel;
}; };
const StarGiftCollectionList = ({ const StarGiftCollectionList = ({
@ -37,7 +37,7 @@ const StarGiftCollectionList = ({
const { updateSelectedGiftCollection, resetSelectedGiftCollection } = getActions(); const { updateSelectedGiftCollection, resetSelectedGiftCollection } = getActions();
const lang = useLang(); const lang = useLang();
const handleItemSelect = useLastCallback((itemId?: string) => { const handleItemSelect = useLastCallback((itemId: string) => {
if (itemId === 'all') { if (itemId === 'all') {
resetSelectedGiftCollection({ peerId }); resetSelectedGiftCollection({ peerId });
} else { } else {
@ -79,7 +79,7 @@ export default memo(withGlobal<OwnProps>(
(global, { peerId }): StateProps => { (global, { peerId }): StateProps => {
const { starGiftCollections } = global; const { starGiftCollections } = global;
const collections = starGiftCollections?.byPeerId?.[peerId]; const collections = starGiftCollections?.byPeerId?.[peerId];
const activeCollectionId = selectActiveCollectionId(global, peerId); const activeCollectionId = selectActiveGiftsCollectionId(global, peerId);
return { return {
collections, collections,

View File

@ -2,11 +2,12 @@ import { memo, useMemo } from '../../../lib/teact/teact';
import { getActions, withGlobal } from '../../../global'; import { getActions, withGlobal } from '../../../global';
import type { ApiStoryAlbum } from '../../../api/types'; import type { ApiStoryAlbum } from '../../../api/types';
import type { ProfileCollectionKey } from '../../../global/selectors/payments';
import type { AnimationLevel } from '../../../types'; import type { AnimationLevel } from '../../../types';
import type { TabItem } from '../../common/AnimatedTabList'; import type { TabItem } from '../../common/AnimatedTabList';
import { selectTabState } from '../../../global/selectors';
import { selectSharedSettings } from '../../../global/selectors/sharedState'; import { selectSharedSettings } from '../../../global/selectors/sharedState';
import { selectActiveStoriesCollectionId } from '../../../global/selectors/stories';
import buildClassName from '../../../util/buildClassName'; import buildClassName from '../../../util/buildClassName';
import useLang from '../../../hooks/useLang'; import useLang from '../../../hooks/useLang';
@ -23,8 +24,8 @@ type OwnProps = {
type StateProps = { type StateProps = {
albums?: ApiStoryAlbum[]; albums?: ApiStoryAlbum[];
selectedAlbumId?: number; selectedAlbumId: ProfileCollectionKey;
animationLevel?: AnimationLevel; animationLevel: AnimationLevel;
}; };
const StoryAlbumList = ({ const StoryAlbumList = ({
@ -77,9 +78,8 @@ const StoryAlbumList = ({
export default memo(withGlobal<OwnProps>( export default memo(withGlobal<OwnProps>(
(global, { peerId }): StateProps => { (global, { peerId }): StateProps => {
const { stories } = global; const { stories } = global;
const tabState = selectTabState(global);
const albums = stories?.albumsByPeerId?.[peerId]; const albums = stories?.albumsByPeerId?.[peerId];
const selectedAlbumId = tabState.selectedStoryAlbumId; const selectedAlbumId = selectActiveStoriesCollectionId(global);
return { return {
albums, albums,

View File

@ -25,7 +25,7 @@ import {
} from '../../reducers'; } from '../../reducers';
import { updateTabState } from '../../reducers/tabs'; import { updateTabState } from '../../reducers/tabs';
import { import {
selectActiveCollectionId, selectActiveGiftsCollectionId,
selectGiftProfileFilter, selectGiftProfileFilter,
selectPeer, selectPeer,
selectPeerSavedGifts, selectPeerSavedGifts,
@ -303,18 +303,18 @@ addActionHandler('loadPeerSavedGifts', async (global, actions, payload): Promise
if (!shouldRefresh && currentGifts && !localNextOffset) return; // Already loaded all if (!shouldRefresh && currentGifts && !localNextOffset) return; // Already loaded all
const fetchingFilter = selectGiftProfileFilter(global, peerId, tabId); const fetchingFilter = selectGiftProfileFilter(global, peerId, tabId);
const fetchingCollectionId = selectActiveCollectionId(global, peerId, tabId); const fetchingCollectionId = selectActiveGiftsCollectionId(global, peerId, tabId);
const result = await callApi('fetchSavedStarGifts', { const result = await callApi('fetchSavedStarGifts', {
peer, peer,
offset: !shouldRefresh ? localNextOffset : '', offset: !shouldRefresh ? localNextOffset : '',
filter: fetchingFilter, filter: fetchingFilter,
collectionId: fetchingCollectionId ? Number(fetchingCollectionId) : undefined, collectionId: fetchingCollectionId === 'all' ? undefined : fetchingCollectionId,
}); });
global = getGlobal(); global = getGlobal();
const currentFilter = selectGiftProfileFilter(global, peerId, tabId); const currentFilter = selectGiftProfileFilter(global, peerId, tabId);
const currentCollectionId = selectActiveCollectionId(global, peerId, tabId); const currentCollectionId = selectActiveGiftsCollectionId(global, peerId, tabId);
if (!result || currentCollectionId !== fetchingCollectionId || currentFilter !== fetchingFilter) { if (!result || currentCollectionId !== fetchingCollectionId || currentFilter !== fetchingFilter) {
return; return;
@ -400,7 +400,7 @@ addActionHandler('changeGiftVisibility', async (global, actions, payload): Promi
const requestInputGift = getRequestInputSavedStarGift(global, gift); const requestInputGift = getRequestInputSavedStarGift(global, gift);
if (!requestInputGift) return; if (!requestInputGift) return;
const activeCollectionId = selectActiveCollectionId(global, peerId, tabId) || 'all'; const activeCollectionId = selectActiveGiftsCollectionId(global, peerId, tabId);
const oldGifts = selectTabState(global, tabId).savedGifts.collectionsByPeerId[peerId]?.[activeCollectionId]; const oldGifts = selectTabState(global, tabId).savedGifts.collectionsByPeerId[peerId]?.[activeCollectionId];
if (oldGifts?.gifts?.length) { if (oldGifts?.gifts?.length) {
const newGifts = oldGifts.gifts.map((g) => { const newGifts = oldGifts.gifts.map((g) => {

View File

@ -31,6 +31,7 @@ import {
selectPeer, selectPeerStories, selectPeerStory, selectPeer, selectPeerStories, selectPeerStory,
selectPinnedStories, selectTabState, selectPinnedStories, selectTabState,
} from '../../selectors'; } from '../../selectors';
import { selectActiveStoriesCollectionId } from '../../selectors/stories';
const INFINITE_LOOP_MARKER = 100; const INFINITE_LOOP_MARKER = 100;
@ -308,9 +309,8 @@ addActionHandler('loadPeerProfileStories', async (global, actions, payload): Pro
return; return;
} }
const tabState = selectTabState(global, tabId); const selectedAlbumId = selectActiveStoriesCollectionId(global, tabId);
const selectedAlbumId = tabState.selectedStoryAlbumId; if (selectedAlbumId !== 'all') {
if (selectedAlbumId) {
let albumData = peerStories?.idsByAlbumId?.[selectedAlbumId]; let albumData = peerStories?.idsByAlbumId?.[selectedAlbumId];
if (albumData?.isFullyLoaded) { if (albumData?.isFullyLoaded) {
return; return;

View File

@ -2,7 +2,7 @@ import type { ApiSavedGifts } from '../../../api/types';
import type { ActionReturnType } from '../../types'; import type { ActionReturnType } from '../../types';
import { DEFAULT_GIFT_PROFILE_FILTER_OPTIONS } from '../../../config'; import { DEFAULT_GIFT_PROFILE_FILTER_OPTIONS } from '../../../config';
import { selectActiveCollectionId } from '../../../global/selectors'; import { selectActiveGiftsCollectionId } from '../../../global/selectors';
import { getCurrentTabId } from '../../../util/establishMultitabRole'; import { getCurrentTabId } from '../../../util/establishMultitabRole';
import { addActionHandler, setGlobal } from '../../index'; import { addActionHandler, setGlobal } from '../../index';
import { import {
@ -102,7 +102,7 @@ addActionHandler('updateGiftProfileFilter', (global, actions, payload): ActionRe
}; };
} }
const activeCollectionId = selectActiveCollectionId(global, peerId, tabId) || 'all'; const activeCollectionId = selectActiveGiftsCollectionId(global, peerId, tabId);
global = updateTabState(global, { global = updateTabState(global, {
savedGifts: { savedGifts: {
@ -126,7 +126,7 @@ addActionHandler('resetGiftProfileFilter', (global, actions, payload): ActionRet
const { peerId, tabId = getCurrentTabId() } = payload || {}; const { peerId, tabId = getCurrentTabId() } = payload || {};
const tabState = selectTabState(global, tabId); const tabState = selectTabState(global, tabId);
const activeCollectionId = selectActiveCollectionId(global, peerId, tabId) || 'all'; const activeCollectionId = selectActiveGiftsCollectionId(global, peerId, tabId);
global = updateTabState(global, { global = updateTabState(global, {
savedGifts: { savedGifts: {

View File

@ -15,7 +15,7 @@ import { getCurrentTabId } from '../../util/establishMultitabRole';
import { omit, omitUndefined, unique } from '../../util/iteratees'; import { omit, omitUndefined, unique } from '../../util/iteratees';
import { MEMO_EMPTY_ARRAY } from '../../util/memo'; import { MEMO_EMPTY_ARRAY } from '../../util/memo';
import { getSavedGiftKey } from '../helpers/stars'; import { getSavedGiftKey } from '../helpers/stars';
import { selectActiveCollectionId } from '../selectors'; import { selectActiveGiftsCollectionId } from '../selectors';
import { selectTabState } from '../selectors'; import { selectTabState } from '../selectors';
import { updateTabState } from './tabs'; import { updateTabState } from './tabs';
@ -346,7 +346,7 @@ export function replacePeerSavedGifts<T extends GlobalState>(
keyCounts.set(id, count + 1); keyCounts.set(id, count + 1);
}); });
const activeCollectionId = selectActiveCollectionId(global, peerId, tabId) || 'all'; const activeCollectionId = selectActiveGiftsCollectionId(global, peerId, tabId);
return updateTabState(global, { return updateTabState(global, {
savedGifts: { savedGifts: {

View File

@ -10,6 +10,8 @@ import { selectChat } from './chats';
import { selectTabState } from './tabs'; import { selectTabState } from './tabs';
import { selectUser } from './users'; import { selectUser } from './users';
export type ProfileCollectionKey = number | 'all';
export function selectPaymentInputInvoice<T extends GlobalState>( export function selectPaymentInputInvoice<T extends GlobalState>(
global: T, global: T,
...[tabId = getCurrentTabId()]: TabArgs<T> ...[tabId = getCurrentTabId()]: TabArgs<T>
@ -97,10 +99,10 @@ export function selectIsGiftProfileFilterDefault<T extends GlobalState>(
return arePropsShallowEqual(selectTabState(global, tabId).savedGifts.filter, DEFAULT_GIFT_PROFILE_FILTER_OPTIONS); return arePropsShallowEqual(selectTabState(global, tabId).savedGifts.filter, DEFAULT_GIFT_PROFILE_FILTER_OPTIONS);
} }
export function selectActiveCollectionId<T extends GlobalState>( export function selectActiveGiftsCollectionId<T extends GlobalState>(
global: T, global: T,
peerId: string, peerId: string,
...[tabId = getCurrentTabId()]: TabArgs<T> ...[tabId = getCurrentTabId()]: TabArgs<T>
) { ): ProfileCollectionKey {
return selectTabState(global, tabId).savedGifts.activeCollectionByPeerId?.[peerId]; return selectTabState(global, tabId).savedGifts.activeCollectionByPeerId?.[peerId] || 'all';
} }

View File

@ -6,6 +6,7 @@ import { isUserId } from '../../util/entities/ids';
import { getCurrentTabId } from '../../util/establishMultitabRole'; import { getCurrentTabId } from '../../util/establishMultitabRole';
import { isChatAdmin, isDeletedUser } from '../helpers'; import { isChatAdmin, isDeletedUser } from '../helpers';
import { selectChat, selectChatFullInfo } from './chats'; import { selectChat, selectChatFullInfo } from './chats';
import { selectActiveGiftsCollectionId } from './payments';
import { selectTabState } from './tabs'; import { selectTabState } from './tabs';
import { selectBot, selectUser, selectUserFullInfo } from './users'; import { selectBot, selectUser, selectUserFullInfo } from './users';
@ -34,7 +35,7 @@ export function selectPeerSavedGifts<T extends GlobalState>(
...[tabId = getCurrentTabId()]: TabArgs<T> ...[tabId = getCurrentTabId()]: TabArgs<T>
): ApiSavedGifts | undefined { ): ApiSavedGifts | undefined {
const tabState = selectTabState(global, tabId); const tabState = selectTabState(global, tabId);
const activeCollectionId = tabState.savedGifts.activeCollectionByPeerId[peerId] || 'all'; const activeCollectionId = selectActiveGiftsCollectionId(global, peerId, tabId);
return tabState.savedGifts.collectionsByPeerId[peerId]?.[activeCollectionId]; return tabState.savedGifts.collectionsByPeerId[peerId]?.[activeCollectionId];
} }

View File

@ -1,5 +1,6 @@
import type { ApiPeerStories, ApiTypeStory } from '../../api/types'; import type { ApiPeerStories, ApiTypeStory } from '../../api/types';
import type { GlobalState, TabArgs } from '../types'; import type { GlobalState, TabArgs } from '../types';
import type { ProfileCollectionKey } from './payments';
import { getCurrentTabId } from '../../util/establishMultitabRole'; import { getCurrentTabId } from '../../util/establishMultitabRole';
import { selectPeer } from './peers'; import { selectPeer } from './peers';
@ -150,3 +151,10 @@ function getPeerStoryIdsForViewer<T extends GlobalState>(
? storyIds.slice(lastReadIndex + 1) ? storyIds.slice(lastReadIndex + 1)
: undefined; : undefined;
} }
export function selectActiveStoriesCollectionId<T extends GlobalState>(
global: T,
...[tabId = getCurrentTabId()]: TabArgs<T>
): ProfileCollectionKey {
return selectTabState(global, tabId).selectedStoryAlbumId || 'all';
}

View File

@ -94,6 +94,7 @@ import type {
import type { WebApp, WebAppModalStateType } from '../../types/webapp'; import type { WebApp, WebAppModalStateType } from '../../types/webapp';
import type { SearchResultKey } from '../../util/keys/searchResultKey'; import type { SearchResultKey } from '../../util/keys/searchResultKey';
import type { RegularLangFnParameters } from '../../util/localization'; import type { RegularLangFnParameters } from '../../util/localization';
import type { ProfileCollectionKey } from '../selectors/payments';
import type { CallbackAction } from './actions'; import type { CallbackAction } from './actions';
export type TabState = { export type TabState = {
@ -220,7 +221,7 @@ export type TabState = {
}; };
savedGifts: { savedGifts: {
collectionsByPeerId: Record<string, Record<number | 'all', ApiSavedGifts>>; collectionsByPeerId: Record<string, Record<ProfileCollectionKey, ApiSavedGifts>>;
activeCollectionByPeerId: Record<string, number | undefined>; activeCollectionByPeerId: Record<string, number | undefined>;
filter: GiftProfileFilterOptions; filter: GiftProfileFilterOptions;
}; };