@umituz/react-native-settings 5.3.47 → 5.3.49
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/about/presentation/hooks/useAboutInfo.ts +4 -1
- package/src/domains/feedback/presentation/screens/FeatureRequestScreen.tsx +1 -1
- package/src/domains/gamification/components/GamificationScreen/GamificationScreen.tsx +1 -1
- package/src/domains/gamification/utils/calculations.ts +13 -4
- package/src/domains/localization/infrastructure/config/I18nInitializer.ts +4 -1
- package/src/domains/localization/infrastructure/storage/LanguageSwitcher.ts +3 -1
- package/src/domains/notifications/infrastructure/services/NotificationScheduler.ts +13 -4
- package/src/domains/notifications/infrastructure/services/NotificationService.ts +4 -1
- package/src/domains/notifications/reminders/infrastructure/hooks/useReminderActions.ts +4 -1
- package/src/domains/rating/application/services/RatingService.ts +16 -5
- package/src/domains/rating/infrastructure/storage/RatingStorage.ts +16 -5
- package/src/presentation/hooks/useSettingsScreenConfig.ts +10 -2
- package/src/presentation/navigation/hooks/useNavigationHandlers.ts +19 -6
- package/src/presentation/navigation/hooks/useSettingsScreens.ts +4 -4
- package/src/presentation/utils/screenFactory.ts +8 -6
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.49",
|
|
4
4
|
"description": "Complete settings hub for React Native apps - consolidated package with settings, localization, about, legal, appearance, feedback, FAQs, rating, and gamification",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -24,6 +24,7 @@ export const useAboutInfo = (
|
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Initialize app info with config
|
|
27
|
+
* FIXED: Set isInitializedRef BEFORE async operation to prevent race condition
|
|
27
28
|
*/
|
|
28
29
|
const initialize = useCallback(
|
|
29
30
|
async (config: AboutConfig) => {
|
|
@@ -31,10 +32,12 @@ export const useAboutInfo = (
|
|
|
31
32
|
return;
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
// FIX: Set ref immediately to prevent race condition from concurrent calls
|
|
36
|
+
isInitializedRef.current = true;
|
|
37
|
+
|
|
34
38
|
await execute(async () => {
|
|
35
39
|
const defaultAppInfo = createDefaultAppInfo(config);
|
|
36
40
|
await repository.saveAppInfo(defaultAppInfo);
|
|
37
|
-
isInitializedRef.current = true;
|
|
38
41
|
return defaultAppInfo;
|
|
39
42
|
});
|
|
40
43
|
},
|
|
@@ -15,7 +15,7 @@ import { ScreenLayout } from "@umituz/react-native-design-system/layouts";
|
|
|
15
15
|
import { FeedbackModal } from "../components/FeedbackModal";
|
|
16
16
|
import { useFeatureRequests } from "../../infrastructure/useFeatureRequests";
|
|
17
17
|
import type { FeedbackRating } from "../../domain/entities/FeedbackEntity";
|
|
18
|
-
import type { FeatureRequestItem
|
|
18
|
+
import type { FeatureRequestItem } from "../../domain/entities/FeatureRequestEntity";
|
|
19
19
|
import type { FeedbackFormTexts } from "../components/FeedbackFormProps";
|
|
20
20
|
|
|
21
21
|
interface FeatureRequestScreenProps {
|
|
@@ -21,7 +21,7 @@ import type { GamificationScreenProps } from "./types";
|
|
|
21
21
|
* Internal component that renders the screen with all props
|
|
22
22
|
*/
|
|
23
23
|
export const GamificationScreenInner: React.FC<GamificationScreenProps> = ({
|
|
24
|
-
title,
|
|
24
|
+
title: _title,
|
|
25
25
|
statsTitle,
|
|
26
26
|
achievementsTitle,
|
|
27
27
|
streakTitle,
|
|
@@ -63,16 +63,25 @@ export const updateAchievementProgress = (
|
|
|
63
63
|
return Math.min(100, (value / definition.threshold) * 100);
|
|
64
64
|
};
|
|
65
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Check if streak is active based on last activity date
|
|
68
|
+
* Returns true if last activity was today or yesterday
|
|
69
|
+
* FIXED: Now uses date comparison instead of hour-based calculation to avoid timezone issues
|
|
70
|
+
*/
|
|
66
71
|
export const isStreakActive = (lastActivityDate: string | null): boolean => {
|
|
67
72
|
if (!lastActivityDate) return false;
|
|
68
73
|
|
|
69
74
|
const last = new Date(lastActivityDate);
|
|
70
75
|
const now = new Date();
|
|
71
|
-
const diffDays = Math.floor(
|
|
72
|
-
(now.getTime() - last.getTime()) / (1000 * 60 * 60 * 24)
|
|
73
|
-
);
|
|
74
76
|
|
|
75
|
-
|
|
77
|
+
// Normalize to midnight to compare days, not hours
|
|
78
|
+
const lastMidnight = new Date(last.getFullYear(), last.getMonth(), last.getDate());
|
|
79
|
+
const nowMidnight = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
80
|
+
const yesterdayMidnight = new Date(nowMidnight);
|
|
81
|
+
yesterdayMidnight.setDate(yesterdayMidnight.getDate() - 1);
|
|
82
|
+
|
|
83
|
+
// Active if last activity was today or yesterday
|
|
84
|
+
return lastMidnight.getTime() >= yesterdayMidnight.getTime();
|
|
76
85
|
};
|
|
77
86
|
|
|
78
87
|
export const isSameDay = (date1: Date, date2: Date): boolean => {
|
|
@@ -10,6 +10,7 @@ import { initReactI18next } from 'react-i18next';
|
|
|
10
10
|
import { DEFAULT_LANGUAGE } from './languages';
|
|
11
11
|
import { ResourceBuilder } from './ResourceBuilder';
|
|
12
12
|
import { NamespaceResolver } from './NamespaceResolver';
|
|
13
|
+
import { isDev } from '../../../../utils/devUtils';
|
|
13
14
|
|
|
14
15
|
export class I18nInitializer {
|
|
15
16
|
private static reactI18nextInitialized = false;
|
|
@@ -52,7 +53,9 @@ export class I18nInitializer {
|
|
|
52
53
|
returnNull: false,
|
|
53
54
|
});
|
|
54
55
|
} catch (error) {
|
|
55
|
-
|
|
56
|
+
if (isDev()) {
|
|
57
|
+
console.error('[I18nInitializer] Failed to initialize i18n:', languageCode, error);
|
|
58
|
+
}
|
|
56
59
|
}
|
|
57
60
|
}
|
|
58
61
|
|
|
@@ -47,7 +47,9 @@ export class LanguageSwitcher {
|
|
|
47
47
|
isRTL: language?.isRTL ?? false,
|
|
48
48
|
};
|
|
49
49
|
} catch (error) {
|
|
50
|
-
|
|
50
|
+
if (isDev()) {
|
|
51
|
+
console.error('[LanguageSwitcher] Failed to switch language:', languageCode, error);
|
|
52
|
+
}
|
|
51
53
|
throw error;
|
|
52
54
|
}
|
|
53
55
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as Notifications from 'expo-notifications';
|
|
2
|
+
import { isDev } from "../../../../utils/devUtils";
|
|
2
3
|
import type { ScheduleNotificationOptions, ScheduledNotification } from './types';
|
|
3
4
|
|
|
4
5
|
export class NotificationScheduler {
|
|
@@ -54,7 +55,9 @@ export class NotificationScheduler {
|
|
|
54
55
|
|
|
55
56
|
return notificationId;
|
|
56
57
|
} catch (error) {
|
|
57
|
-
|
|
58
|
+
if (isDev()) {
|
|
59
|
+
console.error('Failed to schedule notification:', error);
|
|
60
|
+
}
|
|
58
61
|
throw new Error(`Notification scheduling failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
59
62
|
}
|
|
60
63
|
}
|
|
@@ -63,7 +66,9 @@ export class NotificationScheduler {
|
|
|
63
66
|
try {
|
|
64
67
|
await Notifications.cancelScheduledNotificationAsync(notificationId);
|
|
65
68
|
} catch (error) {
|
|
66
|
-
|
|
69
|
+
if (isDev()) {
|
|
70
|
+
console.error('Failed to cancel notification:', notificationId, error);
|
|
71
|
+
}
|
|
67
72
|
// Don't throw - canceling a non-existent notification is not critical
|
|
68
73
|
}
|
|
69
74
|
}
|
|
@@ -72,7 +77,9 @@ export class NotificationScheduler {
|
|
|
72
77
|
try {
|
|
73
78
|
await Notifications.cancelAllScheduledNotificationsAsync();
|
|
74
79
|
} catch (error) {
|
|
75
|
-
|
|
80
|
+
if (isDev()) {
|
|
81
|
+
console.error('Failed to cancel all notifications:', error);
|
|
82
|
+
}
|
|
76
83
|
throw new Error(`Failed to cancel notifications: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
77
84
|
}
|
|
78
85
|
}
|
|
@@ -90,7 +97,9 @@ export class NotificationScheduler {
|
|
|
90
97
|
trigger: notification.trigger,
|
|
91
98
|
}));
|
|
92
99
|
} catch (error) {
|
|
93
|
-
|
|
100
|
+
if (isDev()) {
|
|
101
|
+
console.error('Failed to get scheduled notifications:', error);
|
|
102
|
+
}
|
|
94
103
|
return []; // Return empty array as fallback
|
|
95
104
|
}
|
|
96
105
|
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { NotificationManager } from './NotificationManager';
|
|
11
|
+
import { isDev } from '../../../../utils/devUtils';
|
|
11
12
|
|
|
12
13
|
export * from './types';
|
|
13
14
|
|
|
@@ -31,7 +32,9 @@ export class NotificationService {
|
|
|
31
32
|
NotificationManager.configure();
|
|
32
33
|
this.isConfigured = true;
|
|
33
34
|
} catch (error) {
|
|
34
|
-
|
|
35
|
+
if (isDev()) {
|
|
36
|
+
console.error('[NotificationService] Failed to configure NotificationManager:', error);
|
|
37
|
+
}
|
|
35
38
|
}
|
|
36
39
|
}
|
|
37
40
|
}
|
|
@@ -119,8 +119,11 @@ export const useReminderActions = () => {
|
|
|
119
119
|
throw error; // Re-throw to allow caller to handle
|
|
120
120
|
}
|
|
121
121
|
} else if (!reminder.enabled) {
|
|
122
|
+
// FIX: Create temporary updated reminder for trigger building
|
|
123
|
+
// This prevents state inconsistency where trigger is built with old state
|
|
124
|
+
const tempEnabledReminder = { ...reminder, enabled: true };
|
|
122
125
|
try {
|
|
123
|
-
const trigger = buildTrigger(
|
|
126
|
+
const trigger = buildTrigger(tempEnabledReminder);
|
|
124
127
|
const notificationId = await scheduler.scheduleNotification({
|
|
125
128
|
title: reminder.title,
|
|
126
129
|
body: reminder.body,
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { RatingConfig, RatingState } from "../../domain/entities/RatingConfig";
|
|
7
|
+
import { isDev } from "../../../../utils/devUtils";
|
|
7
8
|
import {
|
|
8
9
|
getEventCount,
|
|
9
10
|
incrementEventCount,
|
|
@@ -40,7 +41,9 @@ export async function trackEvent(eventType: string): Promise<void> {
|
|
|
40
41
|
try {
|
|
41
42
|
await incrementEventCount(eventType);
|
|
42
43
|
} catch (error) {
|
|
43
|
-
|
|
44
|
+
if (isDev()) {
|
|
45
|
+
console.error('[RatingService] Failed to track event:', eventType, error);
|
|
46
|
+
}
|
|
44
47
|
}
|
|
45
48
|
}
|
|
46
49
|
|
|
@@ -90,7 +93,9 @@ export async function markPromptShown(eventType: string): Promise<void> {
|
|
|
90
93
|
try {
|
|
91
94
|
await setLastPromptDate(eventType, toISOString());
|
|
92
95
|
} catch (error) {
|
|
93
|
-
|
|
96
|
+
if (isDev()) {
|
|
97
|
+
console.error('[RatingService] Failed to mark prompt shown:', eventType, error);
|
|
98
|
+
}
|
|
94
99
|
}
|
|
95
100
|
}
|
|
96
101
|
|
|
@@ -101,7 +106,9 @@ export async function markRated(): Promise<void> {
|
|
|
101
106
|
try {
|
|
102
107
|
await setHasRated(true);
|
|
103
108
|
} catch (error) {
|
|
104
|
-
|
|
109
|
+
if (isDev()) {
|
|
110
|
+
console.error('[RatingService] Failed to mark as rated:', error);
|
|
111
|
+
}
|
|
105
112
|
}
|
|
106
113
|
}
|
|
107
114
|
|
|
@@ -112,7 +119,9 @@ export async function markDismissed(): Promise<void> {
|
|
|
112
119
|
try {
|
|
113
120
|
await setDismissed(true);
|
|
114
121
|
} catch (error) {
|
|
115
|
-
|
|
122
|
+
if (isDev()) {
|
|
123
|
+
console.error('[RatingService] Failed to mark as dismissed:', error);
|
|
124
|
+
}
|
|
116
125
|
}
|
|
117
126
|
}
|
|
118
127
|
|
|
@@ -130,6 +139,8 @@ export async function reset(eventType?: string): Promise<void> {
|
|
|
130
139
|
try {
|
|
131
140
|
await resetStorage(eventType);
|
|
132
141
|
} catch (error) {
|
|
133
|
-
|
|
142
|
+
if (isDev()) {
|
|
143
|
+
console.error('[RatingService] Failed to reset:', eventType, error);
|
|
144
|
+
}
|
|
134
145
|
}
|
|
135
146
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { storageRepository, unwrap } from "@umituz/react-native-design-system/storage";
|
|
7
|
+
import { isDev } from "../../../../utils/devUtils";
|
|
7
8
|
import type { RatingState } from "../../domain/entities/RatingConfig";
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -36,7 +37,9 @@ export async function setEventCount(eventType: string, count: number): Promise<v
|
|
|
36
37
|
try {
|
|
37
38
|
await storageRepository.setString(KEYS.eventCount(eventType), count.toString());
|
|
38
39
|
} catch (error) {
|
|
39
|
-
|
|
40
|
+
if (isDev()) {
|
|
41
|
+
console.error('[RatingStorage] Failed to set event count:', eventType, count, error);
|
|
42
|
+
}
|
|
40
43
|
}
|
|
41
44
|
}
|
|
42
45
|
|
|
@@ -78,7 +81,9 @@ export async function setLastPromptDate(eventType: string, date: string): Promis
|
|
|
78
81
|
try {
|
|
79
82
|
await storageRepository.setString(KEYS.lastPrompt(eventType), date);
|
|
80
83
|
} catch (error) {
|
|
81
|
-
|
|
84
|
+
if (isDev()) {
|
|
85
|
+
console.error('[RatingStorage] Failed to set last prompt date:', eventType, date, error);
|
|
86
|
+
}
|
|
82
87
|
}
|
|
83
88
|
}
|
|
84
89
|
|
|
@@ -101,7 +106,9 @@ export async function setHasRated(value: boolean): Promise<void> {
|
|
|
101
106
|
try {
|
|
102
107
|
await storageRepository.setString(KEYS.hasRated, value.toString());
|
|
103
108
|
} catch (error) {
|
|
104
|
-
|
|
109
|
+
if (isDev()) {
|
|
110
|
+
console.error('[RatingStorage] Failed to set has rated:', value, error);
|
|
111
|
+
}
|
|
105
112
|
}
|
|
106
113
|
}
|
|
107
114
|
|
|
@@ -124,7 +131,9 @@ export async function setDismissed(value: boolean): Promise<void> {
|
|
|
124
131
|
try {
|
|
125
132
|
await storageRepository.setString(KEYS.dismissed, value.toString());
|
|
126
133
|
} catch (error) {
|
|
127
|
-
|
|
134
|
+
if (isDev()) {
|
|
135
|
+
console.error('[RatingStorage] Failed to set dismissed:', value, error);
|
|
136
|
+
}
|
|
128
137
|
}
|
|
129
138
|
}
|
|
130
139
|
|
|
@@ -165,6 +174,8 @@ export async function reset(eventType?: string): Promise<void> {
|
|
|
165
174
|
);
|
|
166
175
|
}
|
|
167
176
|
} catch (error) {
|
|
168
|
-
|
|
177
|
+
if (isDev()) {
|
|
178
|
+
console.error('[RatingStorage] Failed to reset rating data:', eventType, error);
|
|
179
|
+
}
|
|
169
180
|
}
|
|
170
181
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import { useMemo } from "react";
|
|
10
10
|
import { useAuth, useUserProfile, useAuthHandlers } from "@umituz/react-native-auth";
|
|
11
11
|
import { createUserProfileDisplay } from "../utils/userProfileUtils";
|
|
12
|
-
import { createAccountConfig } from "../utils/accountConfigUtils";
|
|
12
|
+
import { createAccountConfig, type AccountTranslations } from "../utils/accountConfigUtils";
|
|
13
13
|
import { useSettingsConfigFactory } from "../utils/settingsConfigFactory";
|
|
14
14
|
import type { SettingsConfig, SettingsTranslations } from "../screens/types";
|
|
15
15
|
import type { FeedbackFormData } from "../utils/config-creators";
|
|
@@ -147,7 +147,15 @@ export const useSettingsScreenConfig = (
|
|
|
147
147
|
onSignIn: handleSignIn,
|
|
148
148
|
onLogout: handleSignOut,
|
|
149
149
|
onDeleteAccount: handleDeleteAccount,
|
|
150
|
-
translations: translations?.account
|
|
150
|
+
translations: (translations?.account?.logout &&
|
|
151
|
+
translations?.account?.deleteAccount &&
|
|
152
|
+
translations?.account?.logoutConfirmTitle &&
|
|
153
|
+
translations?.account?.logoutConfirmMessage &&
|
|
154
|
+
translations?.account?.deleteConfirmTitle &&
|
|
155
|
+
translations?.account?.deleteConfirmMessage &&
|
|
156
|
+
translations?.account?.cancel)
|
|
157
|
+
? translations.account as AccountTranslations
|
|
158
|
+
: undefined,
|
|
151
159
|
}), [user, userProfileData, handleSignIn, handleSignOut, handleDeleteAccount, translations]);
|
|
152
160
|
|
|
153
161
|
return {
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import { useCallback, useMemo } from "react";
|
|
7
7
|
import { Linking } from "react-native";
|
|
8
|
+
import { isDev } from "../../../utils/devUtils";
|
|
8
9
|
import type { AppInfo, LegalUrls } from "../types";
|
|
9
10
|
import type { AboutConfig } from "../../../domains/about";
|
|
10
11
|
|
|
@@ -26,10 +27,14 @@ export const useNavigationHandlers = (
|
|
|
26
27
|
if (canOpen) {
|
|
27
28
|
await Linking.openURL(legalUrls.privacy);
|
|
28
29
|
} else {
|
|
29
|
-
|
|
30
|
+
if (isDev()) {
|
|
31
|
+
console.warn('Cannot open privacy policy URL:', legalUrls.privacy);
|
|
32
|
+
}
|
|
30
33
|
}
|
|
31
34
|
} catch (error) {
|
|
32
|
-
|
|
35
|
+
if (isDev()) {
|
|
36
|
+
console.error('Failed to open privacy policy:', error);
|
|
37
|
+
}
|
|
33
38
|
}
|
|
34
39
|
}, [legalUrls.privacy]);
|
|
35
40
|
|
|
@@ -39,10 +44,14 @@ export const useNavigationHandlers = (
|
|
|
39
44
|
if (canOpen) {
|
|
40
45
|
await Linking.openURL(legalUrls.terms);
|
|
41
46
|
} else {
|
|
42
|
-
|
|
47
|
+
if (isDev()) {
|
|
48
|
+
console.warn('Cannot open terms of service URL:', legalUrls.terms);
|
|
49
|
+
}
|
|
43
50
|
}
|
|
44
51
|
} catch (error) {
|
|
45
|
-
|
|
52
|
+
if (isDev()) {
|
|
53
|
+
console.error('Failed to open terms of service:', error);
|
|
54
|
+
}
|
|
46
55
|
}
|
|
47
56
|
}, [legalUrls.terms]);
|
|
48
57
|
|
|
@@ -53,10 +62,14 @@ export const useNavigationHandlers = (
|
|
|
53
62
|
if (canOpen) {
|
|
54
63
|
await Linking.openURL(legalUrls.eula);
|
|
55
64
|
} else {
|
|
56
|
-
|
|
65
|
+
if (isDev()) {
|
|
66
|
+
console.warn('Cannot open EULA URL:', legalUrls.eula);
|
|
67
|
+
}
|
|
57
68
|
}
|
|
58
69
|
} catch (error) {
|
|
59
|
-
|
|
70
|
+
if (isDev()) {
|
|
71
|
+
console.error('Failed to open EULA:', error);
|
|
72
|
+
}
|
|
60
73
|
}
|
|
61
74
|
}
|
|
62
75
|
}, [legalUrls.eula]);
|
|
@@ -84,7 +84,7 @@ export const useSettingsScreens = (props: UseSettingsScreensProps): StackScreen[
|
|
|
84
84
|
|
|
85
85
|
const appearanceScreen = {
|
|
86
86
|
name: "Appearance",
|
|
87
|
-
component: AppearanceScreen
|
|
87
|
+
component: AppearanceScreen,
|
|
88
88
|
options: { headerShown: false },
|
|
89
89
|
};
|
|
90
90
|
|
|
@@ -121,7 +121,7 @@ export const useSettingsScreens = (props: UseSettingsScreensProps): StackScreen[
|
|
|
121
121
|
|
|
122
122
|
const additionalStackScreens: StackScreen[] = (additionalScreens || []).map(convertAdditionalScreen);
|
|
123
123
|
|
|
124
|
-
const gamificationScreen = createScreenWithProps("Gamification", GamificationScreen
|
|
124
|
+
const gamificationScreen = createScreenWithProps("Gamification", GamificationScreen, { config: gamificationConfig });
|
|
125
125
|
|
|
126
126
|
const languageScreen = createScreenWithProps("LanguageSelection", LanguageSelectionScreen, {
|
|
127
127
|
headerTitle: featureTranslations?.language?.title || "",
|
|
@@ -130,10 +130,10 @@ export const useSettingsScreens = (props: UseSettingsScreensProps): StackScreen[
|
|
|
130
130
|
|
|
131
131
|
const accountScreen = createConditionalScreen(
|
|
132
132
|
!!accountConfig && !!AccountScreen,
|
|
133
|
-
() => createScreenWithProps("Account", AccountScreen
|
|
133
|
+
() => createScreenWithProps("Account", AccountScreen, { config: accountConfig })
|
|
134
134
|
);
|
|
135
135
|
|
|
136
|
-
const videoTutorialScreen = createScreenWithProps("VideoTutorial", VideoTutorialsScreen
|
|
136
|
+
const videoTutorialScreen = createScreenWithProps("VideoTutorial", VideoTutorialsScreen, {
|
|
137
137
|
...videoTutorialConfig,
|
|
138
138
|
title: videoTutorialConfig?.title || featureTranslations?.videoTutorial?.title || "",
|
|
139
139
|
});
|
|
@@ -20,7 +20,7 @@ export function createScreenWithProps<P>(
|
|
|
20
20
|
return {
|
|
21
21
|
name,
|
|
22
22
|
options: { headerShown: false, ...options },
|
|
23
|
-
children: (() => React.createElement(component
|
|
23
|
+
children: (() => React.createElement(component, props)) as () => React.ReactElement,
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -28,11 +28,13 @@ export function createScreenWithProps<P>(
|
|
|
28
28
|
* Convert additional screen to stack screen
|
|
29
29
|
*/
|
|
30
30
|
export function convertAdditionalScreen(screen: AdditionalScreen): StackScreen {
|
|
31
|
-
const stackScreen:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
const stackScreen: StackScreen = {
|
|
32
|
+
name: screen.name,
|
|
33
|
+
component: screen.component,
|
|
34
|
+
children: screen.children,
|
|
35
|
+
options: screen.options,
|
|
36
|
+
};
|
|
37
|
+
return stackScreen;
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
/**
|