Skip to content

Commit

Permalink
Merge pull request #115 from unicornultrafoundation/v1.31
Browse files Browse the repository at this point in the history
v1.31
  • Loading branch information
phongnhat19 authored Jul 10, 2024
2 parents 3c02c36 + 1637ffb commit 44a86ca
Show file tree
Hide file tree
Showing 39 changed files with 999 additions and 62 deletions.
13 changes: 6 additions & 7 deletions App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import { useTracking } from './src/hook/useTracking';
import MainTabNav from './src/stack/MainTab';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { useCrashlytics } from './src/hook/useCrashlytics';
import { useNotifications } from './src/hook/useNotifications';
import ToastComponent from './src/component/Toast';

//@ts-ignore
Expand Down Expand Up @@ -75,14 +74,15 @@ function buildDeepLinkFromNotificationData(data: any): string | null {
}
if (navigationId === 'external-sign') {
const signRequestID = data?.signRequestId
console.log('here ', `u2umobilewallet://wallet/external-sign/${signRequestID}`)
return `u2umobilewallet://wallet/external-sign/${signRequestID}`;
}
// if (navigationId === 'home') {
// return 'u2umobilewallet://home';
// }
if (navigationId === 'discover') {
return 'u2umobilewallet://discover-dashboard';
const newsId = data?.newsId
if (newsId) return `u2umobilewallet://discover/detail/${newsId}`
return 'u2umobilewallet://discover/dashboard';
}
const url = data?.url;
if (typeof url === 'string') {
Expand Down Expand Up @@ -110,7 +110,8 @@ const linking = {
},
DiscoverStack: {
screens: {
Home: 'discover-dashboard'
Home: 'discover/dashboard',
NewsDetails: 'discover/detail/:id'
}
}
}
Expand Down Expand Up @@ -154,10 +155,8 @@ function App(): JSX.Element {
const {unlocked} = useGlobalStore()
const { type, isConnected } = useNetInfo();
const {darkMode: isDarkMode, language} = usePreferenceStore()
const preferenceTheme = isDarkMode ? darkTheme : lightTheme
const {t} = useTranslation()

const {blockExplorer, chainId} = useNetwork()
const {chainId} = useNetwork()
const networkStore = useNetworkStore()

const routeNameRef = React.useRef<string>();
Expand Down
2 changes: 1 addition & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ android {
applicationId "com.u2umobilewallet"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 52
versionCode 57
versionName "1.31"
missingDimensionStrategy 'react-native-camera', 'general'
}
Expand Down
4 changes: 2 additions & 2 deletions ios/U2UMobileWallet.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@
CODE_SIGN_ENTITLEMENTS = U2UMobileWallet/U2UMobileWalletDebug.entitlements;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 109;
CURRENT_PROJECT_VERSION = 113;
DEVELOPMENT_TEAM = 668U627Y5V;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 668U627Y5V;
ENABLE_BITCODE = NO;
Expand Down Expand Up @@ -654,7 +654,7 @@
CODE_SIGN_IDENTITY = "Apple Distribution";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 109;
CURRENT_PROJECT_VERSION = 113;
DEVELOPMENT_TEAM = 668U627Y5V;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 668U627Y5V;
INFOPLIST_FILE = U2UMobileWallet/Info.plist;
Expand Down
2 changes: 1 addition & 1 deletion ios/U2UMobileWallet/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>109</string>
<string>113</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
Expand Down
2 changes: 1 addition & 1 deletion ios/U2UMobileWalletTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>109</string>
<string>113</string>
</dict>
</plist>
Binary file added src/asset/images/empty_icon_illus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 45 additions & 12 deletions src/component/Icon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,39 +182,39 @@ const Icon = ({name, width, height, color, style}: {
return (
<View style={[{width: width, height: height, aspectRatio: 1}, style]}>
<Svg width="100%" height="100%" viewBox="0 0 25 24" fill="none">
<Path d="M12.2256 4.25L12.2256 19.25" stroke="#272727" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M6.20124 10.2998L12.2252 4.2498L18.2502 10.2998" stroke="#272727" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M12.2256 4.25L12.2256 19.25" stroke={color || "#272727"} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M6.20124 10.2998L12.2252 4.2498L18.2502 10.2998" stroke={color || "#272727"} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
</Svg>
</View>
)
case 'arrow-down':
return (
<View style={[{width: width, height: height, aspectRatio: 1}, style]}>
<Svg width="100%" height="100%" viewBox="0 0 24 24" fill="none">
<Path d="M12.2744 19.75V4.75" stroke="#272727" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M18.2988 13.7002L12.2748 19.7502L6.24976 13.7002" stroke="#272727" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M12.2744 19.75V4.75" stroke={color || "#272727"} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M18.2988 13.7002L12.2748 19.7502L6.24976 13.7002" stroke={color || "#272727"} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
</Svg>
</View>
)
case 'swap':
return (
<View style={[{width: width, height: height, aspectRatio: 1}, style]}>
<Svg width="100%" height="100%" viewBox="0 0 25 24" fill="none">
<Path d="M17.3395 20.1642V6.54639" stroke="#272727" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M21.4173 16.0681L17.3395 20.1648L13.2617 16.0681" stroke="#272727" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M7.41127 3.83276V17.4505" stroke="#272727" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M3.3335 7.92894L7.41127 3.83228L11.4891 7.92894" stroke="#272727" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M17.3395 20.1642V6.54639" stroke={color || "#272727"} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M21.4173 16.0681L17.3395 20.1648L13.2617 16.0681" stroke={color || "#272727"} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M7.41127 3.83276V17.4505" stroke={color || "#272727"} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M3.3335 7.92894L7.41127 3.83228L11.4891 7.92894" stroke={color || "#272727"} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
</Svg>
</View>
)
case 'paper':
return (
<View style={[{width: width, height: height, aspectRatio: 1}, style]}>
<Svg width="100%" height="100%" viewBox="0 0 25 24" fill="none">
<Path fillRule="evenodd" clipRule="evenodd" d="M15.2368 2.76196H8.58376C6.52476 2.76196 4.74976 4.43096 4.74976 6.49096V17.204C4.74976 19.38 6.40876 21.115 8.58376 21.115H16.5728C18.6328 21.115 20.3018 19.265 20.3018 17.204V8.03796L15.2368 2.76196Z" stroke="#272727" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M14.9741 2.75024V5.65924C14.9741 7.07924 16.1231 8.23124 17.5421 8.23424C18.8591 8.23724 20.2061 8.23824 20.2971 8.23224" stroke="#272727" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M14.784 15.5579H9.38696" stroke="#272727" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M12.7425 10.6057H9.38647" stroke="#272727" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path fillRule="evenodd" clipRule="evenodd" d="M15.2368 2.76196H8.58376C6.52476 2.76196 4.74976 4.43096 4.74976 6.49096V17.204C4.74976 19.38 6.40876 21.115 8.58376 21.115H16.5728C18.6328 21.115 20.3018 19.265 20.3018 17.204V8.03796L15.2368 2.76196Z" stroke={color || "#272727"} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M14.9741 2.75024V5.65924C14.9741 7.07924 16.1231 8.23124 17.5421 8.23424C18.8591 8.23724 20.2061 8.23824 20.2971 8.23224" stroke={color || "#272727"} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M14.784 15.5579H9.38696" stroke={color || "#272727"} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M12.7425 10.6057H9.38647" stroke={color || "#272727"} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
</Svg>
</View>
)
Expand Down Expand Up @@ -823,6 +823,39 @@ const Icon = ({name, width, height, color, style}: {
</Svg>
</View>
)
case 'double-check':
return (
<View style={[{width: width, height: height, aspectRatio: 1}, style]}>
<Svg width="100%" height="100%" viewBox="0 0 26 24" fill="none">
<Path d="M1.40002 12.2279L5.62792 16.4558L14.0987 8" stroke={color || "white"} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<Path d="M10.7014 12.2279L14.9293 16.4558L23.4 8" stroke={color || "white"} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
</Svg>
</View>
)
case 'menu':
return (
<View style={[{width: width, height: height, aspectRatio: 1}, style]}>
<Svg width="100%" height="100%" viewBox="0 0 24 24" fill="none">
<Path d="M3 7H21" stroke={color || "#8D8D8D"} strokeWidth="1.5" strokeLinecap="round"/>
<Path d="M9.48999 12H21" stroke={color || "#8D8D8D"} strokeWidth="1.5" strokeLinecap="round"/>
<Path d="M3 12H5.99" stroke={color || "#8D8D8D"} strokeWidth="1.5" strokeLinecap="round"/>
<Path d="M3 17H21" stroke={color || "#8D8D8D"} strokeWidth="1.5" strokeLinecap="round"/>
</Svg>
</View>
)
case 'experiment':
return (
<View style={[{width: width, height: height, aspectRatio: 1}, style]}>
<Svg
viewBox="0 0 1024 1024"
fill={color || "#FFFFFF"}
height="100%"
width="100%"
>
<Path d="M512 472a40 40 0 1080 0 40 40 0 10-80 0zm367 352.9L696.3 352V178H768v-68H256v68h71.7v174L145 824.9c-2.8 7.4-4.3 15.2-4.3 23.1 0 35.3 28.7 64 64 64h614.6c7.9 0 15.7-1.5 23.1-4.3 33-12.7 49.4-49.8 36.6-82.8zM395.7 364.7V180h232.6v184.7L719.2 600c-20.7-5.3-42.1-8-63.9-8-61.2 0-119.2 21.5-165.3 60a188.78 188.78 0 01-121.3 43.9c-32.7 0-64.1-8.3-91.8-23.7l118.8-307.5zM210.5 844l41.7-107.8c35.7 18.1 75.4 27.8 116.6 27.8 61.2 0 119.2-21.5 165.3-60 33.9-28.2 76.3-43.9 121.3-43.9 35 0 68.4 9.5 97.6 27.1L813.5 844h-603z" />
</Svg>
</View>
)
default:
return null
}
Expand Down
21 changes: 13 additions & 8 deletions src/component/Tab/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react'
import React, { ReactNode, useEffect, useState } from 'react'
import { StyleProp, TextStyle, TouchableOpacity, View, ViewStyle } from 'react-native';
import Text from '../Text'
import styles from './styles';
Expand All @@ -9,6 +9,7 @@ import theme from '../../theme';
interface TabTitle {
label: string;
value: string;
renderLabel?: (isActive: boolean) => ReactNode
}
interface TabProps {
selectedTab?: string;
Expand Down Expand Up @@ -58,13 +59,17 @@ const Tab = ({selectedTab, onChange, tabs, tabStyle, tabTextStyle, containerStyl
]}
onPress={() => onChange && onChange(tabItem.value)}
>
<Text
style={[
styles.tabTitle,
{color: isActive ? preferenceTheme.text.title : theme.color.neutral[500]},
{fontWeight: isActive ? '700' : '500'},
tabTextStyle
]}>{tabItem.label}</Text>
{tabItem.renderLabel ? tabItem.renderLabel(isActive) : (
<Text
style={[
styles.tabTitle,
{color: isActive ? theme.color.primary[500] : theme.color.neutral[500]},
{fontWeight: isActive ? '700' : '500'},
tabTextStyle
]}>
{tabItem.label}
</Text>
)}
</TouchableOpacity>
)
})}
Expand Down
4 changes: 3 additions & 1 deletion src/config/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ export const APP_LOCK_TIME = 30 * 60 * 1000 // 30 minutes
export const NEWS_CATEGORY_ENDPOINT = `https://u2u.xyz/api/v1/categories`
export const ALL_NEWS_ENDPOINT = `https://u2u.xyz/api/v1/blog`
export const NEWS_BY_CATEGORY_ENDPOINT = `https://u2u.xyz/api/v1/blog/categories/`
export const NEWS_DETAIL_ENDPOINT = `https://u2u.xyz/api/v1/blog/find/`
export const FEATURED_NEWS_ENDPOINT = `https://u2u.xyz/api/v1/feature`

