Skip to content

Commit

Permalink
Merge pull request #477 from tonkeeper/release/3.3.2
Browse files Browse the repository at this point in the history
feat(mobile): renew all domains
  • Loading branch information
bogoslavskiy authored Sep 5, 2023
2 parents 93c2865 + e50ae7f commit a17700f
Show file tree
Hide file tree
Showing 24 changed files with 803 additions and 65 deletions.
4 changes: 2 additions & 2 deletions packages/mobile/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ android {
applicationId "com.ton_keeper"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 341
versionName "3.3"
versionCode 367
versionName "3.3.2"
missingDimensionStrategy 'react-native-camera', 'general'
}

Expand Down
8 changes: 4 additions & 4 deletions packages/mobile/ios/ton_keeper.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1218,7 +1218,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = ton_keeper/ton_keeper.entitlements;
CURRENT_PROJECT_VERSION = 341;
CURRENT_PROJECT_VERSION = 367;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = CT523DK2KC;
ENABLE_BITCODE = NO;
Expand All @@ -1228,7 +1228,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 3.3;
MARKETING_VERSION = 3.3.2;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
Expand All @@ -1253,7 +1253,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = ton_keeper/ton_keeper.entitlements;
CURRENT_PROJECT_VERSION = 341;
CURRENT_PROJECT_VERSION = 367;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = CT523DK2KC;
INFOPLIST_FILE = ton_keeper/SupportingFiles/Info.plist;
Expand All @@ -1262,7 +1262,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 3.3;
MARKETING_VERSION = 3.3.2;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
Expand Down
1 change: 1 addition & 0 deletions packages/mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"build:android": "cd android && ./gradlew assembleRelease && ./gradlew bundleRelease && cd .. && node scripts/prepare_builds.js",
"build:android:apk": "cd android && ./gradlew assembleRelease && cd ..",
"build:android:apk-site": "ENVFILE=.env.site yarn build:android:apk",
"build:android:google-play": "git apply ../../patches/google-play-release.patch && yarn build:android && git apply -R ../../patches/google-play-release.patch",
"clean:android": "cd android && ./gradlew clean && cd ..",
"open_build_folder": "open ./android/app/build/outputs/bundle",
"postinstall": "expo-yarn-workspaces postinstall && patch-package",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions packages/mobile/src/assets/icons/svg/28/ic-globe-28.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,15 @@ export const ApprovalCell = React.memo(ApprovalCellComponent);

const styles = Steezy.create(({ colors }) => ({
container: {
backgroundColor: colors.backgroundContentAttention,
backgroundColor: colors.backgroundContentTint,
marginBottom: 4,
},
title: {
marginRight: 40,
},
iconContainer: {
padding: 8,
backgroundColor: colors.iconTertiary,
backgroundColor: colors.backgroundContentAttention,
borderRadius: 32,
},
}));
4 changes: 4 additions & 0 deletions packages/mobile/src/navigation/ModalStack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import { NewConfirmSending } from '$core/ModalContainer/NewConfirmSending/NewCon
import { ActionModal } from '$core/ModalContainer/Action/Action';
import { ExchangeModal } from '$modals/ExchangeModal';
import { Swap } from '$core/Swap/Swap';
import { RenewAllDomainModal } from '../tabs/Wallet/RenewAllDomainModal';
import { СonfirmRenewAllDomains } from '../tabs/Wallet/components/СonfirmRenewAllDomains';

const Stack = createModalStackNavigator();

