Follow up gifts and stories collections (#6216)
This commit is contained in:
parent
3146f58abc
commit
d3b4c57aab
@ -23,14 +23,14 @@ type OwnProps = {
|
||||
items: TabItem[];
|
||||
selectedItemId?: string;
|
||||
className?: string;
|
||||
animationLevel?: AnimationLevel;
|
||||
animationLevel: AnimationLevel;
|
||||
onItemSelect?: (itemId: string) => void;
|
||||
};
|
||||
|
||||
const AnimatedTabList = ({
|
||||
items,
|
||||
selectedItemId,
|
||||
animationLevel = 1,
|
||||
animationLevel,
|
||||
onItemSelect,
|
||||
className,
|
||||
}: OwnProps) => {
|
||||
|
||||
@ -106,7 +106,7 @@
|
||||
}
|
||||
|
||||
.content {
|
||||
transition: transform 0.3s;
|
||||
transition: transform var(--layer-transition);
|
||||
&.showContentPanel {
|
||||
transform: translateY(3rem);
|
||||
padding-bottom: 3.5rem !important;
|
||||
@ -230,7 +230,7 @@
|
||||
right: 0;
|
||||
left: 0;
|
||||
|
||||
transition: transform 0.3s, opacity 0.3s;
|
||||
transition: transform var(--layer-transition), opacity 0.2s ease;
|
||||
|
||||
&.hiddenPanel {
|
||||
transform: translateY(-100%);
|
||||
|
||||
@ -14,6 +14,7 @@ import type {
|
||||
ApiUser,
|
||||
ApiUserStatus,
|
||||
} from '../../api/types';
|
||||
import type { ProfileCollectionKey } from '../../global/selectors/payments';
|
||||
import type { TabState } from '../../global/types';
|
||||
import type { AnimationLevel, ProfileState, ProfileTabType, SharedMediaType, ThemeKey, ThreadId } from '../../types';
|
||||
import type { RegularLangKey } from '../../types/language';
|
||||
@ -21,6 +22,7 @@ import { MAIN_THREAD_ID } from '../../api/types';
|
||||
import { AudioOrigin, MediaViewerOrigin, NewChatMembersProgress } from '../../types';
|
||||
|
||||
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;
|
||||
import {
|
||||
@ -57,6 +59,7 @@ import {
|
||||
import { selectPremiumLimit } from '../../global/selectors/limits';
|
||||
import { selectMessageDownloadableMedia } from '../../global/selectors/media';
|
||||
import { selectSharedSettings } from '../../global/selectors/sharedState';
|
||||
import { selectActiveStoriesCollectionId } from '../../global/selectors/stories';
|
||||
import { areDeepEqual } from '../../util/areDeepEqual';
|
||||
import { IS_TOUCH_ENV } from '../../util/browser/windowEnvironment';
|
||||
import buildClassName from '../../util/buildClassName';
|
||||
@ -147,8 +150,8 @@ type StateProps = {
|
||||
pinnedStoryIds?: number[];
|
||||
archiveStoryIds?: number[];
|
||||
storyByIds?: Record<number, ApiTypeStory>;
|
||||
selectedStoryAlbumId?: number;
|
||||
activeCollectionId?: number;
|
||||
selectedStoryAlbumId: ProfileCollectionKey;
|
||||
activeCollectionId: ProfileCollectionKey;
|
||||
giftsFilter?: any;
|
||||
chatsById: Record<string, ApiChat>;
|
||||
usersById: Record<string, ApiUser>;
|
||||
@ -613,10 +616,12 @@ const Profile: FC<OwnProps & StateProps> = ({
|
||||
if (isFirstTab) {
|
||||
renderingDelay = !isRightColumnShown ? HIDDEN_RENDER_DELAY : 0;
|
||||
// @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;
|
||||
}
|
||||
const canRenderContent = useAsyncRendering([chatId, threadId, resultType, renderingActiveTab], renderingDelay);
|
||||
|
||||
const canRenderContent = useAsyncRendering([chatId, threadId, resultType,
|
||||
renderingActiveTab, activeCollectionId, selectedStoryAlbumId], renderingDelay);
|
||||
|
||||
function getMemberContextAction(memberId: string): MenuItemContextAction[] | undefined {
|
||||
return memberId === currentUserId || !canDeleteMembers ? undefined : [{
|
||||
@ -986,10 +991,10 @@ const Profile: FC<OwnProps & StateProps> = ({
|
||||
const shouldUseTransitionForContent = resultType === 'stories' || resultType === 'gifts';
|
||||
const contentTransitionKey = (() => {
|
||||
if (resultType === 'stories') {
|
||||
return selectedStoryAlbumId || 0;
|
||||
return selectedStoryAlbumId === 'all' ? 0 : selectedStoryAlbumId;
|
||||
}
|
||||
if (resultType === 'gifts') {
|
||||
return activeCollectionId || 0;
|
||||
return activeCollectionId === 'all' ? 0 : activeCollectionId;
|
||||
}
|
||||
return 0;
|
||||
})();
|
||||
@ -1178,8 +1183,9 @@ export default memo(withGlobal<OwnProps>(
|
||||
&& !isSavedDialog;
|
||||
const peerStories = hasStoriesTab ? selectPeerStories(global, peer.id) : undefined;
|
||||
const tabState = selectTabState(global);
|
||||
const { selectedStoryAlbumId, nextProfileTab, forceScrollProfileTab, savedGifts } = tabState;
|
||||
const storyIds = selectedStoryAlbumId
|
||||
const { nextProfileTab, forceScrollProfileTab, savedGifts } = tabState;
|
||||
const selectedStoryAlbumId = selectActiveStoriesCollectionId(global);
|
||||
const storyIds = selectedStoryAlbumId !== 'all'
|
||||
? peerStories?.idsByAlbumId?.[selectedStoryAlbumId]?.ids
|
||||
: peerStories?.profileIds;
|
||||
const pinnedStoryIds = peerStories?.pinnedIds;
|
||||
@ -1187,8 +1193,8 @@ export default memo(withGlobal<OwnProps>(
|
||||
const archiveStoryIds = peerStories?.archiveIds;
|
||||
|
||||
const hasGiftsTab = Boolean(peerFullInfo?.starGiftCount) && !isSavedDialog;
|
||||
const activeCollectionId = savedGifts.activeCollectionByPeerId[chatId];
|
||||
const peerGifts = savedGifts.collectionsByPeerId[chatId]?.[activeCollectionId || 'all'];
|
||||
const activeCollectionId = selectActiveGiftsCollectionId(global, chatId);
|
||||
const peerGifts = savedGifts.collectionsByPeerId[chatId]?.[activeCollectionId];
|
||||
|
||||
const storyAlbums = global.stories.albumsByPeerId?.[chatId];
|
||||
const giftCollections = global.starGiftCollections?.byPeerId?.[chatId];
|
||||
|
||||
@ -2,10 +2,11 @@ import { memo, useMemo } from '../../../lib/teact/teact';
|
||||
import { getActions, withGlobal } from '../../../global';
|
||||
|
||||
import type { ApiStarGiftCollection } from '../../../api/types';
|
||||
import type { ProfileCollectionKey } from '../../../global/selectors/payments';
|
||||
import type { AnimationLevel } from '../../../types';
|
||||
import type { TabItem } from '../../common/AnimatedTabList';
|
||||
|
||||
import { selectActiveCollectionId } from '../../../global/selectors';
|
||||
import { selectActiveGiftsCollectionId } from '../../../global/selectors';
|
||||
import { selectSharedSettings } from '../../../global/selectors/sharedState';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
|
||||
@ -15,7 +16,6 @@ import useLastCallback from '../../../hooks/useLastCallback';
|
||||
import AnimatedTabList from '../../common/AnimatedTabList';
|
||||
|
||||
import styles from './StarGiftCollectionList.module.scss';
|
||||
|
||||
type OwnProps = {
|
||||
peerId: string;
|
||||
className?: string;
|
||||
@ -23,8 +23,8 @@ type OwnProps = {
|
||||
|
||||
type StateProps = {
|
||||
collections?: ApiStarGiftCollection[];
|
||||
activeCollectionId?: number;
|
||||
animationLevel?: AnimationLevel;
|
||||
activeCollectionId: ProfileCollectionKey;
|
||||
animationLevel: AnimationLevel;
|
||||
};
|
||||
|
||||
const StarGiftCollectionList = ({
|
||||
@ -37,7 +37,7 @@ const StarGiftCollectionList = ({
|
||||
const { updateSelectedGiftCollection, resetSelectedGiftCollection } = getActions();
|
||||
const lang = useLang();
|
||||
|
||||
const handleItemSelect = useLastCallback((itemId?: string) => {
|
||||
const handleItemSelect = useLastCallback((itemId: string) => {
|
||||
if (itemId === 'all') {
|
||||
resetSelectedGiftCollection({ peerId });
|
||||
} else {
|
||||
@ -79,7 +79,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
(global, { peerId }): StateProps => {
|
||||
const { starGiftCollections } = global;
|
||||
const collections = starGiftCollections?.byPeerId?.[peerId];
|
||||
const activeCollectionId = selectActiveCollectionId(global, peerId);
|
||||
const activeCollectionId = selectActiveGiftsCollectionId(global, peerId);
|
||||
|
||||
return {
|
||||
collections,
|
||||
|
||||
@ -2,11 +2,12 @@ import { memo, useMemo } from '../../../lib/teact/teact';
|
||||
import { getActions, withGlobal } from '../../../global';
|
||||
|
||||
import type { ApiStoryAlbum } from '../../../api/types';
|
||||
import type { ProfileCollectionKey } from '../../../global/selectors/payments';
|
||||
import type { AnimationLevel } from '../../../types';
|
||||
import type { TabItem } from '../../common/AnimatedTabList';
|
||||
|
||||
import { selectTabState } from '../../../global/selectors';
|
||||
import { selectSharedSettings } from '../../../global/selectors/sharedState';
|
||||
import { selectActiveStoriesCollectionId } from '../../../global/selectors/stories';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
|
||||
import useLang from '../../../hooks/useLang';
|
||||
@ -23,8 +24,8 @@ type OwnProps = {
|
||||
|
||||
type StateProps = {
|
||||
albums?: ApiStoryAlbum[];
|
||||
selectedAlbumId?: number;
|
||||
animationLevel?: AnimationLevel;
|
||||
selectedAlbumId: ProfileCollectionKey;
|
||||
animationLevel: AnimationLevel;
|
||||
};
|
||||
|
||||
const StoryAlbumList = ({
|
||||
@ -77,9 +78,8 @@ const StoryAlbumList = ({
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
(global, { peerId }): StateProps => {
|
||||
const { stories } = global;
|
||||
const tabState = selectTabState(global);
|
||||
const albums = stories?.albumsByPeerId?.[peerId];
|
||||
const selectedAlbumId = tabState.selectedStoryAlbumId;
|
||||
const selectedAlbumId = selectActiveStoriesCollectionId(global);
|
||||
|
||||
return {
|
||||
albums,
|
||||
|
||||
@ -25,7 +25,7 @@ import {
|
||||
} from '../../reducers';
|
||||
import { updateTabState } from '../../reducers/tabs';
|
||||
import {
|
||||
selectActiveCollectionId,
|
||||
selectActiveGiftsCollectionId,
|
||||
selectGiftProfileFilter,
|
||||
selectPeer,
|
||||
selectPeerSavedGifts,
|
||||
@ -303,18 +303,18 @@ addActionHandler('loadPeerSavedGifts', async (global, actions, payload): Promise
|
||||
if (!shouldRefresh && currentGifts && !localNextOffset) return; // Already loaded all
|
||||
|
||||
const fetchingFilter = selectGiftProfileFilter(global, peerId, tabId);
|
||||
const fetchingCollectionId = selectActiveCollectionId(global, peerId, tabId);
|
||||
const fetchingCollectionId = selectActiveGiftsCollectionId(global, peerId, tabId);
|
||||
|
||||
const result = await callApi('fetchSavedStarGifts', {
|
||||
peer,
|
||||
offset: !shouldRefresh ? localNextOffset : '',
|
||||
filter: fetchingFilter,
|
||||
collectionId: fetchingCollectionId ? Number(fetchingCollectionId) : undefined,
|
||||
collectionId: fetchingCollectionId === 'all' ? undefined : fetchingCollectionId,
|
||||
});
|
||||
|
||||
global = getGlobal();
|
||||
const currentFilter = selectGiftProfileFilter(global, peerId, tabId);
|
||||
const currentCollectionId = selectActiveCollectionId(global, peerId, tabId);
|
||||
const currentCollectionId = selectActiveGiftsCollectionId(global, peerId, tabId);
|
||||
|
||||
if (!result || currentCollectionId !== fetchingCollectionId || currentFilter !== fetchingFilter) {
|
||||
return;
|
||||
@ -400,7 +400,7 @@ addActionHandler('changeGiftVisibility', async (global, actions, payload): Promi
|
||||
const requestInputGift = getRequestInputSavedStarGift(global, gift);
|
||||
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];
|
||||
if (oldGifts?.gifts?.length) {
|
||||
const newGifts = oldGifts.gifts.map((g) => {
|
||||
|
||||
@ -31,6 +31,7 @@ import {
|
||||
selectPeer, selectPeerStories, selectPeerStory,
|
||||
selectPinnedStories, selectTabState,
|
||||
} from '../../selectors';
|
||||
import { selectActiveStoriesCollectionId } from '../../selectors/stories';
|
||||
|
||||
const INFINITE_LOOP_MARKER = 100;
|
||||
|
||||
@ -308,9 +309,8 @@ addActionHandler('loadPeerProfileStories', async (global, actions, payload): Pro
|
||||
return;
|
||||
}
|
||||
|
||||
const tabState = selectTabState(global, tabId);
|
||||
const selectedAlbumId = tabState.selectedStoryAlbumId;
|
||||
if (selectedAlbumId) {
|
||||
const selectedAlbumId = selectActiveStoriesCollectionId(global, tabId);
|
||||
if (selectedAlbumId !== 'all') {
|
||||
let albumData = peerStories?.idsByAlbumId?.[selectedAlbumId];
|
||||
if (albumData?.isFullyLoaded) {
|
||||
return;
|
||||
|
||||
@ -2,7 +2,7 @@ import type { ApiSavedGifts } from '../../../api/types';
|
||||
import type { ActionReturnType } from '../../types';
|
||||
|
||||
import { DEFAULT_GIFT_PROFILE_FILTER_OPTIONS } from '../../../config';
|
||||
import { selectActiveCollectionId } from '../../../global/selectors';
|
||||
import { selectActiveGiftsCollectionId } from '../../../global/selectors';
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { addActionHandler, setGlobal } from '../../index';
|
||||
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, {
|
||||
savedGifts: {
|
||||
@ -126,7 +126,7 @@ addActionHandler('resetGiftProfileFilter', (global, actions, payload): ActionRet
|
||||
const { peerId, tabId = getCurrentTabId() } = payload || {};
|
||||
const tabState = selectTabState(global, tabId);
|
||||
|
||||
const activeCollectionId = selectActiveCollectionId(global, peerId, tabId) || 'all';
|
||||
const activeCollectionId = selectActiveGiftsCollectionId(global, peerId, tabId);
|
||||
|
||||
global = updateTabState(global, {
|
||||
savedGifts: {
|
||||
|
||||
@ -15,7 +15,7 @@ import { getCurrentTabId } from '../../util/establishMultitabRole';
|
||||
import { omit, omitUndefined, unique } from '../../util/iteratees';
|
||||
import { MEMO_EMPTY_ARRAY } from '../../util/memo';
|
||||
import { getSavedGiftKey } from '../helpers/stars';
|
||||
import { selectActiveCollectionId } from '../selectors';
|
||||
import { selectActiveGiftsCollectionId } from '../selectors';
|
||||
import { selectTabState } from '../selectors';
|
||||
import { updateTabState } from './tabs';
|
||||
|
||||
@ -346,7 +346,7 @@ export function replacePeerSavedGifts<T extends GlobalState>(
|
||||
keyCounts.set(id, count + 1);
|
||||
});
|
||||
|
||||
const activeCollectionId = selectActiveCollectionId(global, peerId, tabId) || 'all';
|
||||
const activeCollectionId = selectActiveGiftsCollectionId(global, peerId, tabId);
|
||||
|
||||
return updateTabState(global, {
|
||||
savedGifts: {
|
||||
|
||||
@ -10,6 +10,8 @@ import { selectChat } from './chats';
|
||||
import { selectTabState } from './tabs';
|
||||
import { selectUser } from './users';
|
||||
|
||||
export type ProfileCollectionKey = number | 'all';
|
||||
|
||||
export function selectPaymentInputInvoice<T extends GlobalState>(
|
||||
global: 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);
|
||||
}
|
||||
|
||||
export function selectActiveCollectionId<T extends GlobalState>(
|
||||
export function selectActiveGiftsCollectionId<T extends GlobalState>(
|
||||
global: T,
|
||||
peerId: string,
|
||||
...[tabId = getCurrentTabId()]: TabArgs<T>
|
||||
) {
|
||||
return selectTabState(global, tabId).savedGifts.activeCollectionByPeerId?.[peerId];
|
||||
): ProfileCollectionKey {
|
||||
return selectTabState(global, tabId).savedGifts.activeCollectionByPeerId?.[peerId] || 'all';
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import { isUserId } from '../../util/entities/ids';
|
||||
import { getCurrentTabId } from '../../util/establishMultitabRole';
|
||||
import { isChatAdmin, isDeletedUser } from '../helpers';
|
||||
import { selectChat, selectChatFullInfo } from './chats';
|
||||
import { selectActiveGiftsCollectionId } from './payments';
|
||||
import { selectTabState } from './tabs';
|
||||
import { selectBot, selectUser, selectUserFullInfo } from './users';
|
||||
|
||||
@ -34,7 +35,7 @@ export function selectPeerSavedGifts<T extends GlobalState>(
|
||||
...[tabId = getCurrentTabId()]: TabArgs<T>
|
||||
): ApiSavedGifts | undefined {
|
||||
const tabState = selectTabState(global, tabId);
|
||||
const activeCollectionId = tabState.savedGifts.activeCollectionByPeerId[peerId] || 'all';
|
||||
const activeCollectionId = selectActiveGiftsCollectionId(global, peerId, tabId);
|
||||
return tabState.savedGifts.collectionsByPeerId[peerId]?.[activeCollectionId];
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import type { ApiPeerStories, ApiTypeStory } from '../../api/types';
|
||||
import type { GlobalState, TabArgs } from '../types';
|
||||
import type { ProfileCollectionKey } from './payments';
|
||||
|
||||
import { getCurrentTabId } from '../../util/establishMultitabRole';
|
||||
import { selectPeer } from './peers';
|
||||
@ -150,3 +151,10 @@ function getPeerStoryIdsForViewer<T extends GlobalState>(
|
||||
? storyIds.slice(lastReadIndex + 1)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
export function selectActiveStoriesCollectionId<T extends GlobalState>(
|
||||
global: T,
|
||||
...[tabId = getCurrentTabId()]: TabArgs<T>
|
||||
): ProfileCollectionKey {
|
||||
return selectTabState(global, tabId).selectedStoryAlbumId || 'all';
|
||||
}
|
||||
|
||||
@ -94,6 +94,7 @@ import type {
|
||||
import type { WebApp, WebAppModalStateType } from '../../types/webapp';
|
||||
import type { SearchResultKey } from '../../util/keys/searchResultKey';
|
||||
import type { RegularLangFnParameters } from '../../util/localization';
|
||||
import type { ProfileCollectionKey } from '../selectors/payments';
|
||||
import type { CallbackAction } from './actions';
|
||||
|
||||
export type TabState = {
|
||||
@ -220,7 +221,7 @@ export type TabState = {
|
||||
};
|
||||
|
||||
savedGifts: {
|
||||
collectionsByPeerId: Record<string, Record<number | 'all', ApiSavedGifts>>;
|
||||
collectionsByPeerId: Record<string, Record<ProfileCollectionKey, ApiSavedGifts>>;
|
||||
activeCollectionByPeerId: Record<string, number | undefined>;
|
||||
filter: GiftProfileFilterOptions;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user