export const APP_FLYERS_DEV_KEY = Config.APP_FLYERS_DEV_KEY
export const APP_FLYERS_IOS_APP_ID = Config.APP_FLYERS_IOS_APP_ID

export const APP_REMOTE_CONFIG = Config.APP_REMOTE_CONFIG

export const DAPP_PROMOTION_NOTIFICATION_TOPIC = 'dapp-promotion'
export const DAPP_PROMOTION_NOTIFICATION_TOPIC = 'dapp-promotion'
export const NEWS_NOTIFICATION_TOPIC = 'news'
5 changes: 4 additions & 1 deletion src/config/endpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ export const GET_WALLET_NICKNAME_ENDPOINT = '/wallets/'
export const FIND_WALLET_BY_NICKNAME = '/wallets/find-by-nickname/'
export const SUBMIT_CLAIM_REQUEST_ENDPOINT = '/membership-requests'
export const SUBMIT_CLAIM_JUPITER_REQUEST_ENDPOINT = '/jupiter-membership-requests'
export const FETCH_CLAIM_REQUEST_ENDPOINT = '/membership-requests/request-from-device-or-wallet'
export const FETCH_CLAIM_REQUEST_ENDPOINT = '/membership-requests/request-from-device-or-wallet'

export const ALL_NOTI_ENDPOINT = '/notifications/own-noti'
export const MARK_ALL_NOTI_READ_ENDPOINT = '/notifications/read-all'
37 changes: 37 additions & 0 deletions src/hook/useNewsDetail.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useQuery } from "@tanstack/react-query"
import { Article } from "./useNews"
import { fetchNewsDetail } from "../service/news"
import { formatDate } from "../util/date"
import { logErrorForMonitoring } from "./useCrashlytics"