Expand All @@ -48,6 +50,7 @@ export const ModalStack = React.memo(() => (
<Stack.Modal component={NFTSaleCancelModal} path="NFTSaleCancel" />
<Stack.Modal component={ExchangeModal} path="Exchange" />
<Stack.Modal component={OldExchange} path="OldExchange" />
<Stack.Modal component={СonfirmRenewAllDomains} path="СonfirmRenewAllDomains"/>
<Stack.Modal
component={NFTTransferInputAddressModal}
path="NFTTransferInputAddress"
Expand All @@ -57,6 +60,7 @@ export const ModalStack = React.memo(() => (
</Stack.Group>
<Stack.Group behavior="modal">
<Stack.Modal component={NFT} path="NFTItemDetails" />
<Stack.Modal component={RenewAllDomainModal} path="RenewAllDomains" />
<Stack.Modal component={Receive} path={AppStackRouteNames.Receive} />
<Stack.Modal component={Send} path={AppStackRouteNames.Send} />
<Stack.Modal component={StakingSend} path={AppStackRouteNames.StakingSend} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import { ns } from '$utils';
import * as S from './BottomButtonWrap.style';
import { useTheme } from '$hooks';

export const BottomButtonWrapHelper: FC = () => {
export const BottomButtonWrapHelper: FC<{ safeArea?: boolean }> = (props) => {
const { safeArea = true } = props;
const { bottom } = useSafeAreaInsets();
return (
<S.Helper
style={{
height: ns(56 + 16) + bottom + ns(16),
height: ns(56 + 16) + (safeArea ? bottom : 0) + ns(16),
}}
/>
);
Expand Down
4 changes: 3 additions & 1 deletion packages/mobile/src/store/main/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ import { clearSubscribeStatus } from '$utils/messaging';
import { useJettonEventsStore } from '$store/zustand/jettonEvents';
import { useSwapStore } from '$store/zustand/swap';
import * as SecureStore from 'expo-secure-store';
import { useExpiringDomains } from '$store/zustand/domains/useExpiringDomains';

SplashScreen.preventAutoHideAsync()
.then((result) =>
Expand Down Expand Up @@ -210,8 +211,9 @@ export function* initHandler(isTestnet: boolean, canRetry = false) {
yield put(jettonsActions.loadJettons());
yield put(subscriptionsActions.loadSubscriptions());
const { wallet: walletNew } = yield select(walletSelector);
yield call([walletNew.ton, 'getAddress']);
const address = yield call([walletNew.ton, 'getAddress']);
useSwapStore.getState().actions.fetchAssets();
useExpiringDomains.getState().actions.load(address);
} else {
yield put(walletActions.endLoading());
}
Expand Down
39 changes: 39 additions & 0 deletions packages/mobile/src/store/zustand/domains/types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,47 @@
export type RawAddress = string;
export type ExpiringAt = number;

export interface ExpiringDomainItem {
expiring_at: number
name: string
dns_item: DnsItem
}

export interface DnsItem {
address: string
index: number
owner: Owner
collection: Collection
verified: boolean
metadata: Metadata
previews: Preview[]
dns: string
approved_by: string[]
}

export interface Owner {
address: string
is_scam: boolean
}

export interface Collection {
address: string
name: string
description: string
}

export interface Metadata {
name: string
}

export interface Preview {
resolution: string
url: string
}

export type ExpiringDomains = {
domains: { [key in RawAddress]: ExpiringAt };
items: ExpiringDomainItem[];
actions: {
load: (account_id: string) => void;
remove: (address: string) => void;
Expand Down
21 changes: 12 additions & 9 deletions packages/mobile/src/store/zustand/domains/useExpiringDomains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Address } from '$libs/Ton';

const initialState: Omit<ExpiringDomains, 'actions'> = {
domains: {},
items: [],
};

export const useExpiringDomains = create(
Expand All @@ -17,27 +18,29 @@ export const useExpiringDomains = create(
load: async (account_id) => {
try {
const { data } = await Tonapi.getExpiringDNS({
account_id,
account_id,
period: 30,
});

const domains = {};
for (let item of data.items) {
domains[item.dns_item.address] = item.expiring_at;
}

set({ domains });
set({ domains, items: data.items });
} catch (err) {
console.log('err[getExpiringDNS]', err);
console.log('[getExpiringDNS]', err);
}
},
remove: (address) => {
set(({ domains }) => {
set(({ domains, items }) => {
const rawAddress = new Address(address).format({ raw: true });
const { [rawAddress]: remove, ...rest } = domains;
return { domains: rest };
const newItems = items.filter((item) => item.dns_item.address !== rawAddress);

return { domains: rest, items: newItems };
});
}
},
},
})),
);
Expand All @@ -53,7 +56,7 @@ export function useLoadExpiringDomains() {
if (wallet) {
load(wallet.address.rawAddress);
}
}, []);
}, [wallet?.address.rawAddress]);

return null;
}
}
131 changes: 131 additions & 0 deletions packages/mobile/src/tabs/Wallet/RenewAllDomainModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { useNavigation } from '$libs/navigation';
import { navigate, openNFT } from '$navigation/helper';
import { ExpiringDomainItem } from '$store/zustand/domains/types';
import { useExpiringDomains } from '$store/zustand/domains/useExpiringDomains';
import { t } from '$translation';
import { Button, List, NavBar, SText } from '$uikit';
import { ONE_YEAR_MILISEC, delay, format, getCountOfDays, getLocale, ns } from '$utils';
import { memo, useCallback, useRef } from 'react';
import { View, StyleSheet } from 'react-native';
import Animated, {
useAnimatedScrollHandler,
useSharedValue,
} from 'react-native-reanimated';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { Ton } from '$libs/Ton';
import { BottomButtonWrap, BottomButtonWrapHelper } from '$shared/components';
import { openСonfirmRenewAllDomains } from './components/СonfirmRenewAllDomains';
import { CryptoCurrencies } from '$shared/constants';

export const RenewAllDomainModal = memo(() => {
const safeArea = useSafeAreaInsets();
const scrollTop = useSharedValue(0);
const scrollRef = useRef<Animated.ScrollView>(null);
const nav = useNavigation();
const domains = useExpiringDomains((state) => state.items);

const handleRenew = useCallback(async () => {
await delay(1000);
if (domains.length < 1) {
nav.goBack();
}
}, [domains]);

const handleRenewAll = useCallback(async () => {
nav.goBack();
await delay(350);
openСonfirmRenewAllDomains();
}, [domains]);

const scrollHandler = useAnimatedScrollHandler({
onScroll: (event) => {
scrollTop.value = event.contentOffset.y;
},
});

return (
<View style={styles.container}>
<NavBar
hideBackButton
isClosedButton
isModal
scrollTop={scrollTop}
titleProps={{ numberOfLines: 1 }}
>
{t('expiring_domains')}
</NavBar>
<Animated.ScrollView
alwaysBounceVertical={false}
showsVerticalScrollIndicator={false}
keyboardShouldPersistTaps="handled"
keyboardDismissMode="none"
ref={scrollRef}
contentContainerStyle={{
paddingHorizontal: ns(16),
paddingBottom: safeArea.bottom,
}}
onScroll={scrollHandler}
scrollEventThrottle={16}
>
<List indent={false}>
{domains.map((domain) => (
<ExpiringListItem key={domain.name} domain={domain} onRenew={handleRenew} />
))}
</List>
<BottomButtonWrapHelper safeArea={false} />
</Animated.ScrollView>
<BottomButtonWrap>
<Button onPress={handleRenewAll}>
{t('dns_renew_all_until_btn', {
untilDate: format(+new Date() + ONE_YEAR_MILISEC, 'dd MMM yyyy', {
locale: getLocale(),
}),
})}
</Button>
</BottomButtonWrap>
</View>
);
});

const ExpiringListItem = memo(
(props: { domain: ExpiringDomainItem; onRenew: () => void }) => {
const { domain } = props;
const countOfDays = getCountOfDays(+new Date(), domain.expiring_at * 1000);
const days = countOfDays === 366 ? countOfDays - 1 : countOfDays;

const handlePress = useCallback(() => {
openNFT({
address: Ton.formatAddress(domain.dns_item.address),
currency: CryptoCurrencies.Ton,
});
}, [domain.dns_item.address]);

return (
<List.Item
onPress={handlePress}
key={domain.name}
title={domain.name}
chevron
subtitle={
<SText
color={days <= 30 ? 'accentNegative' : 'textSecondary'}
variant="body2"
numberOfLines={1}
>
{t('dns_renew_valid_caption', { count: days })}
</SText>
}
/>
);
},
);

export function openRenewAllDomainModal() {
navigate('RenewAllDomains');
}

const styles = StyleSheet.create({
container: {
flex: 1,
},
});
Loading

0 comments on commit a17700f

Please sign in to comment.