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