export const useNewsDetail = (id: string) => {
const {data, isFetching} = useQuery<Article>({
queryKey: ['news-details', id],
queryFn: async () => {
try {
// const rs = await fetchFeaturedNews()
const rs = await fetchNewsDetail(id)
if (!rs.data) return {} as Article
const rawNews = rs.data
const dateUnixNumber = Number(rawNews.create_at)
return {
id: rawNews.news_id,
title: rawNews.news_title,
description: rawNews.meta_desc,
date: formatDate(new Date(dateUnixNumber * 1000), "MMMM dd, yyyy"),
category: rawNews.news_categories,
thumbnail: rawNews.news_avatar,
content: rawNews.news_description
}
} catch (error) {
logErrorForMonitoring(error as any, 'fetch news detail fail')
return {} as Article
}
},
})

return {
data,
isFetching
}
}
81 changes: 78 additions & 3 deletions src/hook/useNotifications.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
import { useInfiniteQuery } from "@tanstack/react-query"
import { useInfiniteQuery, useMutation, useQuery } from "@tanstack/react-query"
import messaging from '@react-native-firebase/messaging';
import { useEffect } from "react"
import { Platform } from "react-native"
import { requestUserPermissionIOS, requestPermissionAndroid } from "../util/notification";
import { useNavigation } from "@react-navigation/native";
import { useWallet } from "./useWallet";
import { fetchAllNoti, markAllNotiRead } from "../service/notifications";
import { useNetwork } from "./useNetwork";

