Skip to content

Commit

Permalink
v1.17.2
Browse files Browse the repository at this point in the history
  • Loading branch information
mytonwalletorg committed Dec 22, 2023
1 parent 11c55a3 commit c684f72
Show file tree
Hide file tree
Showing 23 changed files with 102 additions and 92 deletions.
1 change: 1 addition & 0 deletions changelogs/1.17.2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Some hotfixes
10 changes: 5 additions & 5 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": "1.17.1",
"version": "1.17.2",
"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 @@
1.17.1
1.17.2
7 changes: 5 additions & 2 deletions src/components/common/TokenSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, {
memo, useEffect, useLayoutEffect, useMemo, useRef, useState,
memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState,
} from '../../lib/teact/teact';
import { getActions, withGlobal } from '../../global';

Expand Down Expand Up @@ -130,7 +130,10 @@ function TokenSelector({

const balancesBySlugPrev = usePrevious(balancesBySlug);

const filterTokens = useLastCallback((tokens: Token[]) => filterAndSortTokens(tokens, tokenInSlug, pairsBySlug));
// It is necessary to use useCallback instead of useLastCallback here
const filterTokens = useCallback((tokens: Token[]) => {
return filterAndSortTokens(tokens, tokenInSlug, pairsBySlug);
}, [pairsBySlug, tokenInSlug]);

const allUnimportedTonTokens = useMemo(() => {
const balances = balancesBySlugPrev ?? balancesBySlug ?? {};
Expand Down
3 changes: 2 additions & 1 deletion src/components/main/modals/BackupModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,14 @@ function BackupModal({
const handlePasswordSubmit = useLastCallback(async (password: string) => {
setIsLoading(true);
mnemonicRef.current = await callApi('getMnemonic', currentAccountId!, password);
setIsLoading(false);

if (!mnemonicRef.current) {
setError('Wrong password, please try again');
if (IS_CAPACITOR) {
void vibrateOnError();
}

setIsLoading(false);
return;
}
if (IS_CAPACITOR) {
Expand All @@ -84,6 +84,7 @@ function BackupModal({
clearIsPinPadPasswordAccepted();
}

setIsLoading(false);
setNextKey(SLIDES.check);
setCurrentSlide(SLIDES.mnemonic);
});
Expand Down
3 changes: 2 additions & 1 deletion src/components/main/modals/TransactionModal.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
align-items: center;
justify-content: center;

margin-top: 3rem;
margin-top: auto;
padding-top: 3rem;
}

.copyButtonWrapper {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,9 @@

transition: background-color 150ms, color 150ms;

@media (hover: hover) {
&:hover,
&:focus {
color: var(--color-blue);
}
&:hover,
&:focus {
color: var(--color-blue);
}

&:active {
Expand Down
2 changes: 1 addition & 1 deletion src/components/main/sections/Content/Swap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ function Swap({
// Skip the 'waiting' status for transactions from TON to account for delayed status updates from changelly.
text = lang('Waiting for payment');
} else if (isPending) {
text = lang('In progress');
text = lang('Waiting for payment');
}

return (
Expand Down
7 changes: 7 additions & 0 deletions src/components/receive/ReceiveModal.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@
.invoiceButton {
max-width: 100% !important;

background-color: var(--color-gray-button-background) !important;

&:focus,
&:hover {
background-color: var(--color-gray-button-background-hover) !important;
}

@include respond-above(xs) {
background-color: var(--color-gray-button-background-desktop) !important;

Expand Down
38 changes: 16 additions & 22 deletions src/components/swap/SwapInitial.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import useFlag from '../../hooks/useFlag';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import usePrevious from '../../hooks/usePrevious';
import usePrevious2 from '../../hooks/usePrevious2';
import useSyncEffect from '../../hooks/useSyncEffect';

import AnimatedIconWithPreview from '../ui/AnimatedIconWithPreview';
Expand Down Expand Up @@ -497,9 +496,7 @@ function SwapInitial({
</div>

<div className={buildClassName(styles.swapButtonWrapper, isStatic && styles.swapButtonWrapperStatic)}>
<div className={styles.swapButton} onClick={handleSwitchTokens}>
<AnimatedArrows value={tokenIn?.slug} />
</div>
<AnimatedArrows onClick={handleSwitchTokens} />
</div>

<div ref={inputOutRef} className={styles.inputContainer}>
Expand Down Expand Up @@ -582,24 +579,21 @@ function useTokenTransitionKey(tokenSlug: string) {
return transitionKeyRef.current;
}

function AnimatedArrows({ value }: { value?: string }) {
function AnimatedArrows({ onClick }: { onClick?: NoneToVoidFunction }) {
const animationLevel = getGlobal().settings.animationLevel;
const prevValue = usePrevious2(value);

const shouldAnimate = (animationLevel === ANIMATION_LEVEL_MAX) && prevValue && prevValue !== value;
const [hasAnimation, setHasAnimation] = useState(false);

useEffect(() => {
if (!shouldAnimate) return undefined;

setHasAnimation(true);

const timeoutId = window.setTimeout(() => {
setHasAnimation(false);
}, 350);
const shouldAnimate = (animationLevel === ANIMATION_LEVEL_MAX);
const [hasAnimation, startAnimation, stopAnimation] = useFlag(false);

const handleClick = useLastCallback(() => {
if (shouldAnimate) {
startAnimation();
window.setTimeout(() => {
stopAnimation();
}, 350);
}

return () => window.clearTimeout(timeoutId);
}, [animationLevel, prevValue, shouldAnimate, value]);
onClick?.();
});

function renderArrow(isInverted?: boolean) {
return (
Expand All @@ -618,9 +612,9 @@ function AnimatedArrows({ value }: { value?: string }) {
}

return (
<>
<div className={styles.swapButton} onClick={handleClick}>
{renderArrow()}
{renderArrow(true)}
</>
</div>
);
}
2 changes: 1 addition & 1 deletion src/components/swap/SwapWaitTokens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ function SwapWaitTokens({
return (
<>
<ModalHeader
title={lang('Waiting Payment')}
title={lang('Waiting for Payment')}
onClose={onClose}
/>

Expand Down
6 changes: 3 additions & 3 deletions src/components/ui/PasswordForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { withGlobal } from '../../global';

import type { AuthConfig } from '../../util/authApi/types';

import { PIN_LENGTH } from '../../config';
import { IS_CAPACITOR, PIN_LENGTH } from '../../config';
import authApi from '../../util/authApi';
import buildClassName from '../../util/buildClassName';
import { getIsFaceIdAvailable, getIsNativeBiometricAuthSupported, getIsTouchIdAvailable } from '../../util/capacitor';
import { getIsFaceIdAvailable, getIsTouchIdAvailable } from '../../util/capacitor';
import captureKeyboardListeners from '../../util/captureKeyboardListeners';
import { pause } from '../../util/schedulers';
import { IS_DELEGATING_BOTTOM_SHEET } from '../../util/windowEnvironment';
Expand Down Expand Up @@ -160,7 +160,7 @@ function PasswordForm({
}
}

if (getIsNativeBiometricAuthSupported()) {
if (IS_CAPACITOR) {
const hasError = Boolean(localError || error);
const title = getPinPadTitle();
const actionName = lang(
Expand Down
30 changes: 19 additions & 11 deletions src/components/ui/PinPad.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ function PinPad({
}: OwnProps & StateProps) {
const isFaceId = getIsFaceIdAvailable();
const canRenderBackspace = value.length > 0;
const isDisablePinButtons = value.length === length || Boolean(type);
const arePinButtonsDisabled = value.length === length
&& type !== 'error'; // Allow pincode entry in case of an error
const isSuccess = type === 'success' || isPinPadPasswordAccepted;
const titleClassName = buildClassName(
styles.title,
Expand All @@ -70,6 +71,13 @@ function PinPad({
}, [length, onChange, onClearError, type, value.length]);

const handleClick = useLastCallback((char: string) => {
if (value.length === length) {
onChange(char);
onClearError?.();

return;
}

const newValue = `${value}${char}`;
onChange(newValue);

Expand Down Expand Up @@ -115,21 +123,21 @@ function PinPad({
{renderDots()}

<div className={styles.grid}>
<PinPadButton value="1" onClick={handleClick} isDisabled={isDisablePinButtons} />
<PinPadButton value="2" onClick={handleClick} isDisabled={isDisablePinButtons} />
<PinPadButton value="3" onClick={handleClick} isDisabled={isDisablePinButtons} />
<PinPadButton value="4" onClick={handleClick} isDisabled={isDisablePinButtons} />
<PinPadButton value="5" onClick={handleClick} isDisabled={isDisablePinButtons} />
<PinPadButton value="6" onClick={handleClick} isDisabled={isDisablePinButtons} />
<PinPadButton value="7" onClick={handleClick} isDisabled={isDisablePinButtons} />
<PinPadButton value="8" onClick={handleClick} isDisabled={isDisablePinButtons} />
<PinPadButton value="9" onClick={handleClick} isDisabled={isDisablePinButtons} />
<PinPadButton value="1" onClick={handleClick} isDisabled={arePinButtonsDisabled} />
<PinPadButton value="2" onClick={handleClick} isDisabled={arePinButtonsDisabled} />
<PinPadButton value="3" onClick={handleClick} isDisabled={arePinButtonsDisabled} />
<PinPadButton value="4" onClick={handleClick} isDisabled={arePinButtonsDisabled} />
<PinPadButton value="5" onClick={handleClick} isDisabled={arePinButtonsDisabled} />
<PinPadButton value="6" onClick={handleClick} isDisabled={arePinButtonsDisabled} />
<PinPadButton value="7" onClick={handleClick} isDisabled={arePinButtonsDisabled} />
<PinPadButton value="8" onClick={handleClick} isDisabled={arePinButtonsDisabled} />
<PinPadButton value="9" onClick={handleClick} isDisabled={arePinButtonsDisabled} />
{!onBiometricsClick ? <span /> : (
<PinPadButton onClick={onBiometricsClick} isDisabled={isSuccess}>
<i className={buildClassName('icon', isFaceId ? 'icon-face-id' : 'icon-touch-id')} aria-hidden />
</PinPadButton>
)}
<PinPadButton value="0" onClick={handleClick} isDisabled={isDisablePinButtons} />
<PinPadButton value="0" onClick={handleClick} isDisabled={arePinButtonsDisabled} />
<PinPadButton
className={!canRenderBackspace && styles.buttonHidden}
isDisabled={!canRenderBackspace}
Expand Down
2 changes: 1 addition & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export const PROXY_HOSTS = process.env.PROXY_HOSTS;

export const TINY_TRANSFER_MAX_COST = 0.01;

export const LANG_CACHE_NAME = 'mtw-lang-53';
export const LANG_CACHE_NAME = 'mtw-lang-54';

export const LANG_LIST: LangItem[] = [{
langCode: 'en',
Expand Down
39 changes: 21 additions & 18 deletions src/global/actions/api/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@ import { parseAccountId } from '../../../util/account';
import authApi from '../../../util/authApi';
import webAuthn from '../../../util/authApi/webAuthn';
import {
getIsBiometricAuthSupported,
getIsNativeBiometricAuthSupported,
vibrateOnError,
vibrateOnSuccess,
} from '../../../util/capacitor';
import { cloneDeep } from '../../../util/iteratees';
import { pause } from '../../../util/schedulers';
import { IS_DELEGATED_BOTTOM_SHEET, IS_ELECTRON } from '../../../util/windowEnvironment';
import { IS_BIOMETRIC_AUTH_SUPPORTED, IS_DELEGATED_BOTTOM_SHEET, IS_ELECTRON } from '../../../util/windowEnvironment';
import { callApi } from '../../../api';
import { addActionHandler, getGlobal, setGlobal } from '../..';
import { INITIAL_STATE } from '../../initialState';
Expand Down Expand Up @@ -114,9 +113,9 @@ addActionHandler('startCreatingWallet', async (global, actions) => {
}

setGlobal(updateAuth(global, {
state: getIsBiometricAuthSupported()
? (getIsNativeBiometricAuthSupported() ? AuthState.createPin : AuthState.createBiometrics)
: AuthState.createPassword,
state: IS_CAPACITOR
? AuthState.createPin
: (IS_BIOMETRIC_AUTH_SUPPORTED ? AuthState.createBiometrics : AuthState.createPassword),
}));

if (isFirstAccount) {
Expand All @@ -136,10 +135,14 @@ addActionHandler('createPin', (global, actions, { pin, isImporting }) => {
});

addActionHandler('confirmPin', (global, actions, { isImporting }) => {
global = updateAuth(global, {
state: isImporting ? AuthState.importWalletCreateNativeBiometrics : AuthState.createNativeBiometrics,
});
setGlobal(global);
if (getIsNativeBiometricAuthSupported()) {
global = updateAuth(global, {
state: isImporting ? AuthState.importWalletCreateNativeBiometrics : AuthState.createNativeBiometrics,
});
setGlobal(global);
} else {
actions.skipCreateNativeBiometrics();
}
});

addActionHandler('cancelConfirmPin', (global, actions, { isImporting }) => {
Expand All @@ -151,9 +154,9 @@ addActionHandler('cancelConfirmPin', (global, actions, { isImporting }) => {

addActionHandler('cancelDisclaimer', (global) => {
setGlobal(updateAuth(global, {
state: getIsBiometricAuthSupported()
? (getIsNativeBiometricAuthSupported() ? AuthState.createPin : AuthState.createBiometrics)
: AuthState.createPassword,
state: IS_CAPACITOR
? AuthState.createPin
: (IS_BIOMETRIC_AUTH_SUPPORTED ? AuthState.createBiometrics : AuthState.createPassword),
}));
});

Expand Down Expand Up @@ -293,6 +296,7 @@ addActionHandler('createAccount', async (global, actions, { password, isImportin
password: undefined,
...(isPasswordNumeric && { isPasswordNumeric: true }),
});
global = clearIsPinPadPasswordAccepted(global);

if (isImporting) {
const hasAccounts = Object.keys(selectAccounts(global) || {}).length > 0;
Expand Down Expand Up @@ -436,12 +440,11 @@ addActionHandler('afterImportMnemonic', async (global, actions, { mnemonic }) =>
mnemonic,
error: undefined,
...(!hasAccounts && {
state: getIsBiometricAuthSupported()
? (getIsNativeBiometricAuthSupported()
? AuthState.importWalletCreatePin
: AuthState.importWalletCreateBiometrics
)
: AuthState.importWalletCreatePassword,
state: IS_CAPACITOR
? AuthState.importWalletCreatePin
: (IS_BIOMETRIC_AUTH_SUPPORTED
? AuthState.importWalletCreateBiometrics
: AuthState.importWalletCreatePassword),
}),
});
setGlobal(global);
Expand Down
Loading

0 comments on commit c684f72

Please sign in to comment.