Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/mobile/src/app/componentUI/MezonButton/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useTheme } from '@mezon/mobile-ui';
import { memo, useMemo } from 'react';
import { Pressable, StyleProp, Text, TextStyle, ViewStyle } from 'react-native';
import { testProperties } from '../../configs/testProperties';
import { style } from './styles';

export enum EMezonButtonTheme {
Expand Down Expand Up @@ -83,6 +84,7 @@ const MezonButton = ({
]}
disabled={disabled}
onPress={onPress}
{...testProperties('mezonButton')}
>
{icon}
{title && <Text style={[styles.title, titleStyle]}>{title}</Text>}
Expand Down
11 changes: 8 additions & 3 deletions apps/mobile/src/app/componentUI/MezonButtonIcon/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useTheme } from '@mezon/mobile-ui';
import { Text, View } from 'react-native';
import { Pressable } from 'react-native-gesture-handler';
import { testProperties } from '../../configs/testProperties';
import { style } from './styles';

interface IMezonButtonIconProps {
Expand All @@ -12,9 +13,13 @@ interface IMezonButtonIconProps {
export default function MezonButtonIcon({ title, icon, onPress }: IMezonButtonIconProps) {
const styles = style(useTheme().themeValue);
return (
<Pressable onPress={onPress} style={styles.container}>
<View style={styles.iconWrapper}>{icon}</View>
<Text style={styles.title}>{title}</Text>
<Pressable onPress={onPress} style={styles.container} {...testProperties('mezonButtonIcon.container')}>
<View style={styles.iconWrapper} {...testProperties('mezonButtonIcon.iconWrapper')}>
{icon}
</View>
<Text style={styles.title} {...testProperties('mezonButtonIcon.title')}>
{title}
</Text>
</Pressable>
);
}
6 changes: 5 additions & 1 deletion apps/mobile/src/app/componentUI/MezonClanAvatar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { StyleProp, Text, TextStyle, View } from 'react-native';
import FastImage from 'react-native-fast-image';
import Images from '../../../assets/Images';
import ImageNative from '../../components/ImageNative';
import { testProperties } from '../../configs/testProperties';
import { IconCDN } from '../../constants/icon_cdn';
import { style } from './styles';

Expand Down Expand Up @@ -53,7 +54,10 @@ export default memo(function MezonClanAvatar({
);
}
return (
<View style={[styles.fakeBox, { backgroundColor: defaultColor || themeValue.colorAvatarDefault }]}>
<View
style={[styles.fakeBox, { backgroundColor: defaultColor || themeValue.colorAvatarDefault }]}
{...testProperties('mezonClanAvatar.fakeBox')}
>
{!noDefaultText ? (
<FastImage source={alt === 'Anonymous' ? IconCDN.anonymousAvatar : Images.ANONYMOUS_AVATAR} style={styles.defaultImageStyle} />
) : null}
Expand Down
13 changes: 10 additions & 3 deletions apps/mobile/src/app/componentUI/MezonConfirm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useTheme } from '@mezon/mobile-ui';
import type { ReactNode } from 'react';
import { useTranslation } from 'react-i18next';
import { DeviceEventEmitter, Text, TouchableOpacity, View } from 'react-native';
import { testProperties } from '../../configs/testProperties';
import useTabletLandscape from '../../hooks/useTabletLandscape';
import { style } from './styles';

Expand Down Expand Up @@ -34,16 +35,22 @@ export default function MezonConfirm({ children, title, confirmText, content, is
<View style={styles.main}>
<View style={styles.container}>
<View style={styles.header}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.title} {...testProperties('confirm.title')}>
{title}
</Text>
</View>

{children ? children : <Text style={styles.contentText}>{content || ''}</Text>}

<View style={styles.btnWrapper}>
<TouchableOpacity style={[styles.btn, styles.btnDefault, isDanger && styles.btnDanger]} onPress={() => handleConfirm()}>
<TouchableOpacity
style={[styles.btn, styles.btnDefault, isDanger && styles.btnDanger]}
onPress={() => handleConfirm()}
{...testProperties('confirm.button')}
>
<Text style={[styles.btnText, styles.btnTextWhite]}>{confirmText}</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.btn} onPress={() => handleClose()}>
<TouchableOpacity style={styles.btn} onPress={() => handleClose()} {...testProperties('confirm.button.cancel')}>
<Text style={styles.btnText}>{t('buzz.cancel')}</Text>
</TouchableOpacity>
</View>
Expand Down
10 changes: 8 additions & 2 deletions apps/mobile/src/app/componentUI/MezonInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useEffect, useRef, useState } from 'react';
import type { KeyboardType, StyleProp, TextStyle, ViewStyle } from 'react-native';
import { Text, TextInput, TouchableOpacity, View } from 'react-native';
import { ErrorInput } from '../../components/ErrorInput';
import { testProperties } from '../../configs/testProperties';
import { IconCDN } from '../../constants/icon_cdn';
import { validInput } from '../../utils/validate';
import MezonIconCDN from '../MezonIconCDN';
Expand Down Expand Up @@ -111,7 +112,11 @@ export default function MezonInput({

return (
<View style={styles.container}>
{label && <Text style={[styles.label, titleUppercase ? styles.titleUppercase : {}, titleStyle]}>{label}</Text>}
{label && (
<Text style={[styles.label, titleUppercase ? styles.titleUppercase : {}, titleStyle]} {...testProperties('mezonInput.label')}>
{label}
</Text>
)}
<View style={[styles.fakeInput, textarea && { paddingTop: 10 }, renderBorder(), inputWrapperStyle]}>
<View style={styles.inputBox}>
{prefixIcon}
Expand All @@ -132,11 +137,12 @@ export default function MezonInput({
editable={!disabled}
defaultValue={defaultValue}
keyboardType={keyboardType}
{...testProperties('mezonInput.input')}
/>
{postfixIcon}

{!textarea && value?.length > 0 && !disabled && (
<TouchableOpacity onPress={handleClearBtn} style={styles.clearBtn}>
<TouchableOpacity onPress={handleClearBtn} style={styles.clearBtn} {...testProperties('mezonInput.clearBtn')}>
<MezonIconCDN icon={IconCDN.circleXIcon} height={size.s_18} width={size.s_18} color={themeValue.white} />
</TouchableOpacity>
)}
Expand Down
12 changes: 10 additions & 2 deletions apps/mobile/src/app/components/FriendItem/FriendItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import React, { useMemo } from 'react';
import { Pressable, Text, TouchableOpacity, View } from 'react-native';
import BouncyCheckbox from 'react-native-bouncy-checkbox/build/dist/BouncyCheckbox';
import MezonIconCDN from '../../componentUI/MezonIconCDN';
import { testProperties } from '../../configs/testProperties';
import { IconCDN } from '../../constants/icon_cdn';
import ImageNative from '../ImageNative';
import { UserStatus } from '../UserStatus';
Expand Down Expand Up @@ -105,11 +106,18 @@ export const FriendItem = React.memo(

{isPendingFriendRequest && showAction && !selectMode ? (
<View style={styles.friendAction}>
<Pressable onPress={() => onPressAction(EFriendItemAction.Delete)}>
<Pressable
onPress={() => onPressAction(EFriendItemAction.Delete)}
{...testProperties(`friend.button.deleteFriend.${friend.user.username}`)}
>
<MezonIconCDN icon={IconCDN.closeIcon} width={18} height={18} color={'#c7c7c7'} />
</Pressable>
{!isSentRequestFriend ? (
<Pressable onPress={() => onPressAction(EFriendItemAction.Approve)} style={styles.approveIcon}>
<Pressable
onPress={() => onPressAction(EFriendItemAction.Approve)}
style={styles.approveIcon}
{...testProperties(`friend.button.approveFriend`)}
>
<MezonIconCDN icon={IconCDN.checkmarkSmallIcon} width={25} height={18} color={'white'} />
</Pressable>
) : null}
Expand Down
12 changes: 12 additions & 0 deletions apps/mobile/src/app/configs/testProperties.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Platform } from 'react-native';

export const IS_IOS = Platform.OS === 'ios';

function testProperties(id: string, disableAccessible = false): { accessible?: boolean; accessibilityLabel?: string; testID?: string } {
const disableAccessibility = disableAccessible ? { accessible: false } : {};

if (IS_IOS) return { ...disableAccessibility, testID: id };
return { ...disableAccessibility, accessibilityLabel: id };
}

export { testProperties };
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { createStackNavigator } from '@react-navigation/stack';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Platform, Pressable, Text } from 'react-native';
import { testProperties } from '../../../configs/testProperties';
import { FriendScreen } from '../../../screens/friend';
import { AddFriendScreen } from '../../../screens/friend/AddFriend';
import { RequestFriendScreen } from '../../../screens/friend/RequestFriend';
Expand All @@ -13,7 +14,11 @@ import { styles } from './styles';
const AddFriendButton = ({ navigation }: { navigation: any }) => {
const { t } = useTranslation(['screen']);
return (
<Pressable onPress={() => navigation.navigate(APP_SCREEN.FRIENDS.STACK, { screen: APP_SCREEN.FRIENDS.ADD_FRIEND })} style={styles.addFriendButton}>
<Pressable
onPress={() => navigation.navigate(APP_SCREEN.FRIENDS.STACK, { screen: APP_SCREEN.FRIENDS.ADD_FRIEND })}
style={styles.addFriendButton}
{...testProperties('friend.button.addFriends')}
>
<Text style={styles.addFriendText}>{t('headerRight.addFriends')}</Text>
</Pressable>
);
Expand Down
3 changes: 2 additions & 1 deletion apps/mobile/src/app/screens/auth/Login/WelcomeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import LinearGradient from 'react-native-linear-gradient';
import { APP_SCREEN } from '../../../navigation/ScreenTypes';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
import { testProperties } from '../../../configs/testProperties';
import FEATURE_BG from './featureBg.png';
import { style } from './styles';

Expand All @@ -25,7 +26,7 @@ const WelcomeScreen = ({ navigation }) => {
<Text style={styles.subtitle}>{t('login.desWelcomeToMezon')}</Text>
<FastImage source={FEATURE_BG} style={styles.welcomeImage} resizeMode={FastImage.resizeMode.contain} />
</View>
<TouchableOpacity style={[styles.otpButton, styles.welcomeButton]} onPress={() => onGetStarted()}>
<TouchableOpacity style={[styles.otpButton, styles.welcomeButton]} onPress={() => onGetStarted()} {...testProperties('started.button')}>
<Text style={[styles.otpButtonText]}>{t('login.getStarted')}</Text>
<LinearGradient start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} colors={['#501794', '#3E70A1']} style={[StyleSheet.absoluteFillObject]} />
</TouchableOpacity>
Expand Down
15 changes: 13 additions & 2 deletions apps/mobile/src/app/screens/auth/Login/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import LinearGradient from 'react-native-linear-gradient';
import Toast from 'react-native-toast-message';
import MezonIconCDN from '../../../componentUI/MezonIconCDN';
import { ErrorInput } from '../../../components/ErrorInput';
import { testProperties } from '../../../configs/testProperties';
import { IconCDN } from '../../../constants/icon_cdn';
import useTabletLandscape from '../../../hooks/useTabletLandscape';
import { APP_SCREEN } from '../../../navigation/ScreenTypes';
Expand Down Expand Up @@ -380,6 +381,7 @@ const LoginScreen = ({ navigation }) => {
autoFocus={true}
onSubmitEditing={handlePrimaryAction}
underlineColorAndroid="transparent"
{...testProperties('login.phone.input')}
/>
</View>
<CountryDropdown
Expand Down Expand Up @@ -409,6 +411,7 @@ const LoginScreen = ({ navigation }) => {
autoFocus={true}
onSubmitEditing={handlePrimaryAction}
underlineColorAndroid="transparent"
{...testProperties('login.email.input')}
/>
)}
</View>
Expand All @@ -434,6 +437,7 @@ const LoginScreen = ({ navigation }) => {
autoCapitalize="none"
autoCorrect={false}
onSubmitEditing={handlePrimaryAction}
{...testProperties('login.password.input')}
/>
</View>
<TouchableOpacity style={styles.showPasswordContainer} onPress={togglePasswordVisibility}>
Expand All @@ -458,6 +462,7 @@ const LoginScreen = ({ navigation }) => {
style={[styles.otpButton, !isFormValid && styles.otpButtonDisabled]}
onPress={handlePrimaryAction}
disabled={!isFormValid || isLoading}
{...testProperties('login.primary.button')}
>
{isLoading ? (
<ActivityIndicator size="small" color="#FFFFFF" style={styles.loading} />
Expand Down Expand Up @@ -485,10 +490,16 @@ const LoginScreen = ({ navigation }) => {
: t('login.passwordNotSet')}
</Text>
<View style={styles.alternativeOptions}>
<TouchableOpacity onPress={loginMode === 'otp' ? () => handleSMSLogin() : () => switchToOTPMode()}>
<TouchableOpacity
onPress={loginMode === 'otp' ? () => handleSMSLogin() : () => switchToOTPMode()}
{...testProperties('login.switch.SMS')}
>
<Text style={styles.linkText}>{loginMode === 'otp' ? t('login.loginWithSMS') : t('login.loginWithEmailOTP')}</Text>
</TouchableOpacity>
<TouchableOpacity onPress={loginMode !== 'password' ? switchToPasswordMode : handleSMSLogin}>
<TouchableOpacity
onPress={loginMode !== 'password' ? switchToPasswordMode : handleSMSLogin}
{...testProperties('login.switch.password')}
>
<Text style={styles.linkText}>
{loginMode !== 'password' ? t('login.loginWithPassword') : t('login.loginWithSMS')}
</Text>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ import { DeviceEventEmitter, Platform, Pressable, StatusBar, Text, TextInput, Vi
import { KeyboardAvoidingView } from 'react-native-keyboard-controller';
import Toast from 'react-native-toast-message';
import { useDispatch, useSelector } from 'react-redux';
import StatusBarHeight from '../../../../../components/StatusBarHeight/StatusBarHeight';
import MezonButton from '../../../../../componentUI/MezonButton';
import MezonIconCDN from '../../../../../componentUI/MezonIconCDN';
import StatusBarHeight from '../../../../../components/StatusBarHeight/StatusBarHeight';
import { testProperties } from '../../../../../configs/testProperties';
import { IconCDN } from '../../../../../constants/icon_cdn';
import { style } from './styles';

Expand Down Expand Up @@ -149,6 +150,7 @@ export const AddFriendModal = React.memo(() => {
style={styles.searchInput}
onChangeText={handleTextChange}
autoCapitalize="none"
{...testProperties('addFriend.input.username')}
/>
</View>
<View style={styles.byTheWayText}>
Expand Down
3 changes: 2 additions & 1 deletion apps/mobile/src/app/screens/friend/AddFriend/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { DeviceEventEmitter, FlatList, Text, TouchableOpacity, View } from 'reac
import { SeparatorWithLine } from '../../../components/Common';
import { EFriendItemAction, FriendItem } from '../../../components/FriendItem';
import { UserInformationBottomSheet } from '../../../components/UserInformationBottomSheet';
import { testProperties } from '../../../configs/testProperties';
import { EFriendRequest } from '../RequestFriend';
import { EmptyFriendRequest } from '../RequestFriend/EmptyFriendRequest';
import { AddFriendModal } from './components/AddFriendModal';
Expand Down Expand Up @@ -61,7 +62,7 @@ export const AddFriendScreen = () => {
return (
<View style={styles.addFriendContainer}>
<View style={styles.groupWrapper}>
<TouchableOpacity onPress={onOpenAddFriendModal} style={styles.addFriendItem}>
<TouchableOpacity onPress={onOpenAddFriendModal} style={styles.addFriendItem} {...testProperties('addFriend.button')}>
<Text style={styles.addFriendText}>{t('addFriend.addByUserName')}</Text>
</TouchableOpacity>
</View>
Expand Down
12 changes: 9 additions & 3 deletions apps/mobile/src/app/screens/friend/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import MezonIconCDN from '../../componentUI/MezonIconCDN';
import { EFriendItemAction } from '../../components/FriendItem';
import { FriendListByAlphabet } from '../../components/FriendListByAlphabet';
import { UserInformationBottomSheet } from '../../components/UserInformationBottomSheet';
import { testProperties } from '../../configs/testProperties';
import { IconCDN } from '../../constants/icon_cdn';
import { APP_SCREEN } from '../../navigation/ScreenTypes';
import { normalizeString } from '../../utils/helpers';
Expand Down Expand Up @@ -164,6 +165,7 @@ export const FriendScreen = React.memo(({ navigation }: { navigation: any }) =>
placeholderTextColor={themeValue.textDisabled}
style={styles.searchInput}
onChangeText={(text) => typingSearchDebounce(text)}
{...testProperties('friend.input.search')}
/>
</View>

Expand All @@ -174,16 +176,20 @@ export const FriendScreen = React.memo(({ navigation }: { navigation: any }) =>
) : null}

{!searchText?.trim()?.length || filteredFriendList?.length === 0 ? (
<Pressable style={styles.requestFriendWrapper} onPress={() => navigateToRequestFriendScreen()}>
<Pressable
style={styles.requestFriendWrapper}
onPress={() => navigateToRequestFriendScreen()}
{...testProperties('friend.button.requestFriend')}
>
<MezonIconCDN icon={IconCDN.paperPlaneIcon} width={25} color={themeValue.text} />
<View style={styles.fill}>
<Text style={styles.defaultText}>{t('friends:friendRequest.title')}</Text>
<View style={styles.requestContentWrapper}>
<Text style={styles.defaultText}>
<Text style={styles.defaultText} {...testProperties('friend.text.requestReceived')}>
{friendRequestCount.received} {t('friends:friendRequest.received')}
</Text>
<Text style={styles.defaultText}>•</Text>
<Text style={styles.defaultText}>
<Text style={styles.defaultText} {...testProperties('friend.text.requestSent')}>
{friendRequestCount.sent} {t('friends:friendRequest.sent')}
</Text>
</View>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { size, useTheme } from '@mezon/mobile-ui';
import { channelsActions, checkDuplicateNameClan, clansActions, getStoreAsync } from '@mezon/store-mobile';
import { handleUploadFileMobile, useMezon } from '@mezon/transport';
import { MAX_FILE_SIZE_1MB } from '@mezon/utils';
import { testProperties } from 'apps/mobile/src/app/configs/testProperties';
import React, { memo, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { DeviceEventEmitter, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
Expand Down Expand Up @@ -134,14 +135,14 @@ const CreateClanModal = memo(() => {
/>

<View style={styles.headerContainer}>
<TouchableOpacity style={styles.backButton} onPress={onClose} activeOpacity={0.7}>
<TouchableOpacity style={styles.backButton} onPress={onClose} activeOpacity={0.7} {...testProperties('createClanModal.closeButton')}>
<MezonIconCDN icon={IconCDN.closeIcon} color={themeValue.text} width={size.s_30} height={size.s_30} />
</TouchableOpacity>
<Text style={[styles.title, { color: themeValue.text }]}>{t('title')}</Text>
<Text style={[styles.description, { color: themeValue.textDisabled }]}>{t('subTitle')}</Text>
</View>
<View style={styles.boxImage}>
<TouchableOpacity style={styles.uploadImage} onPress={onOpen}>
<TouchableOpacity style={styles.uploadImage} onPress={onOpen} {...testProperties('createClanModal.uploadImageButton')}>
{!urlImage ? (
<View style={[styles.uploadCreateClan]}>
<MezonIconCDN
Expand Down
Loading