@umituz/react-native-settings 4.20.54 → 4.20.56
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-settings",
|
|
3
|
-
"version": "4.20.
|
|
3
|
+
"version": "4.20.56",
|
|
4
4
|
"description": "Complete settings hub for React Native apps - consolidated package with settings, about, legal, appearance, feedback, FAQs, and rating",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -4,35 +4,17 @@
|
|
|
4
4
|
* Optimized for performance and memory safety
|
|
5
5
|
*/
|
|
6
6
|
import { useState, useCallback, useRef, useEffect } from 'react';
|
|
7
|
-
import { AppInfo, AboutConfig } from '../../domain/entities/AppInfo';
|
|
7
|
+
import type { AppInfo, AboutConfig } from '../../domain/entities/AppInfo';
|
|
8
8
|
import { AboutRepository } from '../../infrastructure/repositories/AboutRepository';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
export interface UseAboutInfoReturn {
|
|
19
|
-
/** Current app info */
|
|
20
|
-
appInfo: AppInfo | null;
|
|
21
|
-
/** Loading state */
|
|
22
|
-
loading: boolean;
|
|
23
|
-
/** Error state */
|
|
24
|
-
error: string | null;
|
|
25
|
-
/** Initialize with config */
|
|
26
|
-
initialize: (config: AboutConfig) => Promise<void>;
|
|
27
|
-
/** Update with new config */
|
|
28
|
-
update: (config: AboutConfig) => Promise<void>;
|
|
29
|
-
/** Update app info */
|
|
30
|
-
updateAppInfo: (updates: Partial<AppInfo>) => Promise<void>;
|
|
31
|
-
/** Refresh current app info */
|
|
32
|
-
refresh: () => Promise<void>;
|
|
33
|
-
/** Reset to initial state */
|
|
34
|
-
reset: () => void;
|
|
35
|
-
}
|
|
9
|
+
import type { UseAboutInfoOptions, UseAboutInfoReturn } from './useAboutInfo.types';
|
|
10
|
+
import {
|
|
11
|
+
setErrorIfMounted,
|
|
12
|
+
setLoadingIfMounted,
|
|
13
|
+
initializeAppInfo,
|
|
14
|
+
updateAppInfoConfig,
|
|
15
|
+
updateAppInfoPartial,
|
|
16
|
+
refreshAppInfo,
|
|
17
|
+
} from './useAboutInfo.utils';
|
|
36
18
|
|
|
37
19
|
export const useAboutInfo = (
|
|
38
20
|
options: UseAboutInfoOptions = {}
|
|
@@ -46,111 +28,59 @@ export const useAboutInfo = (
|
|
|
46
28
|
const isInitializedRef = useRef(false);
|
|
47
29
|
const isMountedRef = useRef(true);
|
|
48
30
|
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
setLoading
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
isInitializedRef.current = true;
|
|
31
|
+
const initialize = useCallback(
|
|
32
|
+
(config: AboutConfig) => initializeAppInfo(
|
|
33
|
+
config,
|
|
34
|
+
repository,
|
|
35
|
+
isMountedRef,
|
|
36
|
+
isInitializedRef,
|
|
37
|
+
setAppInfo,
|
|
38
|
+
setError,
|
|
39
|
+
setLoading
|
|
40
|
+
),
|
|
41
|
+
[repository]
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const update = useCallback(
|
|
45
|
+
(config: AboutConfig) => updateAppInfoConfig(
|
|
46
|
+
config,
|
|
47
|
+
repository,
|
|
48
|
+
isMountedRef,
|
|
49
|
+
setAppInfo,
|
|
50
|
+
setError,
|
|
51
|
+
setLoading
|
|
52
|
+
),
|
|
53
|
+
[repository]
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const updateAppInfoCallback = useCallback(
|
|
57
|
+
(updates: Partial<AppInfo>) => {
|
|
58
|
+
if (!appInfo) {
|
|
59
|
+
setErrorIfMounted(isMountedRef, setError, 'App info not initialized');
|
|
60
|
+
return Promise.resolve();
|
|
80
61
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
} catch (err) {
|
|
104
|
-
setErrorIfMounted(err instanceof Error ? err.message : 'Unknown error');
|
|
105
|
-
} finally {
|
|
106
|
-
setLoadingIfMounted(false);
|
|
107
|
-
}
|
|
108
|
-
}, [repository, setErrorIfMounted, setLoadingIfMounted]);
|
|
109
|
-
|
|
110
|
-
const updateAppInfo = useCallback(async (updates: Partial<AppInfo>) => {
|
|
111
|
-
if (!appInfo || !isMountedRef.current) {
|
|
112
|
-
if (isMountedRef.current) {
|
|
113
|
-
setErrorIfMounted('App info not initialized');
|
|
114
|
-
}
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
setLoadingIfMounted(true);
|
|
119
|
-
setErrorIfMounted(null);
|
|
120
|
-
|
|
121
|
-
try {
|
|
122
|
-
const updatedInfo = await repository.updateAppInfo(updates);
|
|
123
|
-
|
|
124
|
-
if (isMountedRef.current) {
|
|
125
|
-
setAppInfo(updatedInfo);
|
|
126
|
-
}
|
|
127
|
-
} catch (err) {
|
|
128
|
-
setErrorIfMounted(err instanceof Error ? err.message : 'Unknown error');
|
|
129
|
-
} finally {
|
|
130
|
-
setLoadingIfMounted(false);
|
|
131
|
-
}
|
|
132
|
-
}, [repository, appInfo, setErrorIfMounted, setLoadingIfMounted]);
|
|
133
|
-
|
|
134
|
-
const refresh = useCallback(async () => {
|
|
135
|
-
if (!isMountedRef.current || !appInfo) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
setLoadingIfMounted(true);
|
|
140
|
-
setErrorIfMounted(null);
|
|
141
|
-
|
|
142
|
-
try {
|
|
143
|
-
const refreshedInfo = await repository.getAppInfo();
|
|
144
|
-
|
|
145
|
-
if (isMountedRef.current) {
|
|
146
|
-
setAppInfo(refreshedInfo);
|
|
147
|
-
}
|
|
148
|
-
} catch (err) {
|
|
149
|
-
setErrorIfMounted(err instanceof Error ? err.message : 'Unknown error');
|
|
150
|
-
} finally {
|
|
151
|
-
setLoadingIfMounted(false);
|
|
152
|
-
}
|
|
153
|
-
}, [repository, appInfo, setErrorIfMounted, setLoadingIfMounted]);
|
|
62
|
+
return updateAppInfoPartial(
|
|
63
|
+
updates,
|
|
64
|
+
repository,
|
|
65
|
+
isMountedRef,
|
|
66
|
+
setAppInfo,
|
|
67
|
+
setError,
|
|
68
|
+
setLoading
|
|
69
|
+
);
|
|
70
|
+
},
|
|
71
|
+
[repository, appInfo]
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const refresh = useCallback(
|
|
75
|
+
() => refreshAppInfo(
|
|
76
|
+
repository,
|
|
77
|
+
isMountedRef,
|
|
78
|
+
setAppInfo,
|
|
79
|
+
setError,
|
|
80
|
+
setLoading
|
|
81
|
+
),
|
|
82
|
+
[repository]
|
|
83
|
+
);
|
|
154
84
|
|
|
155
85
|
const reset = useCallback(() => {
|
|
156
86
|
if (!isMountedRef.current) {
|
|
@@ -163,6 +93,7 @@ export const useAboutInfo = (
|
|
|
163
93
|
isInitializedRef.current = false;
|
|
164
94
|
}, []);
|
|
165
95
|
|
|
96
|
+
// Cleanup on unmount
|
|
166
97
|
useEffect(() => {
|
|
167
98
|
return () => {
|
|
168
99
|
isMountedRef.current = false;
|
|
@@ -173,17 +104,25 @@ export const useAboutInfo = (
|
|
|
173
104
|
};
|
|
174
105
|
}, [repository]);
|
|
175
106
|
|
|
107
|
+
// Initialize with default config if provided
|
|
176
108
|
useEffect(() => {
|
|
177
|
-
if (
|
|
109
|
+
if (
|
|
110
|
+
initialConfig &&
|
|
111
|
+
autoInit !== false &&
|
|
112
|
+
isMountedRef.current &&
|
|
113
|
+
!isInitializedRef.current
|
|
114
|
+
) {
|
|
115
|
+
const { createDefaultAppInfo } = require('../../utils/AppInfoFactory');
|
|
178
116
|
const defaultAppInfo = createDefaultAppInfo(initialConfig);
|
|
179
117
|
setAppInfo(defaultAppInfo);
|
|
180
118
|
isInitializedRef.current = true;
|
|
181
119
|
}
|
|
182
120
|
}, [initialConfig, autoInit]);
|
|
183
121
|
|
|
122
|
+
// Auto-initialize if autoInit is true
|
|
184
123
|
useEffect(() => {
|
|
185
124
|
if (autoInit === true && initialConfig && isMountedRef.current) {
|
|
186
|
-
initialize(initialConfig
|
|
125
|
+
initialize(initialConfig);
|
|
187
126
|
}
|
|
188
127
|
}, [autoInit, initialConfig, initialize]);
|
|
189
128
|
|
|
@@ -193,8 +132,11 @@ export const useAboutInfo = (
|
|
|
193
132
|
error,
|
|
194
133
|
initialize,
|
|
195
134
|
update,
|
|
196
|
-
updateAppInfo,
|
|
135
|
+
updateAppInfo: updateAppInfoCallback,
|
|
197
136
|
refresh,
|
|
198
137
|
reset,
|
|
199
138
|
};
|
|
200
139
|
};
|
|
140
|
+
|
|
141
|
+
// Re-export types for convenience
|
|
142
|
+
export type { UseAboutInfoOptions, UseAboutInfoReturn } from './useAboutInfo.types';
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useAboutInfo Hook Utilities
|
|
3
|
+
* Shared utility functions for about info hook
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { MutableRefObject } from 'react';
|
|
7
|
+
import type { AppInfo, AboutConfig } from '../../domain/entities/AppInfo';
|
|
8
|
+
import type { AboutRepository } from '../../infrastructure/repositories/AboutRepository';
|
|
9
|
+
import { createDefaultAppInfo } from '../../utils/AppInfoFactory';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Safely set error if component is mounted
|
|
13
|
+
*/
|
|
14
|
+
export const setErrorIfMounted = (
|
|
15
|
+
isMountedRef: MutableRefObject<boolean>,
|
|
16
|
+
setError: (error: string | null) => void,
|
|
17
|
+
err: string | null
|
|
18
|
+
) => {
|
|
19
|
+
if (isMountedRef.current) {
|
|
20
|
+
setError(err);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Safely set loading state if component is mounted
|
|
26
|
+
*/
|
|
27
|
+
export const setLoadingIfMounted = (
|
|
28
|
+
isMountedRef: MutableRefObject<boolean>,
|
|
29
|
+
setLoading: (loading: boolean) => void,
|
|
30
|
+
value: boolean
|
|
31
|
+
) => {
|
|
32
|
+
if (isMountedRef.current) {
|
|
33
|
+
setLoading(value);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Initialize app info with config
|
|
39
|
+
*/
|
|
40
|
+
export const initializeAppInfo = async (
|
|
41
|
+
config: AboutConfig,
|
|
42
|
+
repository: AboutRepository,
|
|
43
|
+
isMountedRef: MutableRefObject<boolean>,
|
|
44
|
+
isInitializedRef: MutableRefObject<boolean>,
|
|
45
|
+
setAppInfo: (info: AppInfo | null) => void,
|
|
46
|
+
setError: (error: string | null) => void,
|
|
47
|
+
setLoading: (loading: boolean) => void,
|
|
48
|
+
force = false
|
|
49
|
+
): Promise<void> => {
|
|
50
|
+
if (isInitializedRef.current && !force) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!isMountedRef.current) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
setLoading(true);
|
|
59
|
+
setError(null);
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
const defaultAppInfo = createDefaultAppInfo(config);
|
|
63
|
+
await repository.saveAppInfo(defaultAppInfo);
|
|
64
|
+
|
|
65
|
+
if (isMountedRef.current) {
|
|
66
|
+
setAppInfo(defaultAppInfo);
|
|
67
|
+
isInitializedRef.current = true;
|
|
68
|
+
}
|
|
69
|
+
} catch (err) {
|
|
70
|
+
setError(err instanceof Error ? err.message : 'Unknown error');
|
|
71
|
+
} finally {
|
|
72
|
+
setLoading(false);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Update app info with new config
|
|
78
|
+
*/
|
|
79
|
+
export const updateAppInfoConfig = async (
|
|
80
|
+
config: AboutConfig,
|
|
81
|
+
repository: AboutRepository,
|
|
82
|
+
isMountedRef: MutableRefObject<boolean>,
|
|
83
|
+
setAppInfo: (info: AppInfo | null) => void,
|
|
84
|
+
setError: (error: string | null) => void,
|
|
85
|
+
setLoading: (loading: boolean) => void
|
|
86
|
+
): Promise<void> => {
|
|
87
|
+
if (!isMountedRef.current) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
setLoading(true);
|
|
92
|
+
setError(null);
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
const updatedAppInfo = createDefaultAppInfo(config);
|
|
96
|
+
await repository.saveAppInfo(updatedAppInfo);
|
|
97
|
+
|
|
98
|
+
if (isMountedRef.current) {
|
|
99
|
+
setAppInfo(updatedAppInfo);
|
|
100
|
+
}
|
|
101
|
+
} catch (err) {
|
|
102
|
+
setError(err instanceof Error ? err.message : 'Unknown error');
|
|
103
|
+
} finally {
|
|
104
|
+
setLoading(false);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Update app info with partial updates
|
|
110
|
+
*/
|
|
111
|
+
export const updateAppInfoPartial = async (
|
|
112
|
+
updates: Partial<AppInfo>,
|
|
113
|
+
repository: AboutRepository,
|
|
114
|
+
isMountedRef: MutableRefObject<boolean>,
|
|
115
|
+
setAppInfo: (info: AppInfo | null) => void,
|
|
116
|
+
setError: (error: string | null) => void,
|
|
117
|
+
setLoading: (loading: boolean) => void
|
|
118
|
+
): Promise<void> => {
|
|
119
|
+
if (!isMountedRef.current) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
setLoading(true);
|
|
124
|
+
setError(null);
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
const updatedInfo = await repository.updateAppInfo(updates);
|
|
128
|
+
|
|
129
|
+
if (isMountedRef.current) {
|
|
130
|
+
setAppInfo(updatedInfo);
|
|
131
|
+
}
|
|
132
|
+
} catch (err) {
|
|
133
|
+
setError(err instanceof Error ? err.message : 'Unknown error');
|
|
134
|
+
} finally {
|
|
135
|
+
setLoading(false);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Refresh app info from repository
|
|
141
|
+
*/
|
|
142
|
+
export const refreshAppInfo = async (
|
|
143
|
+
repository: AboutRepository,
|
|
144
|
+
isMountedRef: MutableRefObject<boolean>,
|
|
145
|
+
setAppInfo: (info: AppInfo | null) => void,
|
|
146
|
+
setError: (error: string | null) => void,
|
|
147
|
+
setLoading: (loading: boolean) => void
|
|
148
|
+
): Promise<void> => {
|
|
149
|
+
if (!isMountedRef.current) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
setLoading(true);
|
|
154
|
+
setError(null);
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
const refreshedInfo = await repository.getAppInfo();
|
|
158
|
+
|
|
159
|
+
if (isMountedRef.current) {
|
|
160
|
+
setAppInfo(refreshedInfo);
|
|
161
|
+
}
|
|
162
|
+
} catch (err) {
|
|
163
|
+
setError(err instanceof Error ? err.message : 'Unknown error');
|
|
164
|
+
} finally {
|
|
165
|
+
setLoading(false);
|
|
166
|
+
}
|
|
167
|
+
};
|