export interface Notifications {
title: string;
description: string;
notificationData: Record<string, any>;
type: string;
read: boolean;
createdAt: Date;
updatedAt: Date;
}

export const useNotifications = () => {
export const useNotifications = (status = 'all') => {
const {networkConfig} = useNetwork()
const {wallet, getAuthObj} = useWallet()
const navigation = useNavigation<any>()
useEffect(() => {
if (Platform.OS === 'ios') requestUserPermissionIOS()
Expand All @@ -24,7 +38,68 @@ export const useNotifications = () => {
return unsubscribe;
}, [])

const {data: notifications, fetchNextPage, isFetching, refetch} = useInfiniteQuery({
queryKey: ['notification', wallet.address, networkConfig?.api_endpoint, status],
queryFn: async ({pageParam = 1}): Promise<Notifications[]> => {
if (!networkConfig) return []
const authHeaders = await getAuthObj()
const rs = await fetchAllNoti(
networkConfig?.api_endpoint,
{
page: pageParam,
limit: 10,
authObj: authHeaders,
status
}
)
return rs.data.map((i: Record<string, any>) => {
i.createdAt = new Date(i.createdAt)
i.updatedAt = new Date(i.updatedAt)
return i
}) || []
},
getNextPageParam: (lastPage, pages) => {
const nextPageParam = lastPage.length === 0 ? undefined : pages.length + 1
return nextPageParam
},
refetchInterval: 5000
})

const {data: countUnread} = useQuery({
queryKey: ['count-unread', wallet.address, networkConfig?.api_endpoint],
queryFn: async () => {
if (!networkConfig) return 0
const authHeaders = await getAuthObj()
const rs = await fetchAllNoti(
networkConfig?.api_endpoint,
{
page: 1,
limit: 10,
authObj: authHeaders,
status: 'unread'
}
)
return rs.count
},
refetchInterval: 60000,
refetchOnWindowFocus: true
})

const {mutateAsync} = useMutation({
mutationKey: ['mark-noti-read', wallet.address, networkConfig?.api_endpoint],
mutationFn: async () => {
if (!networkConfig) return
const authHeaders = await getAuthObj()
return markAllNotiRead(networkConfig.api_endpoint, authHeaders)
}
})

return {

notifications,
fetchNextPage,
isFetching,
countUnread,
refetchNoti: refetch,
markAsRead: mutateAsync
}
}
Loading

0 comments on commit 44a86ca

Please sign in to comment.