From 433047267450c32e70f5960a1806634dc22d9171 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Wed, 4 Jun 2025 20:41:18 +0200 Subject: [PATCH] Gifts Modal: Support marketplace (#5936) --- src/api/gramjs/apiBuilders/gifts.ts | 101 ++- src/api/gramjs/methods/stars.ts | 48 +- src/api/types/stars.ts | 34 + src/assets/font-icons/dropdown-arrows.svg | 1 + src/assets/font-icons/sort-by-date.svg | 1 + src/assets/font-icons/sort-by-number.svg | 1 + src/assets/font-icons/sort-by-price.svg | 1 + src/assets/localization/fallback.strings | 20 + src/components/common/gift/GiftRibbon.tsx | 11 +- src/components/modals/gift/GiftComposer.tsx | 78 ++- .../modals/gift/GiftItem.module.scss | 12 +- src/components/modals/gift/GiftItemStar.tsx | 141 +++- .../modals/gift/GiftModal.module.scss | 109 ++- src/components/modals/gift/GiftModal.tsx | 151 +++- .../modals/gift/GiftModalResaleScreen.tsx | 171 +++++ .../modals/gift/GiftResaleFilters.module.scss | 160 +++++ .../modals/gift/GiftResaleFilters.tsx | 655 ++++++++++++++++++ ...ResaleGiftMenuAttributeSticker.module.scss | 7 + .../gift/ResaleGiftMenuAttributeSticker.tsx | 69 ++ .../modals/gift/StarGiftCategoryList.tsx | 4 + .../gift/info/GiftInfoModal.module.scss | 5 +- .../modals/gift/info/GiftInfoModal.tsx | 50 +- src/components/ui/Button.scss | 6 + src/components/ui/Button.tsx | 2 +- src/components/ui/SearchInput.tsx | 3 +- src/config.ts | 6 + src/global/actions/api/payments.ts | 4 +- src/global/actions/api/stars.ts | 117 ++++ src/global/actions/ui/stars.ts | 2 + src/global/initialState.ts | 10 + src/global/types/actions.ts | 11 + src/global/types/tabState.ts | 17 + src/lib/gramjs/tl/apiTl.ts | 1 + src/lib/gramjs/tl/static/api.json | 1 + src/styles/icons.scss | 390 ++++++----- src/styles/icons.woff | Bin 33572 -> 34112 bytes src/styles/icons.woff2 | Bin 28064 -> 28404 bytes src/types/icons/font.ts | 4 + src/types/index.ts | 12 +- src/types/language.d.ts | 28 + 40 files changed, 2132 insertions(+), 312 deletions(-) create mode 100644 src/assets/font-icons/dropdown-arrows.svg create mode 100644 src/assets/font-icons/sort-by-date.svg create mode 100644 src/assets/font-icons/sort-by-number.svg create mode 100644 src/assets/font-icons/sort-by-price.svg create mode 100644 src/components/modals/gift/GiftModalResaleScreen.tsx create mode 100644 src/components/modals/gift/GiftResaleFilters.module.scss create mode 100644 src/components/modals/gift/GiftResaleFilters.tsx create mode 100644 src/components/modals/gift/ResaleGiftMenuAttributeSticker.module.scss create mode 100644 src/components/modals/gift/ResaleGiftMenuAttributeSticker.tsx diff --git a/src/api/gramjs/apiBuilders/gifts.ts b/src/api/gramjs/apiBuilders/gifts.ts index 5d5d6c30b..57274a8af 100644 --- a/src/api/gramjs/apiBuilders/gifts.ts +++ b/src/api/gramjs/apiBuilders/gifts.ts @@ -1,3 +1,4 @@ +import bigInt from 'big-integer'; import { Api as GramJs } from '../../../lib/gramjs'; import type { @@ -6,13 +7,18 @@ import type { ApiSavedStarGift, ApiStarGift, ApiStarGiftAttribute, + ApiStarGiftAttributeCounter, + ApiStarGiftAttributeId, + ApiTypeResaleStarGifts, } from '../../types'; import { numberToHexColor } from '../../../util/colors'; +import { buildApiChatFromPreview } from '../apiBuilders/chats'; import { addDocumentToLocalDb } from '../helpers/localDb'; import { buildApiFormattedText } from './common'; import { getApiChatIdFromMtpPeer } from './peers'; import { buildStickerFromDocument } from './symbols'; +import { buildApiUser } from './users'; export function buildApiStarGift(starGift: GramJs.TypeStarGift): ApiStarGift { if (starGift instanceof GramJs.StarGiftUnique) { @@ -40,7 +46,7 @@ export function buildApiStarGift(starGift: GramJs.TypeStarGift): ApiStarGift { const { id, limited, stars, availabilityRemains, availabilityTotal, convertStars, firstSaleDate, lastSaleDate, soldOut, - birthday, upgradeStars, resellMinStars, title, + birthday, upgradeStars, resellMinStars, title, availabilityResale, } = starGift; addDocumentToLocalDb(starGift.sticker); @@ -63,6 +69,7 @@ export function buildApiStarGift(starGift: GramJs.TypeStarGift): ApiStarGift { upgradeStars: upgradeStars?.toJSNumber(), title, resellMinStars: resellMinStars?.toJSNumber(), + availabilityResale: availabilityResale?.toJSNumber(), }; } @@ -101,11 +108,12 @@ export function buildApiStarGiftAttribute(attribute: GramJs.TypeStarGiftAttribut if (attribute instanceof GramJs.StarGiftAttributeBackdrop) { const { - name, rarityPermille, centerColor, edgeColor, patternColor, textColor, + name, rarityPermille, centerColor, edgeColor, patternColor, textColor, backdropId, } = attribute; return { type: 'backdrop', + backdropId, name, rarityPercent: rarityPermille / 10, centerColor: numberToHexColor(centerColor), @@ -180,3 +188,92 @@ export function buildApiDisallowedGiftsSettings( shouldDisallowPremiumGifts: disallowPremiumGifts, }; } + +export function buildApiStarGiftAttributeId( + result: GramJs.TypeStarGiftAttributeId, +): ApiStarGiftAttributeId | undefined { + if (result instanceof GramJs.StarGiftAttributeIdModel) { + return { + type: 'model', + documentId: result.documentId.toString(), + }; + } + + if (result instanceof GramJs.StarGiftAttributeIdPattern) { + return { + type: 'pattern', + documentId: result.documentId.toString(), + }; + } + + if (result instanceof GramJs.StarGiftAttributeIdBackdrop) { + return { + type: 'backdrop', + backdropId: result.backdropId, + }; + } + + return undefined; +} + +export function buildApiStarGiftAttributeCounter( + result: GramJs.TypeStarGiftAttributeCounter, +): ApiStarGiftAttributeCounter | undefined { + const { + count, + } = result; + + const attribute = buildApiStarGiftAttributeId(result.attribute); + if (!attribute) return undefined; + + return { + count, + attribute, + }; +} + +export function buildApiResaleGifts( + result: GramJs.payments.TypeResaleStarGifts, +): ApiTypeResaleStarGifts { + const { + count, + nextOffset, + attributesHash, + } = result; + + const gifts = result.gifts.map((g) => buildApiStarGift(g)); + const attributes = result.attributes?.map((a) => buildApiStarGiftAttribute(a)).filter(Boolean); + const users = result.users.map((u) => buildApiUser(u)).filter(Boolean); + const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean); + const counters = result.counters?.map((c) => buildApiStarGiftAttributeCounter(c)).filter(Boolean); + + return { + count, + gifts, + nextOffset, + attributes, + attributesHash: attributesHash?.toString(), + chats, + counters, + users, + }; +} + +export function buildInputResaleGiftsAttributes(attributes: ApiStarGiftAttributeId[]): +GramJs.TypeStarGiftAttributeId[] { + return attributes.map((attr) => { + switch (attr.type) { + case 'model': + return new GramJs.StarGiftAttributeIdModel({ documentId: bigInt(attr.documentId) }); + + case 'pattern': + return new GramJs.StarGiftAttributeIdPattern({ documentId: bigInt(attr.documentId) }); + + case 'backdrop': + return new GramJs.StarGiftAttributeIdBackdrop({ backdropId: attr.backdropId }); + + default: + throw new Error(`Unknown attribute type: ${(attr as any).type}`); + } + }); +} diff --git a/src/api/gramjs/methods/stars.ts b/src/api/gramjs/methods/stars.ts index 4093f590a..24e079ddc 100644 --- a/src/api/gramjs/methods/stars.ts +++ b/src/api/gramjs/methods/stars.ts @@ -1,15 +1,17 @@ import bigInt from 'big-integer'; import { Api as GramJs } from '../../../lib/gramjs'; -import type { GiftProfileFilterOptions } from '../../../types'; +import type { GiftProfileFilterOptions, ResaleGiftsFilterOptions } from '../../../types'; import type { ApiChat, ApiPeer, ApiRequestInputSavedStarGift, + ApiStarGiftAttributeId, ApiStarGiftRegular, } from '../../types'; -import { buildApiSavedStarGift, buildApiStarGift, buildApiStarGiftAttribute } from '../apiBuilders/gifts'; +import { buildApiResaleGifts, buildApiSavedStarGift, buildApiStarGift, + buildApiStarGiftAttribute, buildInputResaleGiftsAttributes } from '../apiBuilders/gifts'; import { buildApiStarsAmount, buildApiStarsGiftOptions, @@ -44,6 +46,48 @@ export async function fetchStarGifts() { return result.gifts.map(buildApiStarGift).filter((gift): gift is ApiStarGiftRegular => gift.type === 'starGift'); } +export async function fetchResaleGifts({ + giftId, + offset = '', + limit, + attributesHash = '0', + filter, +}: { + giftId: string; + offset?: string; + limit?: number; + attributesHash?: string; + filter?: ResaleGiftsFilterOptions; +}) { + type GetResaleStarGifts = ConstructorParameters[0]; + + const attributes: ApiStarGiftAttributeId[] = [ + ...(filter?.backdropAttributes ?? []), + ...(filter?.modelAttributes ?? []), + ...(filter?.patternAttributes ?? []), + ]; + + const params: GetResaleStarGifts = { + giftId: bigInt(giftId), + offset, + limit, + attributesHash: attributesHash ? bigInt(attributesHash) : undefined, + attributes: buildInputResaleGiftsAttributes(attributes), + ...(filter && { + sortByPrice: filter.sortType === 'byPrice' || undefined, + sortByNum: filter.sortType === 'byNumber' || undefined, + } satisfies GetResaleStarGifts), + }; + + const result = await invokeRequest(new GramJs.payments.GetResaleStarGifts(params)); + + if (!result) { + return undefined; + } + + return buildApiResaleGifts(result); +} + export async function fetchSavedStarGifts({ peer, offset = '', diff --git a/src/api/types/stars.ts b/src/api/types/stars.ts index 58c0e5c30..3c8f95962 100644 --- a/src/api/types/stars.ts +++ b/src/api/types/stars.ts @@ -1,6 +1,7 @@ import type { ApiWebDocument } from './bots'; import type { ApiChat } from './chats'; import type { ApiFormattedText, ApiSticker, BoughtPaidMedia } from './messages'; +import type { ApiUser } from './users'; export interface ApiStarGiftRegular { type: 'starGift'; @@ -10,6 +11,7 @@ export interface ApiStarGiftRegular { stars: number; availabilityRemains?: number; availabilityTotal?: number; + availabilityResale?: number; starsToConvert: number; isSoldOut?: true; firstSaleDate?: number; @@ -54,6 +56,7 @@ export interface ApiStarGiftAttributePattern { export interface ApiStarGiftAttributeBackdrop { type: 'backdrop'; + backdropId: number; name: string; centerColor: string; edgeColor: string; @@ -95,6 +98,37 @@ export interface ApiSavedStarGift { upgradeMsgId?: number; // Local field, used for Action Message } +export type StarGiftAttributeIdModel = { + type: 'model'; + documentId: string; +}; +export type ApiStarGiftAttributeIdPattern = { + type: 'pattern'; + documentId: string; +}; +export type ApiStarGiftAttributeIdBackdrop = { + type: 'backdrop'; + backdropId: number; +}; +export type ApiStarGiftAttributeId = StarGiftAttributeIdModel | + ApiStarGiftAttributeIdPattern | ApiStarGiftAttributeIdBackdrop; + +export interface ApiStarGiftAttributeCounter { + attribute: T; + count: number; +} + +export interface ApiTypeResaleStarGifts { + count: number; + gifts: ApiStarGift[]; + nextOffset?: string; + attributes?: ApiStarGiftAttribute[]; + attributesHash?: string; + chats: ApiChat[]; + counters?: ApiStarGiftAttributeCounter[]; + users: ApiUser[]; +} + export interface ApiInputSavedStarGiftUser { type: 'user'; messageId: number; diff --git a/src/assets/font-icons/dropdown-arrows.svg b/src/assets/font-icons/dropdown-arrows.svg new file mode 100644 index 000000000..f666d90cd --- /dev/null +++ b/src/assets/font-icons/dropdown-arrows.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/font-icons/sort-by-date.svg b/src/assets/font-icons/sort-by-date.svg new file mode 100644 index 000000000..efa84e2cc --- /dev/null +++ b/src/assets/font-icons/sort-by-date.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/font-icons/sort-by-number.svg b/src/assets/font-icons/sort-by-number.svg new file mode 100644 index 000000000..c578de76a --- /dev/null +++ b/src/assets/font-icons/sort-by-number.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/font-icons/sort-by-price.svg b/src/assets/font-icons/sort-by-price.svg new file mode 100644 index 000000000..3c4358a81 --- /dev/null +++ b/src/assets/font-icons/sort-by-price.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/localization/fallback.strings b/src/assets/localization/fallback.strings index 86e143b00..6581ca48e 100644 --- a/src/assets/localization/fallback.strings +++ b/src/assets/localization/fallback.strings @@ -1977,5 +1977,25 @@ "StarGiftSaleTransaction" = "Gift Purchase"; "StarGiftPurchaseTransaction" = "Gift Sale"; "GiftBuyConfirmDescription" = "Do you want to buy **{gift}** for **{stars}**?"; +"GiftBuyForPeerConfirmDescription" = "Do you want to buy **{gift}** for **{stars}** and gift it to **{peer}**?"; "ComposerTitleForwardFrom" = "From: **{users}**"; "ContextMenuItemMention" = "Mention"; +"GiftRibbonResale" = "resale"; +"GiftCategoryResale" = "Resale"; +"HeaderDescriptionResaleGifts_one" = "{count} for resale"; +"HeaderDescriptionResaleGifts_other" = "{count} for resale"; +"GiftSortByPrice" = "Sort by Price"; +"GiftSortByNumber" = "Sort by Number"; +"ContextMenuItemSelectAll" = "Select All"; +"ButtonSort" = "Sort"; +"GiftAttributeModelPlural_one" = "{count} Model"; +"GiftAttributeModelPlural_other" = "{count} Models"; +"GiftAttributeBackdropPlural_one" = "{count} Backdrop"; +"GiftAttributeBackdropPlural_other" = "{count} Backdrops"; +"GiftAttributeSymbolPlural_one" = "{count} Symbol"; +"GiftAttributeSymbolPlural_other" = "{count} Symbols"; +"ValueGiftSortByDate" = "Date"; +"ValueGiftSortByPrice" = "Price"; +"ValueGiftSortByNumber" = "Number"; +"ResellGiftsNoFound" = "No gifts found"; +"ResellGiftsClearFilters" = "Clear Filters"; \ No newline at end of file diff --git a/src/components/common/gift/GiftRibbon.tsx b/src/components/common/gift/GiftRibbon.tsx index a5143ffc5..c57566e51 100644 --- a/src/components/common/gift/GiftRibbon.tsx +++ b/src/components/common/gift/GiftRibbon.tsx @@ -19,9 +19,10 @@ const COLORS = { type ColorKey = keyof typeof COLORS; const COLOR_KEYS = new Set(Object.keys(COLORS) as ColorKey[]); +type GradientColor = readonly [string, string]; type OwnProps = { - color: ColorKey | (string & {}); + color: ColorKey | GradientColor | (string & {}); text: string; className?: string; }; @@ -40,7 +41,13 @@ const GiftRibbon = ({ const isDarkTheme = theme === 'dark'; - const gradientColor = colorKey ? COLORS[colorKey][isDarkTheme ? 1 : 0] : undefined; + const gradientColor: GradientColor | undefined + = Array.isArray(color) + ? color as GradientColor + : colorKey + ? COLORS[colorKey][isDarkTheme ? 1 : 0] + : undefined; + const startColor = gradientColor ? gradientColor[0] : color; const endColor = gradientColor ? gradientColor[1] : color; diff --git a/src/components/modals/gift/GiftComposer.tsx b/src/components/modals/gift/GiftComposer.tsx index 3d313775e..4e06c3caf 100644 --- a/src/components/modals/gift/GiftComposer.tsx +++ b/src/components/modals/gift/GiftComposer.tsx @@ -94,13 +94,14 @@ function GiftComposer({ } }, [shouldDisallowLimitedStarGifts, shouldPayForUpgrade]); - const isStarGift = 'id' in gift; + const isStarGift = 'id' in gift && gift.type === 'starGift'; + const isPremiumGift = 'months' in gift; const hasPremiumByStars = giftByStars && 'amount' in giftByStars; const isPeerUser = peer && isApiPeerUser(peer); const isSelf = peerId === currentUserId; const localMessage = useMemo(() => { - if (!isStarGift) { + if (isPremiumGift) { const currentGift = shouldPayByStars && hasPremiumByStars ? giftByStars : gift; return { id: -1, @@ -121,32 +122,35 @@ function GiftComposer({ } satisfies ApiMessage; } - return { - id: -1, - chatId: '0', - isOutgoing: false, - senderId: currentUserId, - date: Math.floor(Date.now() / 1000), - content: { - action: { - mediaType: 'action', - type: 'starGift', - message: giftMessage?.length ? { - text: giftMessage, - } : undefined, - isNameHidden: shouldHideName || undefined, - starsToConvert: gift.starsToConvert, - canUpgrade: shouldPayForUpgrade || undefined, - alreadyPaidUpgradeStars: shouldPayForUpgrade ? gift.upgradeStars : undefined, - gift, - peerId, - fromId: currentUserId, + if (isStarGift) { + return { + id: -1, + chatId: '0', + isOutgoing: false, + senderId: currentUserId, + date: Math.floor(Date.now() / 1000), + content: { + action: { + mediaType: 'action', + type: 'starGift', + message: giftMessage?.length ? { + text: giftMessage, + } : undefined, + isNameHidden: shouldHideName || undefined, + starsToConvert: gift.starsToConvert, + canUpgrade: shouldPayForUpgrade || undefined, + alreadyPaidUpgradeStars: shouldPayForUpgrade ? gift.upgradeStars : undefined, + gift, + peerId, + fromId: currentUserId, + }, }, - }, - } satisfies ApiMessage; + } satisfies ApiMessage; + } + return undefined; }, [currentUserId, gift, giftMessage, isStarGift, shouldHideName, shouldPayForUpgrade, peerId, - shouldPayByStars, hasPremiumByStars, giftByStars]); + shouldPayByStars, hasPremiumByStars, giftByStars, isPremiumGift]); const handleGiftMessageChange = useLastCallback((e: ChangeEvent) => { setGiftMessage(e.target.value); @@ -198,14 +202,16 @@ function GiftComposer({ return; } - openInvoice({ - type: 'giftcode', - userIds: [peerId], - currency: gift.currency, - amount: gift.amount, - option: gift, - message: giftMessage ? { text: giftMessage } : undefined, - }); + if (isPremiumGift) { + openInvoice({ + type: 'giftcode', + userIds: [peerId], + currency: gift.currency, + amount: gift.amount, + option: gift, + message: giftMessage ? { text: giftMessage } : undefined, + }); + } }); const canUseStarsPayment = hasPremiumByStars && starBalance && (starBalance.amount > giftByStars.amount); @@ -320,7 +326,7 @@ function GiftComposer({ ? formatStarsAsIcon(lang, giftByStars.amount, { asFont: true }) : isStarGift ? formatStarsAsIcon(lang, gift.stars + (shouldPayForUpgrade ? gift.upgradeStars! : 0), { asFont: true }) - : formatCurrency(lang, gift.amount, gift.currency); + : isPremiumGift ? formatCurrency(lang, gift.amount, gift.currency) : undefined; return (
@@ -359,6 +365,8 @@ function GiftComposer({ customBackground && isBackgroundBlurred && styles.blurred, ); + if ((!isStarGift && !isPremiumGift) || !localMessage) return; + return (
void; + onClick: (gift: ApiStarGift, target: 'original' | 'resell') => void; + isResale?: boolean; }; const GIFT_STICKER_SIZE = 90; -function GiftItemStar({ gift, observeIntersection, onClick }: OwnProps) { +function GiftItemStar({ + gift, observeIntersection, onClick, isResale, +}: OwnProps) { const { openGiftInfoModal } = getActions(); const ref = useRef(); + const stickerRef = useRef(); const lang = useLang(); - const [shouldPlay, play] = useFlag(); + const [isVisible, setIsVisible] = useState(false); - const { - stars, - isLimited, - isSoldOut, - sticker, - } = gift; + const sticker = getStickerFromGift(gift); + const isGiftUnique = gift.type === 'starGiftUnique'; + const uniqueGift = isGiftUnique ? gift : undefined; + const regularGift = !isGiftUnique ? gift : undefined; + + const stars = !isGiftUnique ? regularGift?.stars : uniqueGift?.resellPriceInStars; + const resellMinStars = regularGift?.resellMinStars; + const priceInStarsAsString = !isGiftUnique && isResale && resellMinStars + ? lang.number(resellMinStars) + '+' : stars; + const isLimited = !isGiftUnique && Boolean(regularGift?.isLimited); + const isSoldOut = !isGiftUnique && Boolean(regularGift?.isSoldOut); const handleGiftClick = useLastCallback(() => { - if (isSoldOut) { + if (isSoldOut && !isResale) { openGiftInfoModal({ gift }); return; } - onClick(gift); + onClick(gift, isResale ? 'resell' : 'original'); }); + const radialPatternBackdrop = useMemo(() => { + const { backdrop, pattern } = getGiftAttributes(gift) || {}; + + if (!backdrop || !pattern) { + return undefined; + } + + const backdropColors = [backdrop.centerColor, backdrop.edgeColor]; + const patternColor = backdrop.patternColor; + + return ( + + ); + }, [gift]); + + const giftNumber = isGiftUnique ? gift.number : 0; + + const giftRibbon = useMemo(() => { + if (isGiftUnique) { + const { backdrop } = getGiftAttributes(gift) || {}; + if (!backdrop) { + return undefined; + } + return ( + + ); + } + if (isResale) { + return ; + } + if (isSoldOut) { + return ; + } + if (isLimited) { + return ; + } + return undefined; + }, [isGiftUnique, isResale, gift, isSoldOut, isLimited, lang, giftNumber]); + useOnIntersect(ref, observeIntersection, (entry) => { - if (entry.isIntersecting) play(); + const visible = entry.isIntersecting; + setIsVisible(visible); }); return (
- + {sticker && ( + + )} + +
+ - {isLimited && !isSoldOut && } - {isSoldOut && } + {giftRibbon}
); } diff --git a/src/components/modals/gift/GiftModal.module.scss b/src/components/modals/gift/GiftModal.module.scss index def4ff5be..e8d6ffbdc 100644 --- a/src/components/modals/gift/GiftModal.module.scss +++ b/src/components/modals/gift/GiftModal.module.scss @@ -9,17 +9,37 @@ background-color: var(--color-background); :global(html.theme-dark) & { - background-color: #181818; + --color-background: #181818; } } .root :global(.modal-dialog), .transition, .content { - height: min(92vh, 45rem); + height: min(92vh, 49rem); max-height: none !important; } +@media (max-width: 600px) { + .root :global(.modal-dialog), + .transition, + .content { + height: 100%; + } +} + +@media (max-width: 600px) { + .root :global(.modal-dialog) { + width: 100%; + max-width: 100% !important; + height: 100%; + border: none !important; + border-radius: 0; + + box-shadow: none !important; + } +} + .root :global(.modal-dialog), .root :global(.modal-content), .transition { @@ -31,13 +51,22 @@ flex-direction: column; } +.resaleScreenRoot, .main { overflow-y: scroll; - height: 100%; - padding-bottom: 1rem; - padding-inline: 1rem; + padding-bottom: 0.5rem; + padding-inline: 0.5rem; - @include mixins.adapt-padding-to-scrollbar(1rem); + @include mixins.adapt-padding-to-scrollbar(0.5rem); +} + +.resaleScreenRoot { + height: calc(100% - 6.25rem); + margin-top: 6.25rem; +} + +.main { + height: 100%; } .giftSection { @@ -48,6 +77,7 @@ padding: 0.5rem; } +.resaleStarGiftsContainer, .starGiftsContainer, .premiumGiftsGallery { display: flex; @@ -58,6 +88,7 @@ margin-bottom: 0.75rem; } +.resaleStarGiftsContainer, .starGiftsContainer { display: grid; grid-template-columns: repeat(3, 1fr); @@ -67,6 +98,10 @@ padding-top: 0.75rem; } +.resaleStarGiftsContainer { + padding-bottom: 0.625rem; +} + .header { position: absolute; z-index: 2; @@ -83,8 +118,19 @@ border-bottom: 0.0625rem solid var(--color-borders); background: var(--color-background); + /* stylelint-disable-next-line plugin/no-low-performance-animation-properties */ + transition: height 0.25s ease-out, transform 0.25s ease-out; +} - transition: 0.25s ease-out transform; +.resaleHeader { + overflow: visible; + height: 6.25rem; +} + +.resaleHeaderContentContainer { + align-items: center; + justify-items: center; + width: 100%; } .headerSlide { @@ -102,11 +148,27 @@ transform: translateY(-100%); } +.resaleHeaderText, .commonHeaderText { unicode-bidi: plaintext; + margin: 0 0 0 4.5rem; + font-size: 1.25rem; font-weight: var(--font-weight-medium); + line-height: 1.25rem; +} + +.resaleHeaderText { + margin: 0; + margin-bottom: 0.25rem !important; +} + +.resaleHeaderDescription { + unicode-bidi: plaintext; + font-size: 0.875rem; + line-height: 1.25rem; + color: var(--color-text-secondary); } .closeButton { @@ -186,3 +248,36 @@ height: auto; min-height: calc(100% - 3.5rem); } + +.notFoundGiftsRoot { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + + padding-top: 5rem; +} + +.notFoundGiftsDescription { + unicode-bidi: plaintext; + + margin-block: 1rem; + + font-size: 1rem; + font-weight: var(--font-weight-medium); + color: var(--color-text-secondary); + text-align: center; +} + +.notFoundGiftsLink { + font-weight: var(--font-weight-medium); + color: var(--color-links); + transition: opacity 0.15s ease-in; + + &:active, + &:hover { + color: var(--color-links); + text-decoration: none; + opacity: 0.85; + } +} diff --git a/src/components/modals/gift/GiftModal.tsx b/src/components/modals/gift/GiftModal.tsx index 0bf4f4295..1bce32869 100644 --- a/src/components/modals/gift/GiftModal.tsx +++ b/src/components/modals/gift/GiftModal.tsx @@ -8,6 +8,7 @@ import type { ApiDisallowedGifts, ApiPeer, ApiPremiumGiftCodeOption, + ApiStarGift, ApiStarGiftRegular, ApiStarsAmount, } from '../../../api/types'; @@ -17,6 +18,7 @@ import type { StarGiftCategory } from '../../../types'; import { STARS_CURRENCY_CODE } from '../../../config'; import { getUserFullName } from '../../../global/helpers'; import { getPeerTitle, isApiPeerChat, isApiPeerUser } from '../../../global/helpers/peers'; +import { selectTabState } from '../../../global/selectors'; import { selectPeer, selectUserFullInfo } from '../../../global/selectors'; import buildClassName from '../../../util/buildClassName'; import { throttle } from '../../../util/schedulers'; @@ -36,6 +38,8 @@ import BalanceBlock from '../stars/BalanceBlock'; import GiftSendingOptions from './GiftComposer'; import GiftItemPremium from './GiftItemPremium'; import GiftItemStar from './GiftItemStar'; +import GiftModalResaleScreen from './GiftModalResaleScreen'; +import GiftResaleFilters from './GiftResaleFilters'; import StarGiftCategoryList from './StarGiftCategoryList'; import styles from './GiftModal.module.scss'; @@ -46,7 +50,7 @@ export type OwnProps = { modal: TabState['giftModal']; }; -export type GiftOption = ApiPremiumGiftCodeOption | ApiStarGiftRegular; +export type GiftOption = ApiPremiumGiftCodeOption | ApiStarGift; type StateProps = { boostPerSentGift?: number; @@ -56,6 +60,8 @@ type StateProps = { peer?: ApiPeer; isSelf?: boolean; disallowedGifts?: ApiDisallowedGifts; + resaleGiftsCount?: number; + areResaleGiftsLoading?: boolean; }; const AVATAR_SIZE = 100; @@ -72,9 +78,11 @@ const GiftModal: FC = ({ peer, isSelf, disallowedGifts, + resaleGiftsCount, + areResaleGiftsLoading, }) => { const { - closeGiftModal, + closeGiftModal, openGiftInfoModal, resetResaleGifts, loadResaleGifts, } = getActions(); const dialogRef = useRef(); const transitionRef = useRef(); @@ -89,6 +97,7 @@ const GiftModal: FC = ({ const chat = peer && isApiPeerChat(peer) ? peer : undefined; const [selectedGift, setSelectedGift] = useState(); + const [selectedResellGift, setSelectedResellGift] = useState(); const [shouldShowMainScreenHeader, setShouldShowMainScreenHeader] = useState(false); const [isMainScreenHeaderForStarGifts, setIsMainScreenHeaderForStarGifts] = useState(false); const [isGiftScreenHeaderForStarGifts, setIsGiftScreenHeaderForStarGifts] = useState(false); @@ -143,14 +152,22 @@ const GiftModal: FC = ({ observe: observeIntersection, } = useIntersectionObserver({ rootRef: scrollerRef, throttleMs: INTERSECTION_THROTTLE, isDisabled: !isOpen }); + const isResaleScreen = Boolean(selectedResellGift) && !selectedGift; const isGiftScreen = Boolean(selectedGift); - const shouldShowHeader = isGiftScreen || shouldShowMainScreenHeader; + const shouldShowHeader = isResaleScreen || isGiftScreen || shouldShowMainScreenHeader; const isHeaderForStarGifts = isGiftScreen ? isGiftScreenHeaderForStarGifts : isMainScreenHeaderForStarGifts; + useEffect(() => { + if (selectedResellGift) { + loadResaleGifts({ giftId: selectedResellGift.id }); + } + }, [selectedResellGift]); + useEffect(() => { if (!isOpen) { setShouldShowMainScreenHeader(false); setSelectedGift(undefined); + setSelectedResellGift(undefined); setSelectedCategory('all'); } }, [isOpen]); @@ -228,7 +245,18 @@ const GiftModal: FC = ({ ); } - const handleGiftClick = useLastCallback((gift: GiftOption) => { + const handleGiftClick = useLastCallback((gift: GiftOption, target?: 'resell' | 'original') => { + if (target === 'resell') { + if (!('id' in gift)) { + return; + } + if (isResaleScreen) { + openGiftInfoModal({ gift, recipientId: renderingModal?.forPeerId }); + return; + } + setSelectedResellGift(gift); + return; + } setSelectedGift(gift); setIsGiftScreenHeaderForStarGifts('id' in gift); }); @@ -254,16 +282,34 @@ const GiftModal: FC = ({ return (
- {starGiftsById && filteredGiftIds?.map((giftId) => { + {starGiftsById && filteredGiftIds?.flatMap((giftId) => { const gift = starGiftsById[giftId]; - return ( + const shouldShowResale = selectedCategory !== 'stock' && Boolean(gift.availabilityResale); + const shouldDuplicateAsResale = selectedCategory !== 'resale' && shouldShowResale && !gift.isSoldOut; + + const elements = [ - ); + />, + ]; + + if (shouldDuplicateAsResale) { + elements.push( + , + ); + } + + return elements; })}
); @@ -290,12 +336,24 @@ const GiftModal: FC = ({ setSelectedCategory(category); }); + const handleCloseModal = useLastCallback(() => { + setSelectedGift(undefined); + setSelectedResellGift(undefined); + resetResaleGifts(); + closeGiftModal(); + }); + const handleCloseButtonClick = useLastCallback(() => { + if (isResaleScreen) { + setSelectedResellGift(undefined); + resetResaleGifts(); + return; + } if (isGiftScreen) { setSelectedGift(undefined); return; } - closeGiftModal(); + handleCloseModal(); }); function renderMainScreen() { @@ -337,17 +395,51 @@ const GiftModal: FC = ({ ); } - const isBackButton = isGiftScreen; + const isBackButton = isGiftScreen || isResaleScreen; const buttonClassName = buildClassName( 'animated-close-icon', isBackButton && 'state-back', ); + function renderHeader() { + if (!shouldShowHeader) return undefined; + if (isResaleScreen) { + const isFirstLoading = areResaleGiftsLoading && !resaleGiftsCount; + return ( +
+

+ {selectedResellGift.title} +

+ {isFirstLoading + && ( +
+ {lang('Loading')} +
+ )} + {!isFirstLoading && resaleGiftsCount !== undefined + && ( +
+ {lang('HeaderDescriptionResaleGifts', { + count: resaleGiftsCount, + }, { withNodes: true, withMarkdown: true, pluralValue: resaleGiftsCount })} +
+ )} + +
+ ); + } + return ( +

+ {lang(isHeaderForStarGifts ? (isSelf ? 'StarsGiftHeaderSelf' : 'StarsGiftHeader') : 'GiftPremiumHeader')} +

+ ); + } + return ( = ({
-
+
-

- {lang(isHeaderForStarGifts ? (isSelf ? 'StarsGiftHeaderSelf' : 'StarsGiftHeader') : 'GiftPremiumHeader')} -

+ {renderHeader()}
- {!isGiftScreen && renderMainScreen()} + {!isGiftScreen && !isResaleScreen && renderMainScreen()} + {isResaleScreen && selectedResellGift + && ( + + )} {isGiftScreen && renderingModal?.forPeerId && ( ((global, { modal }): StateProps => { const isSelf = Boolean(currentUserId && modal?.forPeerId === currentUserId); const userFullInfo = peer ? selectUserFullInfo(global, peer?.id) : undefined; + const { resaleGifts } = selectTabState(global); + const resaleGiftsCount = resaleGifts.count; + const areResaleGiftsLoading = resaleGifts.isLoading !== false; + return { boostPerSentGift: global.appConfig?.boostsPerSentGift, starGiftsById: starGifts?.byId, @@ -414,12 +518,15 @@ export default memo(withGlobal((global, { modal }): StateProps => { peer, isSelf, disallowedGifts: userFullInfo?.disallowedGifts, + resaleGiftsCount, + areResaleGiftsLoading, }; })(GiftModal)); function getCategoryKey(category: StarGiftCategory) { - if (category === 'all') return -2; - if (category === 'limited') return -1; - if (category === 'stock') return 0; - return category; + if (category === 'all') return 0; + if (category === 'limited') return 1; + if (category === 'resale') return 2; + if (category === 'stock') return 3; + return category + 3; } diff --git a/src/components/modals/gift/GiftModalResaleScreen.tsx b/src/components/modals/gift/GiftModalResaleScreen.tsx new file mode 100644 index 000000000..93b7893c2 --- /dev/null +++ b/src/components/modals/gift/GiftModalResaleScreen.tsx @@ -0,0 +1,171 @@ +import type { FC } from '../../../lib/teact/teact'; +import React, { + memo, + useMemo, + useRef } from '../../../lib/teact/teact'; +import { getActions, withGlobal } from '../../../global'; + +import type { + ApiStarGift, +} from '../../../api/types'; +import type { ResaleGiftsFilterOptions } from '../../../types'; + +import { RESALE_GIFTS_LIMIT } from '../../../config'; +import { selectTabState, +} from '../../../global/selectors'; +import buildClassName from '../../../util/buildClassName'; +import { LOCAL_TGS_URLS } from '../../common/helpers/animatedAssets'; + +import useInfiniteScroll from '../../../hooks/useInfiniteScroll'; +import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver'; +import useLang from '../../../hooks/useLang'; +import useLastCallback from '../../../hooks/useLastCallback'; + +import AnimatedIconWithPreview from '../../common/AnimatedIconWithPreview'; +import InfiniteScroll from '../../ui/InfiniteScroll'; +import Link from '../../ui/Link'; +import Transition from '../../ui/Transition'; +import GiftItemStar from './GiftItemStar'; + +import styles from './GiftModal.module.scss'; + +export type OwnProps = { + onGiftClick: (gift: ApiStarGift) => void; +}; + +type StateProps = { + gift?: ApiStarGift; + resellGifts?: ApiStarGift[]; + filter: ResaleGiftsFilterOptions; + areGiftsAllLoaded?: boolean; + areGiftsLoading?: boolean; + updateIteration: number; +}; + +const INTERSECTION_THROTTLE = 200; + +const GiftModalResaleScreen: FC = ({ + resellGifts, + gift, + filter, + areGiftsAllLoaded, + areGiftsLoading, + updateIteration, + onGiftClick, +}) => { + const { + loadResaleGifts, + updateResaleGiftsFilter, + } = getActions(); + const scrollerRef = useRef(); + + const lang = useLang(); + const resellGiftsIds = useMemo(() => { + return resellGifts?.map((g) => g.id); + }, [resellGifts]); + + const hasFilter = Boolean(filter?.modelAttributes?.length + || filter?.patternAttributes?.length || filter?.backdropAttributes?.length); + + const handleLoadMoreResellGifts = useLastCallback(() => { + if (gift) { + loadResaleGifts({ giftId: gift.id }); + } + }); + + const isGiftsEmpty = Boolean(!resellGifts || resellGifts.length === 0); + + const [viewportIds, onLoadMore] = useInfiniteScroll( + handleLoadMoreResellGifts, + resellGiftsIds, + !gift, + RESALE_GIFTS_LIMIT, + ); + + const { observe } = useIntersectionObserver({ rootRef: scrollerRef, throttleMs: INTERSECTION_THROTTLE }); + + const handleResetGiftsFilter = useLastCallback(() => { + updateResaleGiftsFilter({ filter: { + ...filter, + modelAttributes: [], + backdropAttributes: [], + patternAttributes: [], + } }); + }); + + function renderNothingFoundGiftsWithFilter() { + return ( +
+ +
+ {lang('ResellGiftsNoFound')} +
+ {hasFilter && ( + + {lang('ResellGiftsClearFilters')} + + )} +
+ ); + } + + return ( +
+ + {isGiftsEmpty && areGiftsAllLoaded && renderNothingFoundGiftsWithFilter()} + + {resellGifts?.map((gift) => ( + + ))} + + +
+ ); +}; + +export default memo(withGlobal((global): StateProps => { + const { + starGifts, + } = global; + + const { resaleGifts } = selectTabState(global); + const gift = resaleGifts?.giftId ? starGifts?.byId[resaleGifts.giftId] : undefined; + const filter = resaleGifts.filter; + const areGiftsAllLoaded = resaleGifts.isAllLoaded; + const areGiftsLoading = resaleGifts.isLoading; + const updateIteration = resaleGifts.updateIteration; + + return { + resellGifts: resaleGifts.gifts, + gift, + filter, + areGiftsAllLoaded, + areGiftsLoading, + updateIteration, + }; +})(GiftModalResaleScreen)); diff --git a/src/components/modals/gift/GiftResaleFilters.module.scss b/src/components/modals/gift/GiftResaleFilters.module.scss new file mode 100644 index 000000000..12233393e --- /dev/null +++ b/src/components/modals/gift/GiftResaleFilters.module.scss @@ -0,0 +1,160 @@ +@use '../../../styles/mixins'; + +.root { + position: relative; + display: flex; + width: 100%; + margin-top: 0.5rem; +} + +.buttonsContainer { + scrollbar-color: rgba(0, 0, 0, 0); + scrollbar-width: none; + + overflow-x: auto; + overflow-y: hidden; + display: flex; + align-items: center; + + height: 100%; + padding-right: 0.5rem; + padding-left: 0.5rem; + + white-space: nowrap; + + @include mixins.gradient-border-horizontal(0.5rem, 0.5rem); + + &::-webkit-scrollbar { + height: 0; + } + + &::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0); + } +} + +.itemIcon { + margin-inline-start: 0.25rem; +} + +.sticker { + margin-inline-start: 0.375rem; +} + +.backdropAttributeMenuItemText, +.menuItemStickerText, +.menuItemText { + flex-grow: 1; +} + +.menuItemStickerText { + margin-inline-start: 1.125rem; +} + +.backdropAttributeMenuItemText { + margin-inline-start: 3rem; +} + +.backdrop { + position: absolute; + left: 0.625rem; + + width: 1.5rem; + height: 1.5rem; + border-radius: 50%; +} + +.menuItemIcon { + margin-inline: 0 !important; + margin-inline-start: 0.5 !important; +} + +.item { + display: flex; + align-items: center; + justify-content: center; + + width: auto; + margin-inline: 0.25rem; + padding: 0.125rem 0.75rem; + border-radius: 1rem; + + font-size: 0.875rem; + font-weight: var(--font-weight-semibold); + color: var(--color-text-secondary); + white-space: nowrap; + + background-color: var(--color-background-secondary); + + transition: 0.15s background-color; + + &:hover { + cursor: pointer; + background-color: var(--color-background-secondary-accent); + } +} + +.menuContentContainer { + overflow-y: scroll; + max-height: 20rem; +} + +:global(.MenuItem) { + :global(.icon) { + color: var(--color-text); + } +} + +.menu { + :global(.bubble) { + top: 2.25rem !important; + } + + &.left { + :global(.bubble) { + right: auto !important; + left: 0.125rem !important; + } + } + &.right { + :global(.bubble) { + right: 0.125rem !important; + left: auto !important; + } + } + + :global(.SearchInput) { + --color-placeholders: var(--color-text-secondary); + + width: 15rem; + border: none; + border-bottom: 0.0625rem solid var(--color-borders); + border-radius: 0; + + background-color: transparent; + + :global(.form-control) { + caret-color: var(--color-icon-secondary); + } + + :global(.icon) { + color: var(--color-icon-secondary); + } + + input { + padding-left: 1.25rem; + font-size: 0.875rem; + font-weight: var(--font-weight-medium); + } + + :global(.icon-container-left) { + width: 1.25rem; + margin-inline-start: 1rem; + } + } + + :global(.icon) { + font-size: 1.25rem !important; + color: var(--color-text); + } +} diff --git a/src/components/modals/gift/GiftResaleFilters.tsx b/src/components/modals/gift/GiftResaleFilters.tsx new file mode 100644 index 000000000..f3986ca6e --- /dev/null +++ b/src/components/modals/gift/GiftResaleFilters.tsx @@ -0,0 +1,655 @@ +import { type MouseEvent as ReactMouseEvent } from 'react'; +import type { ElementRef, FC } from '../../../lib/teact/teact'; +import React, { + memo, + useCallback, + useMemo, + useRef, + useState } from '../../../lib/teact/teact'; +import { getActions, withGlobal } from '../../../global'; + +import type { + ApiStarGiftAttribute, + ApiStarGiftAttributeBackdrop, + ApiStarGiftAttributeCounter, + ApiStarGiftAttributeIdBackdrop, + ApiStarGiftAttributeIdPattern, + ApiStarGiftAttributeModel, + ApiStarGiftAttributePattern, + StarGiftAttributeIdModel, +} from '../../../api/types'; +import type { ResaleGiftsFilterOptions, ResaleGiftsSortType } from '../../../types'; + +import { selectTabState, +} from '../../../global/selectors'; +import buildClassName from '../../../util/buildClassName'; + +import useContextMenuHandlers from '../../../hooks/useContextMenuHandlers'; +import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver'; +import useLang from '../../../hooks/useLang'; +import useLastCallback from '../../../hooks/useLastCallback'; + +import Icon from '../../common/icons/Icon'; +import RadialPatternBackground from '../../common/profile/RadialPatternBackground'; +import Menu from '../../ui/Menu'; +import MenuItem from '../../ui/MenuItem'; +import SearchInput from '../../ui/SearchInput'; +import ResaleGiftMenuAttributeSticker from './ResaleGiftMenuAttributeSticker'; + +import styles from './GiftResaleFilters.module.scss'; + +type OwnProps = { + dialogRef: ElementRef; +}; +type StateProps = { + filter: ResaleGiftsFilterOptions; + attributes?: ApiStarGiftAttribute[]; + counters?: ApiStarGiftAttributeCounter[]; +}; + +const GiftResaleFilters: FC = ({ + attributes, + counters, + filter, + dialogRef, +}) => { + const lang = useLang(); + const { + updateResaleGiftsFilter, + } = getActions(); + + const [searchModelQuery, setSearchModelQuery] = useState(''); + const [searchBackdropQuery, setSearchBackdropQuery] = useState(''); + const [searchPatternQuery, setSearchPatternQuery] = useState(''); + const filteredAttributes = useMemo(() => { + const map: { + model: ApiStarGiftAttributeModel[]; + pattern: ApiStarGiftAttributePattern[]; + backdrop: ApiStarGiftAttributeBackdrop[]; + } = { + model: [], + pattern: [], + backdrop: [], + }; + + for (const counter of counters ?? []) { + const { attribute } = counter; + + if (!counter.count) { + continue; + } + + const found = attributes?.find((attr) => { + if (attr.type === 'backdrop' && attribute.type === 'backdrop') { + return attr.backdropId === attribute.backdropId; + } + + if (attr.type === 'model' && attribute.type === 'model') { + return attr.sticker.id === attribute.documentId; + } + + if (attr.type === 'pattern' && attribute.type === 'pattern') { + return attr.sticker.id === attribute.documentId; + } + + return false; + }); + + if (found?.type === 'backdrop') { + map.backdrop.push(found); + } + if (found?.type === 'model') { + map.model.push(found); + } + if (found?.type === 'pattern') { + map.pattern.push(found); + } + } + + return map; + }, [attributes, counters]); + + const filteredAndSearchedAttributes = useMemo(() => { + const filterBySearch = (items: T[], query: string): T[] => { + if (!query.trim()) return items; + + return items.filter( + (item): item is T => Boolean(item.name?.toLowerCase().includes(query.toLowerCase())), + ); + }; + + return { + model: filterBySearch(filteredAttributes.model, searchModelQuery), + pattern: filterBySearch(filteredAttributes.pattern, searchPatternQuery), + backdrop: filterBySearch(filteredAttributes.backdrop, searchBackdropQuery), + }; + }, [filteredAttributes, searchModelQuery, searchBackdropQuery, searchPatternQuery]); + + // Sort Menu + const sortMenuRef = useRef(); + const { + isContextMenuOpen: isSortContextMenuOpen, + contextMenuAnchor: sortContextMenuAnchor, + handleContextMenu: handleSortContextMenu, + handleContextMenuClose: handleSortContextMenuClose, + handleContextMenuHide: handleSortContextMenuHide, + } = useContextMenuHandlers(dialogRef); + const getSortMenuElement = useLastCallback(() => sortMenuRef.current!); + + // Model Menu + const modelMenuRef = useRef(); + const { + isContextMenuOpen: isModelContextMenuOpen, + contextMenuAnchor: modelContextMenuAnchor, + handleContextMenu: handleModelContextMenu, + handleContextMenuClose: handleModelContextMenuClose, + handleContextMenuHide: handleModelContextMenuHide, + } = useContextMenuHandlers(dialogRef); + const getModelMenuElement = useLastCallback( + () => modelMenuRef.current!, + ); + + // Backdrop Menu + const backdropMenuRef = useRef(); + const { + isContextMenuOpen: isBackdropContextMenuOpen, + contextMenuAnchor: backdropContextMenuAnchor, + handleContextMenu: handleBackdropContextMenu, + handleContextMenuClose: handleBackdropContextMenuClose, + handleContextMenuHide: handleBackdropContextMenuHide, + } = useContextMenuHandlers(dialogRef); + const getBackdropMenuElement = useLastCallback(() => backdropMenuRef.current!); + + // Pattern Menu + const patternMenuRef = useRef(); + const { + isContextMenuOpen: isPatternContextMenuOpen, + contextMenuAnchor: patternContextMenuAnchor, + handleContextMenu: handlePatternContextMenu, + handleContextMenuClose: handlePatternContextMenuClose, + handleContextMenuHide: handlePatternContextMenuHide, + } = useContextMenuHandlers(dialogRef); + const getPatternMenuElement = useLastCallback(() => patternMenuRef.current!); + + const SortMenuButton: FC<{ onTrigger: (e: ReactMouseEvent) => void; isOpen?: boolean }> + = useMemo(() => { + const sortType = filter.sortType; + return ({ onTrigger, isOpen: isMenuOpen }) => ( +
+ {sortType === 'byDate' && lang('ValueGiftSortByDate')} + {sortType === 'byNumber' && lang('ValueGiftSortByNumber')} + {sortType === 'byPrice' && lang('ValueGiftSortByPrice')} + +
+ ); + }, [lang, filter]); + + const ModelMenuButton: + FC<{ onTrigger: (e: ReactMouseEvent) => void; isOpen?: boolean }> + = useMemo(() => { + const attributesCount = filter?.modelAttributes?.length || 0; + return ({ onTrigger, isOpen: isMenuOpen }) => ( +
+ {attributesCount === 0 && lang('GiftAttributeModel')} + {attributesCount > 0 + && lang('GiftAttributeModelPlural', { count: attributesCount }, { pluralValue: attributesCount })} + +
+ ); + }, [lang, filter]); + const BackdropMenuButton: + FC<{ onTrigger: (e: ReactMouseEvent) => void; isOpen?: boolean }> + = useMemo(() => { + const attributesCount = filter?.backdropAttributes?.length || 0; + return ({ onTrigger, isOpen: isMenuOpen }) => ( +
+ {attributesCount === 0 && lang('GiftAttributeBackdrop')} + {attributesCount > 0 + && lang('GiftAttributeBackdropPlural', { count: attributesCount }, { pluralValue: attributesCount })} + +
+ ); + }, [lang, filter]); + const PatternMenuButton: FC<{ onTrigger: (e: ReactMouseEvent) => void; isOpen?: boolean }> + = useMemo(() => { + const attributesCount = filter?.patternAttributes?.length || 0; + return ({ onTrigger, isOpen: isMenuOpen }) => ( +
+ {attributesCount === 0 && lang('GiftAttributeSymbol')} + {attributesCount > 0 + && lang('GiftAttributeSymbolPlural', { count: attributesCount }, { pluralValue: attributesCount })} + +
+ ); + }, [lang, filter]); + + const handleSortMenuItemClick = useLastCallback((type: ResaleGiftsSortType) => { + updateResaleGiftsFilter({ filter: { + ...filter, + sortType: type, + } }); + }); + + const handleSelectedAllModelsClick = useLastCallback(() => { + updateResaleGiftsFilter({ filter: { + ...filter, + modelAttributes: [], + } }); + }); + const handleSelectedAllPatternsClick = useLastCallback(() => { + updateResaleGiftsFilter({ filter: { + ...filter, + patternAttributes: [], + } }); + }); + const handleSelectedAllBackdropsClick = useLastCallback(() => { + updateResaleGiftsFilter({ filter: { + ...filter, + backdropAttributes: [], + } }); + }); + + const handleModelMenuItemClick = useLastCallback((attribute: ApiStarGiftAttributeModel) => { + if (!counters) return; + const attributes = filter.modelAttributes || []; + const modelAttribute + = counters.find((counter): counter is ApiStarGiftAttributeCounter => + counter.attribute.type === 'model' && counter.attribute.documentId === attribute.sticker.id, + )?.attribute; + + if (!modelAttribute) return; + + const isActive = attributes.some((item) => item.documentId === modelAttribute.documentId); + const updatedAttributes = isActive + ? attributes.filter((item) => item.documentId !== modelAttribute.documentId) + : [...attributes, modelAttribute]; + updateResaleGiftsFilter({ filter: { + ...filter, + modelAttributes: updatedAttributes, + } }); + }); + + const handlePatternMenuItemClick = useLastCallback((attribute: ApiStarGiftAttributePattern) => { + if (!counters) return; + const attributes = filter.patternAttributes || []; + const patternAttribute = counters.find( + (counter): counter is ApiStarGiftAttributeCounter => + counter.attribute.type === 'pattern' && counter.attribute.documentId === attribute.sticker.id, + )?.attribute; + + if (!patternAttribute) return; + + const isActive = attributes.some((item) => item.documentId === patternAttribute.documentId); + const updatedAttributes = isActive + ? attributes.filter((item) => item.documentId !== patternAttribute.documentId) + : [...attributes, patternAttribute]; + updateResaleGiftsFilter({ filter: { + ...filter, + patternAttributes: updatedAttributes, + } }); + }); + + const handleBackdropMenuItemClick = useLastCallback((attribute: ApiStarGiftAttributeBackdrop) => { + if (!counters) return; + const attributes = filter.backdropAttributes || []; + const backdropAttribute = counters.find( + (counter): counter is ApiStarGiftAttributeCounter => + counter.attribute.type === 'backdrop' && counter.attribute.backdropId === attribute.backdropId, + )?.attribute; + + if (!backdropAttribute) return; + + const isActive = attributes.some((item) => item.backdropId === backdropAttribute.backdropId); + const updatedAttributes = isActive + ? attributes.filter((item) => item.backdropId !== backdropAttribute.backdropId) + : [...attributes, backdropAttribute]; + updateResaleGiftsFilter({ filter: { + ...filter, + backdropAttributes: updatedAttributes, + } }); + }); + + function renderSortMenuItems() { + return ( + <> + { handleSortMenuItemClick('byPrice'); }}> +
+ {lang('GiftSortByPrice')} +
+ +
+ { handleSortMenuItemClick('byDate'); }}> +
+ {lang('GiftSortByDate')} +
+ + +
+ { handleSortMenuItemClick('byNumber'); }}> +
+ {lang('GiftSortByNumber')} +
+ +
+ + ); + } + + function renderSortMenu() { + return ( + + {renderSortMenuItems()} + + ); + } + + const handleSearchModelInputReset = useCallback(() => { + setSearchModelQuery(''); + }, []); + const handleSearchBackdropInputReset = useCallback(() => { + setSearchBackdropQuery(''); + }, []); + const handleSearchPatternInputReset = useCallback(() => { + setSearchPatternQuery(''); + }, []); + const handleSearchInputClick = useLastCallback((e: React.MouseEvent) => { + e.stopPropagation(); + e.preventDefault(); + }); + + const modelMenuItemsContainerRef = useRef(); + const { observe } = useIntersectionObserver({ + rootRef: modelMenuItemsContainerRef, + isDisabled: !modelContextMenuAnchor, + }); + + function renderModelMenuItems() { + const models = filteredAndSearchedAttributes.model; + const selectedAttributes = filter.modelAttributes ?? []; + const isSelectedAll = selectedAttributes.length === 0; + return ( +
+ + + {lang('ContextMenuItemSelectAll')} + + {models.map((model) => { + const isSelected = isSelectedAll + || selectedAttributes.some((attr) => attr.documentId === model.sticker.id); + return ( + { + handleModelMenuItemClick(model); + }} + > + +
+ {model.name} +
+ +
+ ); + })} +
+ ); + } + + function renderModelMenu() { + return ( + + {renderModelMenuItems()} + + ); + } + + function renderBackdropMenuItems() { + const backdrops = filteredAndSearchedAttributes.backdrop; + const selectedAttributes = filter.backdropAttributes ?? []; + const isSelectedAll = selectedAttributes.length === 0; + + return ( +
+ + + {lang('ContextMenuItemSelectAll')} + + {backdrops.map((backdrop) => { + const isSelected = isSelectedAll + || selectedAttributes.some((attr) => attr.backdropId === backdrop.backdropId); + + return ( + { + handleBackdropMenuItemClick(backdrop); + }} + > + +
+ {backdrop.name} +
+ +
+ ); + })} +
+ ); + } + + function renderBackdropMenu() { + return ( + + {renderBackdropMenuItems()} + + ); + } + + function renderPatternMenuItems() { + const patterns = filteredAndSearchedAttributes.pattern; + const selectedAttributes = filter.patternAttributes ?? []; + const isSelectedAll = selectedAttributes.length === 0; + + return ( +
+ + + {lang('ContextMenuItemSelectAll')} + + {patterns.map((pattern) => { + const isSelected = isSelectedAll + || selectedAttributes.some((attr) => attr.documentId === pattern.sticker.id); + + return ( + { + handlePatternMenuItemClick(pattern); + }} + > + + + +
+ {pattern.name} +
+ +
+ ); + })} +
+ ); + } + + function renderPatternMenu() { + return ( + + {renderPatternMenuItems()} + + ); + } + + return ( +
+ {Boolean(sortContextMenuAnchor) && renderSortMenu()} + {Boolean(modelContextMenuAnchor) && renderModelMenu()} + {Boolean(backdropContextMenuAnchor) && renderBackdropMenu()} + {Boolean(patternContextMenuAnchor) && renderPatternMenu()} +
+ + + + +
+
+ ); +}; + +export default memo(withGlobal((global): StateProps => { + const { resaleGifts } = selectTabState(global); + + const attributes = resaleGifts.attributes; + const counters = resaleGifts.counters; + const filter = resaleGifts.filter; + + return { + attributes, + counters, + filter, + }; +})(GiftResaleFilters)); diff --git a/src/components/modals/gift/ResaleGiftMenuAttributeSticker.module.scss b/src/components/modals/gift/ResaleGiftMenuAttributeSticker.module.scss new file mode 100644 index 000000000..af02899d6 --- /dev/null +++ b/src/components/modals/gift/ResaleGiftMenuAttributeSticker.module.scss @@ -0,0 +1,7 @@ +.root { + position: relative; +} + +.thumb { + position: absolute; +} diff --git a/src/components/modals/gift/ResaleGiftMenuAttributeSticker.tsx b/src/components/modals/gift/ResaleGiftMenuAttributeSticker.tsx new file mode 100644 index 000000000..aa89bc455 --- /dev/null +++ b/src/components/modals/gift/ResaleGiftMenuAttributeSticker.tsx @@ -0,0 +1,69 @@ +import type { FC } from '../../../lib/teact/teact'; +import React, { memo, useRef } from '../../../lib/teact/teact'; +import { withGlobal } from '../../../global'; + +import type { ApiSticker } from '../../../api/types'; +import type { ThemeKey } from '../../../types'; + +import { selectTheme } from '../../../global/selectors'; +import buildClassName from '../../../util/buildClassName'; +import { REM } from '../../common/helpers/mediaDimensions'; + +import useDynamicColorListener from '../../../hooks/stickers/useDynamicColorListener'; +import { type ObserveFn } from '../../../hooks/useIntersectionObserver'; + +import StickerView from '../../common/StickerView'; + +import styles from './ResaleGiftMenuAttributeSticker.module.scss'; + +type OwnProps = { + className?: string; + type: 'model' | 'pattern'; + sticker: ApiSticker; + observeIntersectionForLoading?: ObserveFn; + observeIntersectionForPlaying?: ObserveFn; +}; + +type StateProps = { + theme: ThemeKey; +}; + +const ATTRIBUTE_STICKER_SIZE = 1.5 * REM; + +const ResaleGiftMenuAttributeSticker: FC = ({ + className, + type, + sticker, + observeIntersectionForLoading, + observeIntersectionForPlaying, + theme, +}) => { + const stickerRef = useRef(); + + const customColor = useDynamicColorListener(stickerRef, undefined, type !== 'pattern'); + + return ( +
+ +
+ ); +}; + +export default memo(withGlobal((global): StateProps => { + return { + theme: selectTheme(global), + }; +})(ResaleGiftMenuAttributeSticker)); diff --git a/src/components/modals/gift/StarGiftCategoryList.tsx b/src/components/modals/gift/StarGiftCategoryList.tsx index 2a1132100..d1e63386a 100644 --- a/src/components/modals/gift/StarGiftCategoryList.tsx +++ b/src/components/modals/gift/StarGiftCategoryList.tsx @@ -37,6 +37,8 @@ const StarGiftCategoryList = ({ .sort((a, b) => a - b), [idsByCategory]); + const hasResale = idsByCategory && idsByCategory['resale'].length > 0; + const [selectedCategory, setSelectedCategory] = useState('all'); function handleItemClick(category: StarGiftCategory) { @@ -50,6 +52,7 @@ const StarGiftCategoryList = ({ if (category === 'all') return lang('AllGiftsCategory'); if (category === 'stock') return lang('StockGiftsCategory'); if (category === 'limited') return lang('LimitedGiftsCategory'); + if (category === 'resale') return lang('GiftCategoryResale'); return category; } @@ -80,6 +83,7 @@ const StarGiftCategoryList = ({
{renderCategoryItem('all')} {!areLimitedStarGiftsDisallowed && renderCategoryItem('limited')} + {!areLimitedStarGiftsDisallowed && hasResale && renderCategoryItem('resale')} {renderCategoryItem('stock')} {starCategories?.map(renderCategoryItem)}
diff --git a/src/components/modals/gift/info/GiftInfoModal.module.scss b/src/components/modals/gift/info/GiftInfoModal.module.scss index dd64b03c6..3e3e65947 100644 --- a/src/components/modals/gift/info/GiftInfoModal.module.scss +++ b/src/components/modals/gift/info/GiftInfoModal.module.scss @@ -53,6 +53,7 @@ font-size: 0.75rem; } +.starAmountIcon, .giftResalePriceStar { margin-inline-start: 0 !important; } @@ -121,10 +122,6 @@ margin-bottom: 0; } -.starAmountIcon { - margin-inline-start: 0 !important; -} - .modalHeader { position: absolute; z-index: 2; diff --git a/src/components/modals/gift/info/GiftInfoModal.tsx b/src/components/modals/gift/info/GiftInfoModal.tsx index 31268ca64..1b5e02f51 100644 --- a/src/components/modals/gift/info/GiftInfoModal.tsx +++ b/src/components/modals/gift/info/GiftInfoModal.tsx @@ -58,6 +58,7 @@ type StateProps = { collectibleEmojiStatuses?: ApiEmojiStatusType[]; tonExplorerUrl?: string; currentUser?: ApiUser; + recipientPeer?: ApiPeer; }; const STICKER_SIZE = 120; @@ -73,6 +74,7 @@ const GiftInfoModal = ({ collectibleEmojiStatuses, tonExplorerUrl, currentUser, + recipientPeer, }: OwnProps & StateProps) => { const { closeGiftInfoModal, @@ -83,6 +85,7 @@ const GiftInfoModal = ({ openGiftUpgradeModal, showNotification, buyStarGift, + closeGiftModal, } = getActions(); const [isConvertConfirmOpen, openConvertConfirm, closeConvertConfirm] = useFlag(); @@ -161,7 +164,7 @@ const GiftInfoModal = ({ }); const handleBuyGift = useLastCallback(() => { - if (!savedGift || gift?.type !== 'starGiftUnique' || !gift.resellPriceInStars) return; + if (gift?.type !== 'starGiftUnique' || !gift.resellPriceInStars) return; setIsConfirmModalOpen(true); }); @@ -170,9 +173,11 @@ const GiftInfoModal = ({ }); const handleConfirmBuyGift = useLastCallback(() => { - if (!savedGift || gift?.type !== 'starGiftUnique' || !gift.resellPriceInStars) return; + const peer = recipientPeer || currentUser; + if (!peer || gift?.type !== 'starGiftUnique' || !gift.resellPriceInStars) return; closeConfirmModal(); - buyStarGift({ slug: gift.slug, stars: gift.resellPriceInStars }); + closeGiftModal(); + buyStarGift({ peerId: peer.id, slug: gift.slug, stars: gift.resellPriceInStars }); }); const giftAttributes = useMemo(() => { @@ -726,18 +731,34 @@ const GiftInfoModal = ({ > -

- {lang('GiftBuyConfirmDescription', { - gift: lang('GiftUnique', { title: uniqueGift.title, number: uniqueGift.number }), - stars: formatStarsAsText(lang, resellPriceInStars), - }, { - withNodes: true, - withMarkdown: true, - })} -

+ {!recipientPeer + && ( +

+ {lang('GiftBuyConfirmDescription', { + gift: lang('GiftUnique', { title: uniqueGift.title, number: uniqueGift.number }), + stars: formatStarsAsText(lang, resellPriceInStars), + }, { + withNodes: true, + withMarkdown: true, + })} +

+ )} + {recipientPeer + && ( +

+ {lang('GiftBuyForPeerConfirmDescription', { + gift: lang('GiftUnique', { title: uniqueGift.title, number: uniqueGift.number }), + stars: formatStarsAsText(lang, resellPriceInStars), + peer: getPeerTitle(lang, recipientPeer), + }, { + withNodes: true, + withMarkdown: true, + })} +

+ )} )} {savedGift && ( @@ -786,6 +807,8 @@ export default memo(withGlobal( const chat = targetPeer && isApiPeerChat(targetPeer) ? targetPeer : undefined; const hasAdminRights = chat && getHasAdminRight(chat, 'postMessages'); const currentUser = selectUser(global, currentUserId!); + const recipientPeer = modal?.recipientId && currentUserId !== modal.recipientId + ? selectPeer(global, modal.recipientId) : undefined; const currentUserEmojiStatus = currentUser?.emojiStatus; const collectibleEmojiStatuses = global.collectibleEmojiStatuses?.statuses; @@ -799,6 +822,7 @@ export default memo(withGlobal( currentUserEmojiStatus, collectibleEmojiStatuses, currentUser, + recipientPeer, }; }, )(GiftInfoModal)); diff --git a/src/components/ui/Button.scss b/src/components/ui/Button.scss index b31f993a6..e749a46ec 100644 --- a/src/components/ui/Button.scss +++ b/src/components/ui/Button.scss @@ -317,6 +317,12 @@ } } + &.bluredStarsBadge { + color: var(--color-white); + background: rgba(0, 0, 0, 0.2) !important; + backdrop-filter: blur(50px); + } + &.smaller { height: 2.75rem; padding: 0.3125rem; diff --git a/src/components/ui/Button.tsx b/src/components/ui/Button.tsx index 3cf375f20..a2e860324 100644 --- a/src/components/ui/Button.tsx +++ b/src/components/ui/Button.tsx @@ -22,7 +22,7 @@ export type OwnProps = { size?: 'default' | 'smaller' | 'tiny'; color?: ( 'primary' | 'secondary' | 'gray' | 'danger' | 'translucent' | 'translucent-white' | 'translucent-black' - | 'translucent-bordered' | 'dark' | 'green' | 'adaptive' | 'stars' + | 'translucent-bordered' | 'dark' | 'green' | 'adaptive' | 'stars' | 'bluredStarsBadge' ); backgroundImage?: string; id?: string; diff --git a/src/components/ui/SearchInput.tsx b/src/components/ui/SearchInput.tsx index a43c49e1d..d984dc4ab 100644 --- a/src/components/ui/SearchInput.tsx +++ b/src/components/ui/SearchInput.tsx @@ -1,3 +1,4 @@ +import type { MouseEvent as ReactMouseEvent } from 'react'; import type { ElementRef, FC } from '../../lib/teact/teact'; import React, { memo, useEffect, useRef, @@ -43,7 +44,7 @@ type OwnProps = { onReset?: NoneToVoidFunction; onFocus?: NoneToVoidFunction; onBlur?: NoneToVoidFunction; - onClick?: NoneToVoidFunction; + onClick?: (e: ReactMouseEvent) => void; onUpClick?: (event: React.MouseEvent) => void; onDownClick?: (event: React.MouseEvent) => void; onSpinnerClick?: NoneToVoidFunction; diff --git a/src/config.ts b/src/config.ts index bf0c67915..fa78bc607 100644 --- a/src/config.ts +++ b/src/config.ts @@ -3,6 +3,7 @@ import type { } from './api/types'; import type { GiftProfileFilterOptions, + ResaleGiftsFilterOptions, } from './types'; export const APP_CODE_NAME = 'A'; @@ -104,6 +105,7 @@ export const GROUP_CALL_PARTICIPANTS_LIMIT = 100; export const STORY_LIST_LIMIT = 100; export const API_GENERAL_ID_LIMIT = 100; export const STATISTICS_PUBLIC_FORWARDS_LIMIT = 50; +export const RESALE_GIFTS_LIMIT = 50; export const STORY_VIEWS_MIN_SEARCH = 15; export const STORY_MIN_REACTIONS_SORT = 10; @@ -465,3 +467,7 @@ export const DEFAULT_GIFT_PROFILE_FILTER_OPTIONS: GiftProfileFilterOptions = { shouldIncludeDisplayed: true, shouldIncludeHidden: true, } as const; + +export const DEFAULT_RESALE_GIFTS_FILTER_OPTIONS: ResaleGiftsFilterOptions = { + sortType: 'byDate', +}; diff --git a/src/global/actions/api/payments.ts b/src/global/actions/api/payments.ts index cf703da0a..f0745100c 100644 --- a/src/global/actions/api/payments.ts +++ b/src/global/actions/api/payments.ts @@ -146,13 +146,13 @@ addActionHandler('sendStarGift', (global, actions, payload): ActionReturnType => addActionHandler('buyStarGift', (global, actions, payload): ActionReturnType => { const { - slug, stars, tabId = getCurrentTabId(), + slug, peerId, stars, tabId = getCurrentTabId(), } = payload; const inputInvoice: ApiInputInvoiceStarGiftResale = { type: 'stargiftResale', slug, - peerId: global.currentUserId!, + peerId, }; payInputStarInvoice(global, inputInvoice, stars, tabId); diff --git a/src/global/actions/api/stars.ts b/src/global/actions/api/stars.ts index 8adec6458..021b381d6 100644 --- a/src/global/actions/api/stars.ts +++ b/src/global/actions/api/stars.ts @@ -2,6 +2,7 @@ import type { ApiSavedStarGift, ApiStarGiftUnique } from '../../../api/types'; import type { StarGiftCategory } from '../../../types'; import type { ActionReturnType } from '../../types'; +import { DEFAULT_RESALE_GIFTS_FILTER_OPTIONS, RESALE_GIFTS_LIMIT } from '../../../config'; import { getCurrentTabId } from '../../../util/establishMultitabRole'; import { buildCollectionByKey } from '../../../util/iteratees'; import { callApi } from '../../../api/gramjs'; @@ -11,8 +12,10 @@ import { appendStarsSubscriptions, appendStarsTransactions, replacePeerSavedGifts, + updateChats, updateStarsBalance, updateStarsSubscriptionLoading, + updateUsers, } from '../../reducers'; import { updateTabState } from '../../reducers/tabs'; import { @@ -102,6 +105,7 @@ addActionHandler('loadStarGifts', async (global): Promise => { all: [], stock: [], limited: [], + resale: [], }; const allStarGiftIds = Object.keys(byId); @@ -114,9 +118,13 @@ addActionHandler('loadStarGifts', async (global): Promise => { gift.availabilityRemains || !gift.availabilityTotal ? gift.id : undefined )).filter(Boolean); + const resaleStarGiftIds = allStarGifts.map((gift) => (gift.availabilityResale ? gift.id : undefined)) + .filter(Boolean); + idsByCategoryName.all = allStarGiftIds; idsByCategoryName.limited = limitedStarGiftIds; idsByCategoryName.stock = stockedStarGiftIds; + idsByCategoryName.resale = resaleStarGiftIds; allStarGifts.forEach((gift) => { const starsCategory = gift.stars; @@ -137,6 +145,115 @@ addActionHandler('loadStarGifts', async (global): Promise => { setGlobal(global); }); +addActionHandler('updateResaleGiftsFilter', (global, actions, payload): ActionReturnType => { + const { + filter, tabId = getCurrentTabId(), + } = payload; + + const tabState = selectTabState(global, tabId); + global = updateTabState(global, { + resaleGifts: { + ...tabState.resaleGifts, + filter, + }, + }, tabId); + if (tabState.resaleGifts.giftId) { + actions.loadResaleGifts({ giftId: tabState.resaleGifts.giftId, shouldRefresh: true, tabId }); + } + + setGlobal(global); +}); + +addActionHandler('loadResaleGifts', async (global, actions, payload): Promise => { + const { + giftId, shouldRefresh, tabId = getCurrentTabId(), + } = payload; + + let tabState = selectTabState(global, tabId); + if (tabState.resaleGifts.isLoading || (tabState.resaleGifts.isAllLoaded && !shouldRefresh)) return; + + global = updateTabState(global, { + resaleGifts: { + ...tabState.resaleGifts, + isLoading: true, + ...(shouldRefresh && { + count: 0, + nextOffset: undefined, + isAllLoaded: false, + }), + }, + }, tabId); + setGlobal(global); + + global = getGlobal(); + tabState = selectTabState(global, tabId); + const nextOffset = tabState.resaleGifts.nextOffset; + const attributesHash = tabState.resaleGifts.attributesHash; + const filter = tabState.resaleGifts.filter; + + const result = await callApi('fetchResaleGifts', { + giftId, + offset: nextOffset, + limit: RESALE_GIFTS_LIMIT, + attributesHash, + filter, + }); + + if (!result) { + return; + }; + + const { + chats, + users, + } = result; + + global = getGlobal(); + tabState = selectTabState(global, tabId); + + const currentGifts = tabState.resaleGifts.gifts; + const newGifts = !shouldRefresh ? currentGifts.concat(result.gifts) : result.gifts; + const currentUpdateIteration = tabState.resaleGifts.updateIteration; + const shouldUpdateIteration = tabState.resaleGifts.giftId !== giftId || shouldRefresh; + const updateIteration = shouldUpdateIteration ? currentUpdateIteration + 1 : currentUpdateIteration; + global = updateTabState(global, { + resaleGifts: { + ...tabState.resaleGifts, + giftId, + count: result.count || tabState.resaleGifts.count, + gifts: newGifts, + attributes: result.attributes || tabState.resaleGifts.attributes, + counters: result.counters || tabState.resaleGifts.counters, + attributesHash: result.attributesHash, + nextOffset: result.nextOffset, + isLoading: false, + isAllLoaded: !result.nextOffset, + updateIteration, + }, + }, tabId); + + global = updateUsers(global, buildCollectionByKey(users, 'id')); + global = updateChats(global, buildCollectionByKey(chats, 'id')); + + setGlobal(global); +}); + +addActionHandler('resetResaleGifts', (global, actions, payload): ActionReturnType => { + const { + tabId = getCurrentTabId(), + } = payload || {}; + + const tabState = selectTabState(global, tabId); + return updateTabState(global, { + resaleGifts: { + updateIteration: tabState.resaleGifts.updateIteration + 1, + filter: DEFAULT_RESALE_GIFTS_FILTER_OPTIONS, + count: 0, + gifts: [], + }, + }, tabId); +}); + addActionHandler('loadPeerSavedGifts', async (global, actions, payload): Promise => { const { peerId, shouldRefresh, tabId = getCurrentTabId(), diff --git a/src/global/actions/ui/stars.ts b/src/global/actions/ui/stars.ts index b202f8a34..40477c06c 100644 --- a/src/global/actions/ui/stars.ts +++ b/src/global/actions/ui/stars.ts @@ -256,11 +256,13 @@ addActionHandler('openGiftInfoModal', (global, actions, payload): ActionReturnTy } = payload; const peerId = 'peerId' in payload ? payload.peerId : undefined; + const recipientId = 'recipientId' in payload ? payload.recipientId : undefined; return updateTabState(global, { giftInfoModal: { peerId, gift, + recipientId, }, }, tabId); }); diff --git a/src/global/initialState.ts b/src/global/initialState.ts index 757321a63..19e5045d1 100644 --- a/src/global/initialState.ts +++ b/src/global/initialState.ts @@ -9,6 +9,7 @@ import { DEFAULT_MESSAGE_TEXT_SIZE_PX, DEFAULT_PATTERN_COLOR, DEFAULT_PLAYBACK_RATE, + DEFAULT_RESALE_GIFTS_FILTER_OPTIONS, DEFAULT_VOLUME, IOS_DEFAULT_MESSAGE_TEXT_SIZE_PX, MACOS_DEFAULT_MESSAGE_TEXT_SIZE_PX, @@ -389,6 +390,15 @@ export const INITIAL_TAB_STATE: TabState = { giftsByPeerId: {}, }, + resaleGifts: { + gifts: [], + count: 0, + updateIteration: 0, + filter: { + ...DEFAULT_RESALE_GIFTS_FILTER_OPTIONS, + }, + }, + storyViewer: { isMuted: true, isRibbonShown: false, diff --git a/src/global/types/actions.ts b/src/global/types/actions.ts index c392cd603..012ad25c2 100644 --- a/src/global/types/actions.ts +++ b/src/global/types/actions.ts @@ -80,6 +80,7 @@ import type { PerformanceType, Point, ProfileTabType, + ResaleGiftsFilterOptions, ScrollTargetPosition, SendMessageParams, SettingsScreens, @@ -2394,6 +2395,14 @@ export interface ActionPayloads { loadPremiumGifts: undefined; loadStarGifts: undefined; + updateResaleGiftsFilter: { + filter: ResaleGiftsFilterOptions; + } & WithTabId; + loadResaleGifts: { + giftId: string; + shouldRefresh?: boolean; + } & WithTabId; + resetResaleGifts: WithTabId | undefined; loadDefaultTopicIcons: undefined; loadPremiumStickers: undefined; @@ -2403,6 +2412,7 @@ export interface ActionPayloads { closeGiftModal: WithTabId | undefined; sendStarGift: StarGiftInfo & WithTabId; buyStarGift: { + peerId: string; slug: string; stars: number; } & WithTabId; @@ -2419,6 +2429,7 @@ export interface ActionPayloads { } & WithTabId; openGiftInfoModal: ({ peerId: string; + recipientId?: string; gift: ApiSavedStarGift; } | { gift: ApiStarGift; diff --git a/src/global/types/tabState.ts b/src/global/types/tabState.ts index 1258a2124..2b6908d1b 100644 --- a/src/global/types/tabState.ts +++ b/src/global/types/tabState.ts @@ -38,6 +38,7 @@ import type { ApiSponsoredPeer, ApiStarGift, ApiStarGiftAttribute, + ApiStarGiftAttributeCounter, ApiStarGiveawayOption, ApiStarsSubscription, ApiStarsTransaction, @@ -76,6 +77,7 @@ import type { PaymentStep, ProfileEditProgress, ProfileTabType, + ResaleGiftsFilterOptions, ScrollTargetPosition, SettingsScreens, SharedMediaType, @@ -217,6 +219,20 @@ export type TabState = { filter: GiftProfileFilterOptions; }; + resaleGifts: { + giftId?: string; + gifts: ApiStarGift[]; + count: number; + attributes?: ApiStarGiftAttribute[]; + counters?: ApiStarGiftAttributeCounter[]; + nextOffset?: string; + attributesHash?: string; + isLoading?: boolean; + isAllLoaded?: boolean; + filter: ResaleGiftsFilterOptions; + updateIteration: number; + }; + leftColumn: { contentKey: LeftColumnContent; settingsScreen: SettingsScreens; @@ -761,6 +777,7 @@ export type TabState = { giftInfoModal?: { peerId?: string; + recipientId?: string; gift: ApiSavedStarGift | ApiStarGift; }; diff --git a/src/lib/gramjs/tl/apiTl.ts b/src/lib/gramjs/tl/apiTl.ts index 2f1ef58ff..6ff916c1b 100644 --- a/src/lib/gramjs/tl/apiTl.ts +++ b/src/lib/gramjs/tl/apiTl.ts @@ -1765,6 +1765,7 @@ payments.getUniqueStarGift#a1974d72 slug:string = payments.UniqueStarGift; payments.getSavedStarGifts#23830de9 flags:# exclude_unsaved:flags.0?true exclude_saved:flags.1?true exclude_unlimited:flags.2?true exclude_limited:flags.3?true exclude_unique:flags.4?true sort_by_value:flags.5?true peer:InputPeer offset:string limit:int = payments.SavedStarGifts; payments.getStarGiftWithdrawalUrl#d06e93a8 stargift:InputSavedStarGift password:InputCheckPasswordSRP = payments.StarGiftWithdrawalUrl; payments.toggleStarGiftsPinnedToTop#1513e7b0 peer:InputPeer stargift:Vector = Bool; +payments.getResaleStarGifts#7a5fa236 flags:# sort_by_price:flags.1?true sort_by_num:flags.2?true attributes_hash:flags.0?long gift_id:long attributes:flags.3?Vector offset:string limit:int = payments.ResaleStarGifts; payments.updateStarGiftPrice#3baea4e1 stargift:InputSavedStarGift resell_stars:long = Updates; phone.requestCall#42ff96ed flags:# video:flags.0?true user_id:InputUser random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall; phone.acceptCall#3bd2b4a0 peer:InputPhoneCall g_b:bytes protocol:PhoneCallProtocol = phone.PhoneCall; diff --git a/src/lib/gramjs/tl/static/api.json b/src/lib/gramjs/tl/static/api.json index 5d9f58f71..ec6145828 100644 --- a/src/lib/gramjs/tl/static/api.json +++ b/src/lib/gramjs/tl/static/api.json @@ -319,6 +319,7 @@ "payments.getUniqueStarGift", "payments.getStarGiftWithdrawalUrl", "payments.toggleStarGiftsPinnedToTop", + "payments.getResaleStarGifts", "payments.updateStarGiftPrice", "langpack.getLangPack", "langpack.getStrings", diff --git a/src/styles/icons.scss b/src/styles/icons.scss index 1c6489d46..69a0c33c5 100644 --- a/src/styles/icons.scss +++ b/src/styles/icons.scss @@ -109,193 +109,197 @@ $icons-map: ( "double-badge": "\f148", "down": "\f149", "download": "\f14a", - "eats": "\f14b", - "edit": "\f14c", - "email": "\f14d", - "enter": "\f14e", - "expand-modal": "\f14f", - "expand": "\f150", - "eye-crossed-outline": "\f151", - "eye-crossed": "\f152", - "eye-outline": "\f153", - "eye": "\f154", - "favorite-filled": "\f155", - "favorite": "\f156", - "file-badge": "\f157", - "flag": "\f158", - "folder-badge": "\f159", - "folder": "\f15a", - "fontsize": "\f15b", - "forums": "\f15c", - "forward": "\f15d", - "fragment": "\f15e", - "frozen-time": "\f15f", - "fullscreen": "\f160", - "gifs": "\f161", - "gift": "\f162", - "group-filled": "\f163", - "group": "\f164", - "grouped-disable": "\f165", - "grouped": "\f166", - "hand-stop": "\f167", - "hashtag": "\f168", - "heart-outline": "\f169", - "heart": "\f16a", - "help": "\f16b", - "info-filled": "\f16c", - "info": "\f16d", - "install": "\f16e", - "italic": "\f16f", - "key": "\f170", - "keyboard": "\f171", - "lamp": "\f172", - "language": "\f173", - "large-pause": "\f174", - "large-play": "\f175", - "link-badge": "\f176", - "link-broken": "\f177", - "link": "\f178", - "location": "\f179", - "lock-badge": "\f17a", - "lock": "\f17b", - "logout": "\f17c", - "loop": "\f17d", - "mention": "\f17e", - "message-failed": "\f17f", - "message-pending": "\f180", - "message-read": "\f181", - "message-succeeded": "\f182", - "message": "\f183", - "microphone-alt": "\f184", - "microphone": "\f185", - "monospace": "\f186", - "more-circle": "\f187", - "more": "\f188", - "move-caption-down": "\f189", - "move-caption-up": "\f18a", - "mute": "\f18b", - "muted": "\f18c", - "my-notes": "\f18d", - "new-chat-filled": "\f18e", - "next": "\f18f", - "nochannel": "\f190", - "noise-suppression": "\f191", - "non-contacts": "\f192", - "one-filled": "\f193", - "open-in-new-tab": "\f194", - "password-off": "\f195", - "pause": "\f196", - "permissions": "\f197", - "phone-discard-outline": "\f198", - "phone-discard": "\f199", - "phone": "\f19a", - "photo": "\f19b", - "pin-badge": "\f19c", - "pin-list": "\f19d", - "pin": "\f19e", - "pinned-chat": "\f19f", - "pinned-message": "\f1a0", - "pip": "\f1a1", - "play-story": "\f1a2", - "play": "\f1a3", - "poll": "\f1a4", - "previous": "\f1a5", - "privacy-policy": "\f1a6", - "proof-of-ownership": "\f1a7", - "quote-text": "\f1a8", - "quote": "\f1a9", - "radial-badge": "\f1aa", - "readchats": "\f1ab", - "recent": "\f1ac", - "reload": "\f1ad", - "remove-quote": "\f1ae", - "remove": "\f1af", - "reopen-topic": "\f1b0", - "replace": "\f1b1", - "replies": "\f1b2", - "reply-filled": "\f1b3", - "reply": "\f1b4", - "revenue-split": "\f1b5", - "revote": "\f1b6", - "save-story": "\f1b7", - "saved-messages": "\f1b8", - "schedule": "\f1b9", - "search": "\f1ba", - "select": "\f1bb", - "sell-outline": "\f1bc", - "sell": "\f1bd", - "send-outline": "\f1be", - "send": "\f1bf", - "settings-filled": "\f1c0", - "settings": "\f1c1", - "share-filled": "\f1c2", - "share-screen-outlined": "\f1c3", - "share-screen-stop": "\f1c4", - "share-screen": "\f1c5", - "show-message": "\f1c6", - "sidebar": "\f1c7", - "skip-next": "\f1c8", - "skip-previous": "\f1c9", - "smallscreen": "\f1ca", - "smile": "\f1cb", - "sort": "\f1cc", - "speaker-muted-story": "\f1cd", - "speaker-outline": "\f1ce", - "speaker-story": "\f1cf", - "speaker": "\f1d0", - "spoiler-disable": "\f1d1", - "spoiler": "\f1d2", - "sport": "\f1d3", - "star": "\f1d4", - "stars-lock": "\f1d5", - "stats": "\f1d6", - "stealth-future": "\f1d7", - "stealth-past": "\f1d8", - "stickers": "\f1d9", - "stop-raising-hand": "\f1da", - "stop": "\f1db", - "story-caption": "\f1dc", - "story-expired": "\f1dd", - "story-priority": "\f1de", - "story-reply": "\f1df", - "strikethrough": "\f1e0", - "tag-add": "\f1e1", - "tag-crossed": "\f1e2", - "tag-filter": "\f1e3", - "tag-name": "\f1e4", - "tag": "\f1e5", - "timer": "\f1e6", - "toncoin": "\f1e7", - "trade": "\f1e8", - "transcribe": "\f1e9", - "truck": "\f1ea", - "unarchive": "\f1eb", - "underlined": "\f1ec", - "unique-profile": "\f1ed", - "unlist-outline": "\f1ee", - "unlist": "\f1ef", - "unlock-badge": "\f1f0", - "unlock": "\f1f1", - "unmute": "\f1f2", - "unpin": "\f1f3", - "unread": "\f1f4", - "up": "\f1f5", - "user-filled": "\f1f6", - "user-online": "\f1f7", - "user": "\f1f8", - "video-outlined": "\f1f9", - "video-stop": "\f1fa", - "video": "\f1fb", - "view-once": "\f1fc", - "voice-chat": "\f1fd", - "volume-1": "\f1fe", - "volume-2": "\f1ff", - "volume-3": "\f200", - "web": "\f201", - "webapp": "\f202", - "word-wrap": "\f203", - "zoom-in": "\f204", - "zoom-out": "\f205", + "dropdown-arrows": "\f14b", + "eats": "\f14c", + "edit": "\f14d", + "email": "\f14e", + "enter": "\f14f", + "expand-modal": "\f150", + "expand": "\f151", + "eye-crossed-outline": "\f152", + "eye-crossed": "\f153", + "eye-outline": "\f154", + "eye": "\f155", + "favorite-filled": "\f156", + "favorite": "\f157", + "file-badge": "\f158", + "flag": "\f159", + "folder-badge": "\f15a", + "folder": "\f15b", + "fontsize": "\f15c", + "forums": "\f15d", + "forward": "\f15e", + "fragment": "\f15f", + "frozen-time": "\f160", + "fullscreen": "\f161", + "gifs": "\f162", + "gift": "\f163", + "group-filled": "\f164", + "group": "\f165", + "grouped-disable": "\f166", + "grouped": "\f167", + "hand-stop": "\f168", + "hashtag": "\f169", + "heart-outline": "\f16a", + "heart": "\f16b", + "help": "\f16c", + "info-filled": "\f16d", + "info": "\f16e", + "install": "\f16f", + "italic": "\f170", + "key": "\f171", + "keyboard": "\f172", + "lamp": "\f173", + "language": "\f174", + "large-pause": "\f175", + "large-play": "\f176", + "link-badge": "\f177", + "link-broken": "\f178", + "link": "\f179", + "location": "\f17a", + "lock-badge": "\f17b", + "lock": "\f17c", + "logout": "\f17d", + "loop": "\f17e", + "mention": "\f17f", + "message-failed": "\f180", + "message-pending": "\f181", + "message-read": "\f182", + "message-succeeded": "\f183", + "message": "\f184", + "microphone-alt": "\f185", + "microphone": "\f186", + "monospace": "\f187", + "more-circle": "\f188", + "more": "\f189", + "move-caption-down": "\f18a", + "move-caption-up": "\f18b", + "mute": "\f18c", + "muted": "\f18d", + "my-notes": "\f18e", + "new-chat-filled": "\f18f", + "next": "\f190", + "nochannel": "\f191", + "noise-suppression": "\f192", + "non-contacts": "\f193", + "one-filled": "\f194", + "open-in-new-tab": "\f195", + "password-off": "\f196", + "pause": "\f197", + "permissions": "\f198", + "phone-discard-outline": "\f199", + "phone-discard": "\f19a", + "phone": "\f19b", + "photo": "\f19c", + "pin-badge": "\f19d", + "pin-list": "\f19e", + "pin": "\f19f", + "pinned-chat": "\f1a0", + "pinned-message": "\f1a1", + "pip": "\f1a2", + "play-story": "\f1a3", + "play": "\f1a4", + "poll": "\f1a5", + "previous": "\f1a6", + "privacy-policy": "\f1a7", + "proof-of-ownership": "\f1a8", + "quote-text": "\f1a9", + "quote": "\f1aa", + "radial-badge": "\f1ab", + "readchats": "\f1ac", + "recent": "\f1ad", + "reload": "\f1ae", + "remove-quote": "\f1af", + "remove": "\f1b0", + "reopen-topic": "\f1b1", + "replace": "\f1b2", + "replies": "\f1b3", + "reply-filled": "\f1b4", + "reply": "\f1b5", + "revenue-split": "\f1b6", + "revote": "\f1b7", + "save-story": "\f1b8", + "saved-messages": "\f1b9", + "schedule": "\f1ba", + "search": "\f1bb", + "select": "\f1bc", + "sell-outline": "\f1bd", + "sell": "\f1be", + "send-outline": "\f1bf", + "send": "\f1c0", + "settings-filled": "\f1c1", + "settings": "\f1c2", + "share-filled": "\f1c3", + "share-screen-outlined": "\f1c4", + "share-screen-stop": "\f1c5", + "share-screen": "\f1c6", + "show-message": "\f1c7", + "sidebar": "\f1c8", + "skip-next": "\f1c9", + "skip-previous": "\f1ca", + "smallscreen": "\f1cb", + "smile": "\f1cc", + "sort-by-date": "\f1cd", + "sort-by-number": "\f1ce", + "sort-by-price": "\f1cf", + "sort": "\f1d0", + "speaker-muted-story": "\f1d1", + "speaker-outline": "\f1d2", + "speaker-story": "\f1d3", + "speaker": "\f1d4", + "spoiler-disable": "\f1d5", + "spoiler": "\f1d6", + "sport": "\f1d7", + "star": "\f1d8", + "stars-lock": "\f1d9", + "stats": "\f1da", + "stealth-future": "\f1db", + "stealth-past": "\f1dc", + "stickers": "\f1dd", + "stop-raising-hand": "\f1de", + "stop": "\f1df", + "story-caption": "\f1e0", + "story-expired": "\f1e1", + "story-priority": "\f1e2", + "story-reply": "\f1e3", + "strikethrough": "\f1e4", + "tag-add": "\f1e5", + "tag-crossed": "\f1e6", + "tag-filter": "\f1e7", + "tag-name": "\f1e8", + "tag": "\f1e9", + "timer": "\f1ea", + "toncoin": "\f1eb", + "trade": "\f1ec", + "transcribe": "\f1ed", + "truck": "\f1ee", + "unarchive": "\f1ef", + "underlined": "\f1f0", + "unique-profile": "\f1f1", + "unlist-outline": "\f1f2", + "unlist": "\f1f3", + "unlock-badge": "\f1f4", + "unlock": "\f1f5", + "unmute": "\f1f6", + "unpin": "\f1f7", + "unread": "\f1f8", + "up": "\f1f9", + "user-filled": "\f1fa", + "user-online": "\f1fb", + "user": "\f1fc", + "video-outlined": "\f1fd", + "video-stop": "\f1fe", + "video": "\f1ff", + "view-once": "\f200", + "voice-chat": "\f201", + "volume-1": "\f202", + "volume-2": "\f203", + "volume-3": "\f204", + "web": "\f205", + "webapp": "\f206", + "word-wrap": "\f207", + "zoom-in": "\f208", + "zoom-out": "\f209", ); .icon-active-sessions::before { @@ -520,6 +524,9 @@ $icons-map: ( .icon-download::before { content: map.get($icons-map, "download"); } +.icon-dropdown-arrows::before { + content: map.get($icons-map, "dropdown-arrows"); +} .icon-eats::before { content: map.get($icons-map, "eats"); } @@ -907,6 +914,15 @@ $icons-map: ( .icon-smile::before { content: map.get($icons-map, "smile"); } +.icon-sort-by-date::before { + content: map.get($icons-map, "sort-by-date"); +} +.icon-sort-by-number::before { + content: map.get($icons-map, "sort-by-number"); +} +.icon-sort-by-price::before { + content: map.get($icons-map, "sort-by-price"); +} .icon-sort::before { content: map.get($icons-map, "sort"); } diff --git a/src/styles/icons.woff b/src/styles/icons.woff index c0bd67fb6b0b2ea9b10bdb4f791ce6728ced69ff..8b8701bb9b1c5c7bc9f11c4b03eb138fd77c2791 100644 GIT binary patch delta 24802 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 N+4&y;1b!O;000k4Ds2D& delta 24268 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 { @@ -2464,6 +2475,11 @@ export interface LangPairWithVariables { 'gift': V; 'stars': V; }; + 'GiftBuyForPeerConfirmDescription': { + 'gift': V; + 'stars': V; + 'peer': V; + }; 'ComposerTitleForwardFrom': { 'users': V; }; @@ -2758,6 +2774,18 @@ export interface LangPairPluralWithVariables { 'PaidMessageTransaction': { 'count': V; }; + 'HeaderDescriptionResaleGifts': { + 'count': V; + }; + 'GiftAttributeModelPlural': { + 'count': V; + }; + 'GiftAttributeBackdropPlural': { + 'count': V; + }; + 'GiftAttributeSymbolPlural': { + 'count': V; + }; } export type RegularLangKey = keyof LangPair; export type RegularLangKeyWithVariables = keyof LangPairWithVariables;