@umituz/react-native-settings 5.3.62 → 5.3.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/domains/appearance/presentation/components/ThemeOption.tsx +0 -27
- package/src/infrastructure/utils/configFactory.ts +1 -1
- package/src/presentation/components/SettingsItemCard.tsx +1 -1
- package/src/presentation/components/settings/SettingsItemCardContent.tsx +6 -4
- package/src/presentation/hooks/useSettingsScreenConfig.ts +53 -41
- package/src/presentation/utils/config-creators/base-configs.ts +0 -5
- package/src/presentation/utils/config-creators/feature-configs.ts +0 -1
- package/src/presentation/utils/config-creators/support-configs.ts +0 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-settings",
|
|
3
|
-
"version": "5.3.
|
|
3
|
+
"version": "5.3.63",
|
|
4
4
|
"description": "Complete settings hub for React Native apps - consolidated package with settings, localization, about, legal, appearance, feedback, FAQs, rating, and gamification - expo-store-review and expo-device now lazy loaded",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -25,13 +25,6 @@ interface ThemeOptionProps {
|
|
|
25
25
|
// Valid theme modes for validation
|
|
26
26
|
const VALID_THEME_MODES: readonly ThemeMode[] = ["light", "dark", "auto"];
|
|
27
27
|
|
|
28
|
-
// Icon names mapping for type safety
|
|
29
|
-
const THEME_ICONS: Record<ThemeMode, string> = {
|
|
30
|
-
light: "sunny-outline",
|
|
31
|
-
dark: "moon-outline",
|
|
32
|
-
auto: "desktop-outline",
|
|
33
|
-
};
|
|
34
|
-
|
|
35
28
|
// Utility function to add opacity to hex color
|
|
36
29
|
const addOpacityToHex = (hexColor: string, opacity: string): string => {
|
|
37
30
|
// Remove # if present
|
|
@@ -54,14 +47,6 @@ export const ThemeOption: React.FC<ThemeOptionProps> = React.memo(({
|
|
|
54
47
|
// Memoize styles to prevent unnecessary re-creation
|
|
55
48
|
const styles = useMemo(() => getStyles(tokens), [tokens]);
|
|
56
49
|
|
|
57
|
-
// Type-safe icon name selection with validation
|
|
58
|
-
const iconName: string = useMemo(() => {
|
|
59
|
-
if (VALID_THEME_MODES.includes(mode)) {
|
|
60
|
-
return THEME_ICONS[mode];
|
|
61
|
-
}
|
|
62
|
-
// Fallback for invalid mode
|
|
63
|
-
return THEME_ICONS.auto;
|
|
64
|
-
}, [mode]);
|
|
65
50
|
|
|
66
51
|
return (
|
|
67
52
|
<TouchableOpacity
|
|
@@ -72,9 +57,6 @@ export const ThemeOption: React.FC<ThemeOptionProps> = React.memo(({
|
|
|
72
57
|
accessibilityState={{ selected: isSelected }}
|
|
73
58
|
>
|
|
74
59
|
<View style={styles.header}>
|
|
75
|
-
<View style={styles.iconContainer}>
|
|
76
|
-
<AtomicIcon name={iconName} customSize={24} customColor={tokens.colors.primary} />
|
|
77
|
-
</View>
|
|
78
60
|
<View style={styles.textContainer}>
|
|
79
61
|
<AtomicText type="titleLarge" color="primary">
|
|
80
62
|
{title}
|
|
@@ -149,15 +131,6 @@ const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>) =>
|
|
|
149
131
|
alignItems: "center",
|
|
150
132
|
marginBottom: 12,
|
|
151
133
|
},
|
|
152
|
-
iconContainer: {
|
|
153
|
-
width: 48,
|
|
154
|
-
height: 48,
|
|
155
|
-
borderRadius: 24,
|
|
156
|
-
backgroundColor: addOpacityToHex(tokens.colors.primary, "15"),
|
|
157
|
-
justifyContent: "center",
|
|
158
|
-
alignItems: "center",
|
|
159
|
-
marginRight: 12,
|
|
160
|
-
},
|
|
161
134
|
textContainer: {
|
|
162
135
|
flex: 1,
|
|
163
136
|
},
|
|
@@ -12,7 +12,7 @@ import { SettingsItemCardSection } from "./settings/SettingsItemCardSection";
|
|
|
12
12
|
export interface SettingsItemCardProps {
|
|
13
13
|
title: string;
|
|
14
14
|
description?: string;
|
|
15
|
-
icon
|
|
15
|
+
icon?: IconName;
|
|
16
16
|
onPress?: () => void;
|
|
17
17
|
containerStyle?: StyleProp<ViewStyle>;
|
|
18
18
|
sectionTitle?: string;
|
|
@@ -4,7 +4,7 @@ import { AtomicIcon, AtomicText, type IconName } from "@umituz/react-native-desi
|
|
|
4
4
|
import { useAppDesignTokens } from "@umituz/react-native-design-system/theme";
|
|
5
5
|
|
|
6
6
|
export interface SettingsItemCardContentProps {
|
|
7
|
-
icon
|
|
7
|
+
icon?: IconName;
|
|
8
8
|
title: string;
|
|
9
9
|
description?: string;
|
|
10
10
|
iconBgColor: string;
|
|
@@ -26,9 +26,11 @@ export const SettingsItemCardContent: React.FC<SettingsItemCardContentProps> = R
|
|
|
26
26
|
|
|
27
27
|
return (
|
|
28
28
|
<View style={styles.content}>
|
|
29
|
-
|
|
30
|
-
<
|
|
31
|
-
|
|
29
|
+
{!!icon && (
|
|
30
|
+
<View style={[styles.iconContainer, { backgroundColor: iconBgColor, borderRadius: tokens.borders.radius.md }]}>
|
|
31
|
+
<AtomicIcon name={icon} size="lg" customColor={iconColor} />
|
|
32
|
+
</View>
|
|
33
|
+
)}
|
|
32
34
|
<View style={styles.textContainer}>
|
|
33
35
|
<AtomicText
|
|
34
36
|
type="bodyLarge"
|
|
@@ -35,6 +35,21 @@ export interface UseSettingsScreenConfigParams {
|
|
|
35
35
|
additionalScreens?: AdditionalScreen[];
|
|
36
36
|
features?: SettingsFeatures;
|
|
37
37
|
translations?: SettingsTranslations;
|
|
38
|
+
/** Optional auth data for apps that use authentication */
|
|
39
|
+
auth?: {
|
|
40
|
+
user: {
|
|
41
|
+
displayName?: string;
|
|
42
|
+
userId?: string;
|
|
43
|
+
photoURL?: string;
|
|
44
|
+
isAnonymous?: boolean;
|
|
45
|
+
} | null;
|
|
46
|
+
isLoading?: boolean;
|
|
47
|
+
isAuthReady?: boolean;
|
|
48
|
+
onSignIn: () => void;
|
|
49
|
+
onLogout: () => Promise<void>;
|
|
50
|
+
onDeleteAccount: () => Promise<void>;
|
|
51
|
+
accountTranslations?: AccountTranslations;
|
|
52
|
+
};
|
|
38
53
|
}
|
|
39
54
|
|
|
40
55
|
export interface SettingsScreenConfigResult {
|
|
@@ -49,7 +64,15 @@ export interface SettingsScreenConfigResult {
|
|
|
49
64
|
export const useSettingsScreenConfig = (
|
|
50
65
|
params: UseSettingsScreenConfigParams
|
|
51
66
|
): SettingsScreenConfigResult => {
|
|
52
|
-
const {
|
|
67
|
+
const {
|
|
68
|
+
appInfo,
|
|
69
|
+
faqData,
|
|
70
|
+
isPremium,
|
|
71
|
+
onFeedbackSubmit,
|
|
72
|
+
features = {},
|
|
73
|
+
translations,
|
|
74
|
+
auth
|
|
75
|
+
} = params;
|
|
53
76
|
|
|
54
77
|
const {
|
|
55
78
|
notifications: showNotifications = true,
|
|
@@ -65,26 +88,13 @@ export const useSettingsScreenConfig = (
|
|
|
65
88
|
subscription: showSubscription = true,
|
|
66
89
|
} = features;
|
|
67
90
|
|
|
68
|
-
//
|
|
69
|
-
const loading = false;
|
|
70
|
-
const isAuthReady = true;
|
|
91
|
+
// Auth orchestration
|
|
92
|
+
const loading = auth?.isLoading ?? false;
|
|
93
|
+
const isAuthReady = auth?.isAuthReady ?? true;
|
|
71
94
|
|
|
72
|
-
// Default handlers (no-ops for no-auth version)
|
|
73
95
|
const handleRatePress = useMemo(() => async () => {
|
|
74
|
-
// Default rate behavior -
|
|
75
|
-
console.
|
|
76
|
-
}, []);
|
|
77
|
-
|
|
78
|
-
const handleSignOut = useMemo(() => async () => {
|
|
79
|
-
// No-op in no-auth version
|
|
80
|
-
}, []);
|
|
81
|
-
|
|
82
|
-
const handleDeleteAccount = useMemo(() => async () => {
|
|
83
|
-
// No-op in no-auth version
|
|
84
|
-
}, []);
|
|
85
|
-
|
|
86
|
-
const handleSignIn = useMemo(() => async () => {
|
|
87
|
-
// No-op in no-auth version
|
|
96
|
+
// Default rate behavior - typically handled by app or a separate rating hook
|
|
97
|
+
console.log("[useSettingsScreenConfig] Rate pressed");
|
|
88
98
|
}, []);
|
|
89
99
|
|
|
90
100
|
// Use settings config factory
|
|
@@ -114,11 +124,11 @@ export const useSettingsScreenConfig = (
|
|
|
114
124
|
translations,
|
|
115
125
|
};
|
|
116
126
|
|
|
127
|
+
// Apply translations to specific features if available
|
|
117
128
|
if (config.subscription && typeof config.subscription === 'object') {
|
|
118
129
|
config.subscription = {
|
|
119
130
|
...config.subscription,
|
|
120
|
-
|
|
121
|
-
title: translations?.features?.subscription?.title || config.subscription.title || "Subscription",
|
|
131
|
+
title: translations?.features?.subscription?.title || config.subscription.title,
|
|
122
132
|
description: translations?.features?.subscription?.description || config.subscription.description,
|
|
123
133
|
};
|
|
124
134
|
}
|
|
@@ -127,8 +137,7 @@ export const useSettingsScreenConfig = (
|
|
|
127
137
|
const existingConfig = typeof config.gamification === 'object' ? config.gamification : { enabled: true };
|
|
128
138
|
config.gamification = {
|
|
129
139
|
...existingConfig,
|
|
130
|
-
|
|
131
|
-
title: translations?.features?.gamification?.title || existingConfig.title || "Your Progress",
|
|
140
|
+
title: translations?.features?.gamification?.title || existingConfig.title,
|
|
132
141
|
description: translations?.features?.gamification?.description || existingConfig.description,
|
|
133
142
|
};
|
|
134
143
|
}
|
|
@@ -137,8 +146,7 @@ export const useSettingsScreenConfig = (
|
|
|
137
146
|
const existingConfig = typeof config.videoTutorial === 'object' ? config.videoTutorial : { enabled: true };
|
|
138
147
|
config.videoTutorial = {
|
|
139
148
|
...existingConfig,
|
|
140
|
-
|
|
141
|
-
title: translations?.features?.videoTutorial?.title || existingConfig.title || "Video Tutorials",
|
|
149
|
+
title: translations?.features?.videoTutorial?.title || existingConfig.title,
|
|
142
150
|
description: translations?.features?.videoTutorial?.description || existingConfig.description,
|
|
143
151
|
};
|
|
144
152
|
}
|
|
@@ -146,24 +154,28 @@ export const useSettingsScreenConfig = (
|
|
|
146
154
|
return config;
|
|
147
155
|
}, [baseSettingsConfig, translations]);
|
|
148
156
|
|
|
149
|
-
//
|
|
157
|
+
// User profile display configuration
|
|
150
158
|
const userProfile = useMemo(() => createUserProfileDisplay({
|
|
151
|
-
profileData:
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
159
|
+
profileData: auth?.user ? {
|
|
160
|
+
displayName: auth.user.displayName,
|
|
161
|
+
userId: auth.user.userId,
|
|
162
|
+
isAnonymous: auth.user.isAnonymous,
|
|
163
|
+
avatarUrl: auth.user.photoURL,
|
|
164
|
+
} : null,
|
|
165
|
+
onSignIn: auth?.onSignIn || (() => {}),
|
|
166
|
+
}), [auth?.user, auth?.onSignIn]);
|
|
167
|
+
|
|
168
|
+
// Account screen configuration
|
|
156
169
|
const accountConfig = useMemo(() => createAccountConfig({
|
|
157
|
-
displayName:
|
|
158
|
-
userId:
|
|
159
|
-
photoURL:
|
|
160
|
-
isAnonymous:
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}), [handleSignIn, handleSignOut, handleDeleteAccount]);
|
|
170
|
+
displayName: auth?.user?.displayName,
|
|
171
|
+
userId: auth?.user?.userId,
|
|
172
|
+
photoURL: auth?.user?.photoURL,
|
|
173
|
+
isAnonymous: auth?.user?.isAnonymous,
|
|
174
|
+
onSignIn: auth?.onSignIn || (() => {}),
|
|
175
|
+
onLogout: auth?.onLogout || (async () => {}),
|
|
176
|
+
onDeleteAccount: auth?.onDeleteAccount || (async () => {}),
|
|
177
|
+
translations: auth?.accountTranslations,
|
|
178
|
+
}), [auth?.user, auth?.onSignIn, auth?.onLogout, auth?.onDeleteAccount, auth?.accountTranslations]);
|
|
167
179
|
|
|
168
180
|
return {
|
|
169
181
|
settingsConfig,
|
|
@@ -20,7 +20,6 @@ export const createAppearanceConfig = (
|
|
|
20
20
|
routeOrOnPress?: string | (() => void),
|
|
21
21
|
): AppearanceConfig => {
|
|
22
22
|
return createBaseConfig<AppearanceConfig>({
|
|
23
|
-
icon: "color-palette-outline",
|
|
24
23
|
routeOrOnPress,
|
|
25
24
|
});
|
|
26
25
|
};
|
|
@@ -32,7 +31,6 @@ export const createLanguageConfig = (
|
|
|
32
31
|
routeOrOnPress?: string | (() => void),
|
|
33
32
|
): LanguageConfig => {
|
|
34
33
|
return createBaseConfig<LanguageConfig>({
|
|
35
|
-
icon: "globe-outline",
|
|
36
34
|
routeOrOnPress,
|
|
37
35
|
});
|
|
38
36
|
};
|
|
@@ -45,7 +43,6 @@ export const createNotificationsConfig = (
|
|
|
45
43
|
): NotificationsConfig => {
|
|
46
44
|
return createConfigWithExtensions<NotificationsConfig>(
|
|
47
45
|
{
|
|
48
|
-
icon: "notifications-outline",
|
|
49
46
|
routeOrOnPress,
|
|
50
47
|
defaultRoute: "Notifications",
|
|
51
48
|
},
|
|
@@ -62,7 +59,6 @@ export const createAboutConfig = (
|
|
|
62
59
|
routeOrOnPress?: string | (() => void),
|
|
63
60
|
): AboutConfig => {
|
|
64
61
|
return createBaseConfig<AboutConfig>({
|
|
65
|
-
icon: "information-circle-outline",
|
|
66
62
|
routeOrOnPress,
|
|
67
63
|
});
|
|
68
64
|
};
|
|
@@ -74,7 +70,6 @@ export const createLegalConfig = (
|
|
|
74
70
|
routeOrOnPress?: string | (() => void),
|
|
75
71
|
): LegalConfig => {
|
|
76
72
|
return createBaseConfig<LegalConfig>({
|
|
77
|
-
icon: "document-text-outline",
|
|
78
73
|
routeOrOnPress,
|
|
79
74
|
});
|
|
80
75
|
};
|
|
@@ -21,7 +21,6 @@ export const createSubscriptionConfig = (
|
|
|
21
21
|
routeOrOnPress: keyof SettingsStackParamList | (() => void),
|
|
22
22
|
): SubscriptionConfig => ({
|
|
23
23
|
enabled: true,
|
|
24
|
-
icon: "diamond",
|
|
25
24
|
route: typeof routeOrOnPress === "function" ? undefined : routeOrOnPress,
|
|
26
25
|
onPress: typeof routeOrOnPress === "function" ? routeOrOnPress : undefined,
|
|
27
26
|
isPremium,
|
|
@@ -17,7 +17,6 @@ export const createFeedbackConfig = (
|
|
|
17
17
|
onSubmit: (data: FeedbackFormData) => Promise<void>,
|
|
18
18
|
): FeedbackConfig => ({
|
|
19
19
|
enabled: true,
|
|
20
|
-
icon: "chatbubble-outline",
|
|
21
20
|
onSubmit,
|
|
22
21
|
});
|
|
23
22
|
|
|
@@ -39,5 +38,4 @@ export const createRatingConfig = (
|
|
|
39
38
|
*/
|
|
40
39
|
export const createFAQConfig = (): FAQConfig => ({
|
|
41
40
|
enabled: true,
|
|
42
|
-
icon: "help-circle-outline",
|
|
43
41
|
});
|