@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.54",
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 { createDefaultAppInfo } from '../../utils/AppInfoFactory';
10
-
11
- export interface UseAboutInfoOptions {
12
- /** Initial configuration */
13
- initialConfig?: AboutConfig;
14
- /** Auto-initialize on mount */
15
- autoInit?: boolean;
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 setErrorIfMounted = useCallback((err: string | null) => {
50
- if (isMountedRef.current) {
51
- setError(err);
52
- }
53
- }, []);
54
-
55
- const setLoadingIfMounted = useCallback((value: boolean) => {
56
- if (isMountedRef.current) {
57
- setLoading(value);
58
- }
59
- }, []);
60
-
61
- const initialize = useCallback(async (config: AboutConfig, force = false) => {
62
- if (isInitializedRef.current && !force) {
63
- return;
64
- }
65
-
66
- if (!isMountedRef.current) {
67
- return;
68
- }
69
-
70
- setLoadingIfMounted(true);
71
- setErrorIfMounted(null);
72
-
73
- try {
74
- const defaultAppInfo = createDefaultAppInfo(config);
75
- await repository.saveAppInfo(defaultAppInfo);
76
-
77
- if (isMountedRef.current) {
78
- setAppInfo(defaultAppInfo);
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
- } catch (err) {
82
- setErrorIfMounted(err instanceof Error ? err.message : 'Unknown error');
83
- } finally {
84
- setLoadingIfMounted(false);
85
- }
86
- }, [repository, setErrorIfMounted, setLoadingIfMounted]);
87
-
88
- const update = useCallback(async (config: AboutConfig) => {
89
- if (!isMountedRef.current) {
90
- return;
91
- }
92
-
93
- setLoadingIfMounted(true);
94
- setErrorIfMounted(null);
95
-
96
- try {
97
- const updatedAppInfo = createDefaultAppInfo(config);
98
- await repository.saveAppInfo(updatedAppInfo);
99
-
100
- if (isMountedRef.current) {
101
- setAppInfo(updatedAppInfo);
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 (initialConfig && autoInit !== false && isMountedRef.current && !isInitializedRef.current) {
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, true);
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
+ };