Gifts Filter: Support transition for gifts in profile (#5584)
This commit is contained in:
parent
8922beda37
commit
ae4fc89058
@ -131,6 +131,7 @@ type StateProps = {
|
|||||||
hasPreviewMediaTab?: boolean;
|
hasPreviewMediaTab?: boolean;
|
||||||
hasGiftsTab?: boolean;
|
hasGiftsTab?: boolean;
|
||||||
gifts?: ApiSavedStarGift[];
|
gifts?: ApiSavedStarGift[];
|
||||||
|
giftsTransitionKey: number;
|
||||||
areMembersHidden?: boolean;
|
areMembersHidden?: boolean;
|
||||||
canAddMembers?: boolean;
|
canAddMembers?: boolean;
|
||||||
canDeleteMembers?: boolean;
|
canDeleteMembers?: boolean;
|
||||||
@ -199,6 +200,7 @@ const Profile: FC<OwnProps & StateProps> = ({
|
|||||||
hasPreviewMediaTab,
|
hasPreviewMediaTab,
|
||||||
hasGiftsTab,
|
hasGiftsTab,
|
||||||
gifts,
|
gifts,
|
||||||
|
giftsTransitionKey,
|
||||||
botPreviewMedia,
|
botPreviewMedia,
|
||||||
areMembersHidden,
|
areMembersHidden,
|
||||||
canAddMembers,
|
canAddMembers,
|
||||||
@ -490,7 +492,7 @@ const Profile: FC<OwnProps & StateProps> = ({
|
|||||||
}, [hasMembersTab, activeTab, tabs]);
|
}, [hasMembersTab, activeTab, tabs]);
|
||||||
|
|
||||||
const handleResetGiftsFilter = useLastCallback(() => {
|
const handleResetGiftsFilter = useLastCallback(() => {
|
||||||
resetGiftProfileFilter();
|
resetGiftProfileFilter({ peerId: chatId });
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -827,6 +829,20 @@ const Profile: FC<OwnProps & StateProps> = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const shouldUseTransitionForContent = resultType === 'gifts';
|
||||||
|
const contentTransitionKey = giftsTransitionKey;
|
||||||
|
|
||||||
|
function renderContentWithTransition() {
|
||||||
|
return (
|
||||||
|
<Transition
|
||||||
|
activeKey={contentTransitionKey}
|
||||||
|
name="fade"
|
||||||
|
>
|
||||||
|
{renderContent()}
|
||||||
|
</Transition>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InfiniteScroll
|
<InfiniteScroll
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
@ -859,7 +875,7 @@ const Profile: FC<OwnProps & StateProps> = ({
|
|||||||
onStart={applyTransitionFix}
|
onStart={applyTransitionFix}
|
||||||
onStop={handleTransitionStop}
|
onStop={handleTransitionStop}
|
||||||
>
|
>
|
||||||
{renderContent()}
|
{shouldUseTransitionForContent ? renderContentWithTransition() : renderContent()}
|
||||||
</Transition>
|
</Transition>
|
||||||
<TabList activeTab={renderingActiveTab} tabs={tabs} onSwitchTab={handleSwitchTab} />
|
<TabList activeTab={renderingActiveTab} tabs={tabs} onSwitchTab={handleSwitchTab} />
|
||||||
</div>
|
</div>
|
||||||
@ -952,6 +968,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
|
|
||||||
const hasGiftsTab = Boolean(peerFullInfo?.starGiftCount) && !isSavedDialog;
|
const hasGiftsTab = Boolean(peerFullInfo?.starGiftCount) && !isSavedDialog;
|
||||||
const peerGifts = selectTabState(global).savedGifts.giftsByPeerId[chatId];
|
const peerGifts = selectTabState(global).savedGifts.giftsByPeerId[chatId];
|
||||||
|
const giftsTransitionKey = selectTabState(global).savedGifts.transitionKey || 0;
|
||||||
|
|
||||||
const isNotDefaultGiftFilter = !selectIsGiftProfileFilterDefault(global);
|
const isNotDefaultGiftFilter = !selectIsGiftProfileFilterDefault(global);
|
||||||
|
|
||||||
@ -979,6 +996,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
storyIds,
|
storyIds,
|
||||||
hasGiftsTab,
|
hasGiftsTab,
|
||||||
gifts: peerGifts?.gifts,
|
gifts: peerGifts?.gifts,
|
||||||
|
giftsTransitionKey,
|
||||||
pinnedStoryIds,
|
pinnedStoryIds,
|
||||||
archiveStoryIds,
|
archiveStoryIds,
|
||||||
storyByIds,
|
storyByIds,
|
||||||
|
|||||||
@ -509,7 +509,7 @@ const RightHeader: FC<OwnProps & StateProps> = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h3 className="title">{lang('ProfileTabGifts')}</h3>
|
<h3 className="title">{lang('ProfileTabGifts')}</h3>
|
||||||
{canUseGiftFilter && (
|
{canUseGiftFilter && chatId && (
|
||||||
<section className="tools">
|
<section className="tools">
|
||||||
<DropdownMenu
|
<DropdownMenu
|
||||||
trigger={PrimaryLinkMenuButton}
|
trigger={PrimaryLinkMenuButton}
|
||||||
@ -520,7 +520,7 @@ const RightHeader: FC<OwnProps & StateProps> = ({
|
|||||||
icon={giftsSortType === 'byDate' ? 'calendar-filter' : 'cash-circle'}
|
icon={giftsSortType === 'byDate' ? 'calendar-filter' : 'cash-circle'}
|
||||||
// eslint-disable-next-line react/jsx-no-bind
|
// eslint-disable-next-line react/jsx-no-bind
|
||||||
onClick={() => updateGiftProfileFilter(
|
onClick={() => updateGiftProfileFilter(
|
||||||
{ filter: { sortType: giftsSortType === 'byDate' ? 'byValue' : 'byDate' } },
|
{ peerId: chatId, filter: { sortType: giftsSortType === 'byDate' ? 'byValue' : 'byDate' } },
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{lang(giftsSortType === 'byDate' ? 'GiftSortByDate' : 'GiftSortByValue')}
|
{lang(giftsSortType === 'byDate' ? 'GiftSortByDate' : 'GiftSortByValue')}
|
||||||
@ -532,7 +532,7 @@ const RightHeader: FC<OwnProps & StateProps> = ({
|
|||||||
icon={shouldIncludeUnlimitedGifts ? 'check' : 'placeholder'}
|
icon={shouldIncludeUnlimitedGifts ? 'check' : 'placeholder'}
|
||||||
// eslint-disable-next-line react/jsx-no-bind
|
// eslint-disable-next-line react/jsx-no-bind
|
||||||
onClick={() => updateGiftProfileFilter(
|
onClick={() => updateGiftProfileFilter(
|
||||||
{ filter: { shouldIncludeUnlimited: !shouldIncludeUnlimitedGifts } },
|
{ peerId: chatId, filter: { shouldIncludeUnlimited: !shouldIncludeUnlimitedGifts } },
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{lang('GiftFilterUnlimited')}
|
{lang('GiftFilterUnlimited')}
|
||||||
@ -542,7 +542,7 @@ const RightHeader: FC<OwnProps & StateProps> = ({
|
|||||||
icon={shouldIncludeLimitedGifts ? 'check' : 'placeholder'}
|
icon={shouldIncludeLimitedGifts ? 'check' : 'placeholder'}
|
||||||
// eslint-disable-next-line react/jsx-no-bind
|
// eslint-disable-next-line react/jsx-no-bind
|
||||||
onClick={() => updateGiftProfileFilter(
|
onClick={() => updateGiftProfileFilter(
|
||||||
{ filter: { shouldIncludeLimited: !shouldIncludeLimitedGifts } },
|
{ peerId: chatId, filter: { shouldIncludeLimited: !shouldIncludeLimitedGifts } },
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{lang('GiftFilterLimited')}
|
{lang('GiftFilterLimited')}
|
||||||
@ -552,7 +552,7 @@ const RightHeader: FC<OwnProps & StateProps> = ({
|
|||||||
icon={shouldIncludeUniqueGifts ? 'check' : 'placeholder'}
|
icon={shouldIncludeUniqueGifts ? 'check' : 'placeholder'}
|
||||||
// eslint-disable-next-line react/jsx-no-bind
|
// eslint-disable-next-line react/jsx-no-bind
|
||||||
onClick={() => updateGiftProfileFilter(
|
onClick={() => updateGiftProfileFilter(
|
||||||
{ filter: { shouldIncludeUnique: !shouldIncludeUniqueGifts } },
|
{ peerId: chatId, filter: { shouldIncludeUnique: !shouldIncludeUniqueGifts } },
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{lang('GiftFilterUnique')}
|
{lang('GiftFilterUnique')}
|
||||||
@ -565,7 +565,7 @@ const RightHeader: FC<OwnProps & StateProps> = ({
|
|||||||
icon={shouldIncludeDisplayedGifts ? 'check' : 'placeholder'}
|
icon={shouldIncludeDisplayedGifts ? 'check' : 'placeholder'}
|
||||||
// eslint-disable-next-line react/jsx-no-bind
|
// eslint-disable-next-line react/jsx-no-bind
|
||||||
onClick={() => updateGiftProfileFilter(
|
onClick={() => updateGiftProfileFilter(
|
||||||
{ filter: { shouldIncludeDisplayed: !shouldIncludeDisplayedGifts } },
|
{ peerId: chatId, filter: { shouldIncludeDisplayed: !shouldIncludeDisplayedGifts } },
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{lang('GiftFilterDisplayed')}
|
{lang('GiftFilterDisplayed')}
|
||||||
@ -575,7 +575,7 @@ const RightHeader: FC<OwnProps & StateProps> = ({
|
|||||||
icon={shouldIncludeHiddenGifts ? 'check' : 'placeholder'}
|
icon={shouldIncludeHiddenGifts ? 'check' : 'placeholder'}
|
||||||
// eslint-disable-next-line react/jsx-no-bind
|
// eslint-disable-next-line react/jsx-no-bind
|
||||||
onClick={() => updateGiftProfileFilter(
|
onClick={() => updateGiftProfileFilter(
|
||||||
{ filter: { shouldIncludeHidden: !shouldIncludeHiddenGifts } },
|
{ peerId: chatId, filter: { shouldIncludeHidden: !shouldIncludeHiddenGifts } },
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{lang('GiftFilterHidden')}
|
{lang('GiftFilterHidden')}
|
||||||
|
|||||||
@ -138,7 +138,7 @@ addActionHandler('loadStarGifts', async (global): Promise<void> => {
|
|||||||
|
|
||||||
addActionHandler('loadPeerSavedGifts', async (global, actions, payload): Promise<void> => {
|
addActionHandler('loadPeerSavedGifts', async (global, actions, payload): Promise<void> => {
|
||||||
const {
|
const {
|
||||||
peerId, shouldRefresh, tabId = getCurrentTabId(),
|
peerId, shouldRefresh, withTransition, tabId = getCurrentTabId(),
|
||||||
} = payload;
|
} = payload;
|
||||||
|
|
||||||
const peer = selectPeer(global, peerId);
|
const peer = selectPeer(global, peerId);
|
||||||
@ -149,20 +149,35 @@ addActionHandler('loadPeerSavedGifts', async (global, actions, payload): Promise
|
|||||||
|
|
||||||
if (!shouldRefresh && currentGifts && !localNextOffset) return; // Already loaded all
|
if (!shouldRefresh && currentGifts && !localNextOffset) return; // Already loaded all
|
||||||
|
|
||||||
|
global = getGlobal();
|
||||||
|
const fetchingFilter = selectGiftProfileFilter(global, peerId, tabId);
|
||||||
|
|
||||||
const result = await callApi('fetchSavedStarGifts', {
|
const result = await callApi('fetchSavedStarGifts', {
|
||||||
peer,
|
peer,
|
||||||
offset: !shouldRefresh ? localNextOffset : '',
|
offset: !shouldRefresh ? localNextOffset : '',
|
||||||
filter: selectGiftProfileFilter(global, peerId, tabId),
|
filter: fetchingFilter,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!result) {
|
global = getGlobal();
|
||||||
|
const currentFilter = selectGiftProfileFilter(global, peerId, tabId);
|
||||||
|
|
||||||
|
if (!result || currentFilter !== fetchingFilter) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
global = getGlobal();
|
|
||||||
|
|
||||||
const newGifts = currentGifts && !shouldRefresh ? currentGifts.gifts.concat(result.gifts) : result.gifts;
|
const newGifts = currentGifts && !shouldRefresh ? currentGifts.gifts.concat(result.gifts) : result.gifts;
|
||||||
|
|
||||||
|
const tabState = selectTabState(global, tabId);
|
||||||
|
|
||||||
|
if (withTransition) {
|
||||||
|
global = updateTabState(global, {
|
||||||
|
savedGifts: {
|
||||||
|
...tabState.savedGifts,
|
||||||
|
transitionKey: (tabState?.savedGifts.transitionKey || 0) + 1,
|
||||||
|
},
|
||||||
|
}, tabId);
|
||||||
|
}
|
||||||
|
|
||||||
global = replacePeerSavedGifts(global, peerId, newGifts, result.nextOffset, tabId);
|
global = replacePeerSavedGifts(global, peerId, newGifts, result.nextOffset, tabId);
|
||||||
setGlobal(global);
|
setGlobal(global);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import type { ActionReturnType } from '../../types';
|
|||||||
|
|
||||||
import { DEFAULT_GIFT_PROFILE_FILTER_OPTIONS } from '../../../config';
|
import { DEFAULT_GIFT_PROFILE_FILTER_OPTIONS } from '../../../config';
|
||||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||||
import { addActionHandler } from '../../index';
|
import { addActionHandler, setGlobal } from '../../index';
|
||||||
import {
|
import {
|
||||||
clearPayment,
|
clearPayment,
|
||||||
updatePayment,
|
updatePayment,
|
||||||
@ -68,7 +68,7 @@ addActionHandler('closeGiftCodeModal', (global, actions, payload): ActionReturnT
|
|||||||
});
|
});
|
||||||
|
|
||||||
addActionHandler('updateGiftProfileFilter', (global, actions, payload): ActionReturnType => {
|
addActionHandler('updateGiftProfileFilter', (global, actions, payload): ActionReturnType => {
|
||||||
const { filter, tabId = getCurrentTabId() } = payload || {};
|
const { filter, peerId, tabId = getCurrentTabId() } = payload || {};
|
||||||
const tabState = selectTabState(global, tabId);
|
const tabState = selectTabState(global, tabId);
|
||||||
|
|
||||||
const prevFilter = tabState.savedGifts.filter;
|
const prevFilter = tabState.savedGifts.filter;
|
||||||
@ -98,23 +98,40 @@ addActionHandler('updateGiftProfileFilter', (global, actions, payload): ActionRe
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return updateTabState(global, {
|
global = updateTabState(global, {
|
||||||
savedGifts: {
|
savedGifts: {
|
||||||
giftsByPeerId: {},
|
...tabState.savedGifts,
|
||||||
|
giftsByPeerId: {
|
||||||
|
[peerId]: tabState.savedGifts.giftsByPeerId[peerId],
|
||||||
|
},
|
||||||
filter: updatedFilter,
|
filter: updatedFilter,
|
||||||
},
|
},
|
||||||
}, tabId);
|
}, tabId);
|
||||||
|
setGlobal(global);
|
||||||
|
|
||||||
|
actions.loadPeerSavedGifts({
|
||||||
|
peerId, shouldRefresh: true, withTransition: true, tabId: tabState.id,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
addActionHandler('resetGiftProfileFilter', (global, actions, payload): ActionReturnType => {
|
addActionHandler('resetGiftProfileFilter', (global, actions, payload): ActionReturnType => {
|
||||||
const { tabId = getCurrentTabId() } = payload || {};
|
const { peerId, tabId = getCurrentTabId() } = payload || {};
|
||||||
|
const tabState = selectTabState(global, tabId);
|
||||||
|
|
||||||
return updateTabState(global, {
|
global = updateTabState(global, {
|
||||||
savedGifts: {
|
savedGifts: {
|
||||||
giftsByPeerId: {},
|
...tabState.savedGifts,
|
||||||
|
giftsByPeerId: {
|
||||||
|
[peerId]: tabState.savedGifts.giftsByPeerId[peerId],
|
||||||
|
},
|
||||||
filter: {
|
filter: {
|
||||||
...DEFAULT_GIFT_PROFILE_FILTER_OPTIONS,
|
...DEFAULT_GIFT_PROFILE_FILTER_OPTIONS,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, tabId);
|
}, tabId);
|
||||||
|
setGlobal(global);
|
||||||
|
|
||||||
|
actions.loadPeerSavedGifts({
|
||||||
|
peerId, shouldRefresh: true, withTransition: true, tabId: tabState.id,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2369,6 +2369,7 @@ export interface ActionPayloads {
|
|||||||
loadPeerSavedGifts: {
|
loadPeerSavedGifts: {
|
||||||
peerId: string;
|
peerId: string;
|
||||||
shouldRefresh?: boolean;
|
shouldRefresh?: boolean;
|
||||||
|
withTransition?: boolean;
|
||||||
} & WithTabId;
|
} & WithTabId;
|
||||||
changeGiftVisibility: {
|
changeGiftVisibility: {
|
||||||
gift: ApiInputSavedStarGift;
|
gift: ApiInputSavedStarGift;
|
||||||
@ -2397,9 +2398,12 @@ export interface ActionPayloads {
|
|||||||
closeSuggestedStatusModal: WithTabId | undefined;
|
closeSuggestedStatusModal: WithTabId | undefined;
|
||||||
|
|
||||||
updateGiftProfileFilter: {
|
updateGiftProfileFilter: {
|
||||||
|
peerId: string;
|
||||||
filter: Partial<GiftProfileFilterOptions>;
|
filter: Partial<GiftProfileFilterOptions>;
|
||||||
} & WithTabId;
|
} & WithTabId;
|
||||||
resetGiftProfileFilter: WithTabId | undefined;
|
resetGiftProfileFilter: {
|
||||||
|
peerId: string;
|
||||||
|
} & WithTabId;
|
||||||
|
|
||||||
// Invoice
|
// Invoice
|
||||||
openInvoice: Exclude<ApiInputInvoice, ApiInputInvoiceStarGift> & WithTabId;
|
openInvoice: Exclude<ApiInputInvoice, ApiInputInvoiceStarGift> & WithTabId;
|
||||||
|
|||||||
@ -209,6 +209,7 @@ export type TabState = {
|
|||||||
savedGifts: {
|
savedGifts: {
|
||||||
giftsByPeerId: Record<string, ApiSavedGifts>;
|
giftsByPeerId: Record<string, ApiSavedGifts>;
|
||||||
filter: GiftProfileFilterOptions;
|
filter: GiftProfileFilterOptions;
|
||||||
|
transitionKey?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
globalSearch: {
|
globalSearch: {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user