Skip to content

Commit

Permalink
v3.2.10
Browse files Browse the repository at this point in the history
  • Loading branch information
mytonwalletorg committed Jan 23, 2025
1 parent 450f6a6 commit c381b41
Show file tree
Hide file tree
Showing 19 changed files with 190 additions and 115 deletions.
1 change: 1 addition & 0 deletions changelogs/3.2.10.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Bug fixes and performance improvements
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mytonwallet",
"version": "3.2.9",
"version": "3.2.10",
"description": "The most feature-rich web wallet and browser extension for TON – with support of multi-accounts, tokens (jettons), NFT, TON DNS, TON Sites, TON Proxy, and TON Magic.",
"main": "index.js",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion public/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.2.9
3.2.10
20 changes: 12 additions & 8 deletions src/api/chains/ton/util/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,14 @@ import type {
ApiNetwork,
ApiNft,
ApiNftMetadata,
ApiParsedPayload, ApiTransactionType,
ApiParsedPayload,
ApiTransactionType,
} from '../../../types';
import type { DnsCategory } from '../constants';
import type { ApiTransactionExtra, JettonMetadata } from '../types';

import {
DEBUG,
LIQUID_JETTON,
MTW_CARDS_COLLECTION,
NFT_FRAGMENT_COLLECTIONS,
DEBUG, LIQUID_JETTON, MTW_CARDS_COLLECTION, NFT_FRAGMENT_COLLECTIONS,
} from '../../../../config';
import { omitUndefined, pick, range } from '../../../../util/iteratees';
import { logDebugError } from '../../../../util/logs';
Expand Down Expand Up @@ -650,7 +648,7 @@ export function readSnakeBytes(slice: Slice) {
return buffer;
}

function buildNftMetadata(metadata: Record<string, any>): ApiNftMetadata | undefined {
function buildMtwCardsNftMetadata(metadata: Record<string, any>): ApiNftMetadata | undefined {
const { image, id } = metadata as { image?: string; id?: number };

let mtwCardType: ApiMtwCardType | undefined;
Expand Down Expand Up @@ -708,12 +706,13 @@ export function buildNft(network: ApiNetwork, rawNft: NftItem): ApiNft | undefin
} = rawNft;

const {
name, image, description, render_type: renderType,
name, image, description, render_type: renderType, lottie,
} = rawMetadata as {
name?: string;
image?: string;
description?: string;
render_type?: string;
lottie?: string;
};

const collectionAddress = collection && toBase64Address(collection.address, true, network);
Expand All @@ -727,10 +726,15 @@ export function buildNft(network: ApiNetwork, rawNft: NftItem): ApiNft | undefin
}
}

const isWhitelisted = trust === 'whitelist';
const isScam = hasScamLink || description === 'SCAM' || trust === 'blacklist';
const isHidden = renderType === 'hidden' || isScam;
const imageFromPreview = previews!.find((x) => x.resolution === '1500x1500')!.url;
const metadata = collectionAddress === MTW_CARDS_COLLECTION ? buildNftMetadata(rawMetadata) : undefined;

const metadata = {
...(isWhitelisted && { lottie }),
...(collectionAddress === MTW_CARDS_COLLECTION && buildMtwCardsNftMetadata(rawMetadata)),
};

return omitUndefined<ApiNft>({
index,
Expand Down
3 changes: 2 additions & 1 deletion src/api/types/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export type ApiMtwCardTextType = 'light' | 'dark';
export type ApiMtwCardBorderShineType = 'up' | 'down' | 'left' | 'right' | 'radioactive';

export interface ApiNftMetadata {
lottie?: string;
imageUrl?: string;
mtwCardId?: number;
mtwCardType?: ApiMtwCardType;
Expand All @@ -109,7 +110,7 @@ export interface ApiNft {
isHidden?: boolean;
isOnFragment?: boolean;
isScam?: boolean;
metadata?: ApiNftMetadata;
metadata: ApiNftMetadata;
}

export type ApiHistoryList = Array<[number, number]>;
Expand Down
6 changes: 2 additions & 4 deletions src/components/main/sections/Content/Nft.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@
.imageWrapper {
/* Fix for border-radius missing during transform on Safari. See https://stackoverflow.com/a/58283449 */
isolation: isolate;
position: relative;

display: block !important;

Expand All @@ -192,11 +191,10 @@
}

.image {
position: absolute;
top: 0;
left: 0;
transform-origin: center;

overflow: hidden;

width: 100%;
height: 100%;

Expand Down
77 changes: 63 additions & 14 deletions src/components/main/sections/Content/Nft.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@ import React, {
import { getActions } from '../../../../global';

import type { ApiNft } from '../../../../api/types';
import type { ObserveFn } from '../../../../hooks/useIntersectionObserver';
import { type IAnchorPosition, MediaType } from '../../../../global/types';

import buildClassName from '../../../../util/buildClassName';
import { vibrate } from '../../../../util/capacitor';
import { preloadImage } from '../../../../util/preloadImage';
import { shortenAddress } from '../../../../util/shortenAddress';

import useFlag from '../../../../hooks/useFlag';
import { useIsIntersecting } from '../../../../hooks/useIntersectionObserver';
import useLang from '../../../../hooks/useLang';
import useLastCallback from '../../../../hooks/useLastCallback';
import useShowTransition from '../../../../hooks/useShowTransition';

import AnimatedIconWithPreview from '../../../ui/AnimatedIconWithPreview';
import Image from '../../../ui/Image';
import Radio from '../../../ui/Radio';
import NftMenu from './NftMenu';
Expand All @@ -24,14 +27,21 @@ import styles from './Nft.module.scss';
interface OwnProps {
nft: ApiNft;
selectedAddresses?: string[];
observeIntersection: ObserveFn;
}

function Nft({ nft, selectedAddresses }: OwnProps) {
function Nft({ nft, selectedAddresses, observeIntersection }: OwnProps) {
const { openMediaViewer, selectNfts, clearNftSelection } = getActions();

const lang = useLang();

// eslint-disable-next-line no-null/no-null
const ref = useRef<HTMLDivElement>(null);

const {
isLottie, shouldPlay, noLoop, markHover, unmarkHover,
} = useLottie(nft, ref, observeIntersection);

const [menuPosition, setMenuPosition] = useState<IAnchorPosition>();
const isSelectionEnabled = !!selectedAddresses && selectedAddresses.length > 0;
const isSelected = useMemo(() => selectedAddresses?.includes(nft.address), [selectedAddresses, nft.address]);
Expand All @@ -40,6 +50,7 @@ function Nft({ nft, selectedAddresses }: OwnProps) {
shouldRender: shouldRenderWarning,
transitionClassNames: warningTransitionClassNames,
} = useShowTransition(isSelectionEnabled && nft.isOnSale);

const fullClassName = buildClassName(
styles.item,
!isSelectionEnabled && nft.isOnSale && styles.item_onSale,
Expand Down Expand Up @@ -70,18 +81,15 @@ function Nft({ nft, selectedAddresses }: OwnProps) {
setMenuPosition(undefined);
});

const handleIntersect = useLastCallback(() => {
preloadImage(nft.image).catch(() => {
});
});

return (
<div
key={nft.address}
ref={ref}
data-nft-address={nft.address}
onClick={!isSelectionEnabled || !nft.isOnSale ? handleClick : undefined}
className={fullClassName}
onMouseEnter={markHover}
onMouseLeave={unmarkHover}
onClick={!isSelectionEnabled || !nft.isOnSale ? handleClick : undefined}
>
{isSelectionEnabled && !nft.isOnSale && (
<Radio
Expand All @@ -99,12 +107,27 @@ function Nft({ nft, selectedAddresses }: OwnProps) {
onClose={handleCloseMenu}
/>
)}
<Image
url={nft.thumbnail}
className={styles.imageWrapper}
imageClassName={buildClassName(styles.image, isSelected && styles.imageSelected)}
onIntersect={handleIntersect}
/>
{isLottie ? (
<div
className={styles.imageWrapper}
>
<AnimatedIconWithPreview
shouldStretch
play={shouldPlay}
noLoop={noLoop}
tgsUrl={nft.metadata!.lottie}
previewUrl={nft.thumbnail}
noPreviewTransition
className={buildClassName(styles.image, isSelected && styles.imageSelected)}
/>
</div>
) : (
<Image
url={nft.thumbnail}
className={styles.imageWrapper}
imageClassName={buildClassName(styles.image, isSelected && styles.imageSelected)}
/>
)}
{shouldRenderWarning && (
<div className={buildClassName(styles.warning, warningTransitionClassNames)}>
{lang('For sale. Cannot be sent and burned')}
Expand All @@ -119,3 +142,29 @@ function Nft({ nft, selectedAddresses }: OwnProps) {
}

export default memo(Nft);

function useLottie(
nft: ApiNft,
ref: React.RefObject<HTMLDivElement>,
observeIntersection: ObserveFn,
) {
const isLottie = Boolean(nft.metadata?.lottie);

const isIntersecting = useIsIntersecting(ref, isLottie ? observeIntersection : undefined);
const [isHover, markHover, unmarkHover] = useFlag();

if (!isLottie) {
return { isLottie };
}

const shouldPlay = isIntersecting || isHover;
const noLoop = !isHover;

return {
isLottie,
shouldPlay,
noLoop,
markHover,
unmarkHover,
};
}
34 changes: 0 additions & 34 deletions src/components/main/sections/Content/NftImage.tsx

This file was deleted.

Loading

0 comments on commit c381b41

Please sign in to comment.