@umituz/react-native-settings 4.20.55 → 4.20.57
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/README.md +145 -3
- package/package.json +1 -2
- package/src/application/README.md +322 -0
- package/src/domains/about/README.md +452 -0
- package/src/domains/about/presentation/hooks/README.md +350 -0
- package/src/domains/appearance/README.md +596 -0
- package/src/domains/appearance/hooks/README.md +366 -0
- package/src/domains/appearance/infrastructure/services/README.md +455 -0
- package/src/domains/cloud-sync/README.md +451 -0
- package/src/domains/cloud-sync/presentation/components/README.md +493 -0
- package/src/domains/dev/README.md +477 -0
- package/src/domains/disclaimer/README.md +421 -0
- package/src/domains/disclaimer/presentation/components/README.md +394 -0
- package/src/domains/faqs/README.md +586 -0
- package/src/domains/feedback/README.md +565 -0
- package/src/domains/feedback/presentation/hooks/README.md +428 -0
- package/src/domains/legal/README.md +549 -0
- package/src/domains/rating/README.md +452 -0
- package/src/domains/rating/presentation/components/README.md +475 -0
- package/src/domains/video-tutorials/README.md +482 -0
- package/src/domains/video-tutorials/presentation/components/README.md +433 -0
- package/src/infrastructure/README.md +509 -0
- package/src/infrastructure/repositories/README.md +475 -0
- package/src/infrastructure/services/README.md +510 -0
- package/src/presentation/components/README.md +482 -0
- package/src/presentation/components/SettingsErrorBoundary/README.md +461 -0
- package/src/presentation/components/SettingsFooter/README.md +446 -0
- package/src/presentation/components/SettingsItemCard/README.md +457 -0
- package/src/presentation/components/SettingsSection/README.md +421 -0
- package/src/presentation/hooks/README.md +413 -0
- package/src/presentation/hooks/mutations/README.md +430 -0
- package/src/presentation/hooks/queries/README.md +441 -0
- package/src/presentation/navigation/README.md +532 -0
- package/src/presentation/navigation/components/README.md +330 -0
- package/src/presentation/navigation/hooks/README.md +399 -0
- package/src/presentation/navigation/utils/README.md +442 -0
- package/src/presentation/screens/README.md +525 -0
- package/src/presentation/screens/components/SettingsContent/README.md +404 -0
- package/src/presentation/screens/components/SettingsHeader/README.md +322 -0
- package/src/presentation/screens/components/sections/CustomSettingsList/README.md +388 -0
- package/src/presentation/screens/components/sections/FeatureSettingsSection/README.md +232 -0
- package/src/presentation/screens/components/sections/IdentitySettingsSection/README.md +325 -0
- package/src/presentation/screens/components/sections/ProfileSectionLoader/README.md +480 -0
- package/src/presentation/screens/components/sections/SupportSettingsSection/README.md +391 -0
- package/src/presentation/screens/hooks/README.md +383 -0
- package/src/presentation/screens/types/README.md +439 -0
- package/src/presentation/screens/utils/README.md +288 -0
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
# useFeatureDetection Hook
|
|
2
|
+
|
|
3
|
+
Hook for automatically detecting which settings features should be shown based on configuration and navigation state.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Auto Detection**: Automatically detects available screens
|
|
8
|
+
- **Config Override**: Respects explicit enabled/disabled flags
|
|
9
|
+
- **Service Check**: Checks for required services (e.g., notifications)
|
|
10
|
+
- **Navigation Check**: Verifies screen exists in navigation stack
|
|
11
|
+
- **Memoized**: Optimized with useMemo for performance
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
This hook is part of `@umituz/react-native-settings`.
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### Basic Usage
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { useFeatureDetection } from '@umituz/react-native-settings';
|
|
23
|
+
|
|
24
|
+
function MySettingsScreen() {
|
|
25
|
+
const navigation = useNavigation();
|
|
26
|
+
const normalizedConfig = normalizeSettingsConfig(config);
|
|
27
|
+
|
|
28
|
+
const features = useFeatureDetection(normalizedConfig, navigation);
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<View>
|
|
32
|
+
{features.appearance && <Text>Appearance is available</Text>}
|
|
33
|
+
{features.language && <Text>Language is available</Text>}
|
|
34
|
+
</View>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## API
|
|
40
|
+
|
|
41
|
+
### Parameters
|
|
42
|
+
|
|
43
|
+
| Parameter | Type | Description |
|
|
44
|
+
|-----------|------|-------------|
|
|
45
|
+
| `normalizedConfig` | `NormalizedConfig` | Normalized configuration object |
|
|
46
|
+
| `navigation` | `NavigationProp` | React Navigation object |
|
|
47
|
+
| `options` | `DetectionOptions` | Optional detection options |
|
|
48
|
+
|
|
49
|
+
### DetectionOptions
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
interface DetectionOptions {
|
|
53
|
+
notificationServiceAvailable?: boolean;
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Returns
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
interface FeatureFlags {
|
|
61
|
+
appearance: boolean; // Is appearance screen available?
|
|
62
|
+
language: boolean; // Is language screen available?
|
|
63
|
+
notifications: boolean; // Are notifications available?
|
|
64
|
+
about: boolean; // Is about screen available?
|
|
65
|
+
legal: boolean; // Is legal screen available?
|
|
66
|
+
disclaimer: boolean; // Is disclaimer available?
|
|
67
|
+
userProfile: boolean; // Should show user profile?
|
|
68
|
+
feedback: boolean; // Is feedback available?
|
|
69
|
+
rating: boolean; // Is rating available?
|
|
70
|
+
faqs: boolean; // Are FAQs available?
|
|
71
|
+
subscription: boolean; // Is subscription available?
|
|
72
|
+
wallet: boolean; // Is wallet available?
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Detection Logic
|
|
77
|
+
|
|
78
|
+
### Auto Detection Algorithm
|
|
79
|
+
|
|
80
|
+
For each feature:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
function shouldShowFeature(
|
|
84
|
+
normalizedConfig,
|
|
85
|
+
navigation,
|
|
86
|
+
options
|
|
87
|
+
): boolean {
|
|
88
|
+
const { enabled, config } = normalizedConfig;
|
|
89
|
+
|
|
90
|
+
// Check normalized enabled flag
|
|
91
|
+
if (!enabled) return false;
|
|
92
|
+
|
|
93
|
+
// Explicit override in config object
|
|
94
|
+
if (config?.enabled === true) return true;
|
|
95
|
+
if (config?.enabled === false) return false;
|
|
96
|
+
|
|
97
|
+
// Auto-detect based on navigation
|
|
98
|
+
const defaultRoute = getDefaultRoute(feature);
|
|
99
|
+
return hasNavigationScreen(navigation, defaultRoute);
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Navigation Screen Check
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
function hasNavigationScreen(
|
|
107
|
+
navigation: any,
|
|
108
|
+
screenName: string
|
|
109
|
+
): boolean {
|
|
110
|
+
try {
|
|
111
|
+
const state = navigation.getState();
|
|
112
|
+
if (!state) return false;
|
|
113
|
+
|
|
114
|
+
const checkRoutes = (routes: any[]): boolean => {
|
|
115
|
+
for (const route of routes) {
|
|
116
|
+
if (route.name === screenName) return true;
|
|
117
|
+
if (route.state?.routes && checkRoutes(route.state.routes)) {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
return checkRoutes(state.routes || []);
|
|
125
|
+
} catch {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Examples
|
|
132
|
+
|
|
133
|
+
### With Auto Detection
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
function AutoDetectedSettings() {
|
|
137
|
+
const navigation = useNavigation();
|
|
138
|
+
const config = {
|
|
139
|
+
appearance: 'auto', // Will detect Appearance screen
|
|
140
|
+
language: 'auto', // Will detect Language screen
|
|
141
|
+
notifications: 'auto', // Will detect Notifications screen
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const normalized = normalizeSettingsConfig(config);
|
|
145
|
+
const features = useFeatureDetection(normalized, navigation);
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<SettingsContent
|
|
149
|
+
normalizedConfig={normalized}
|
|
150
|
+
features={features}
|
|
151
|
+
/>
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### With Service Check
|
|
157
|
+
|
|
158
|
+
```tsx
|
|
159
|
+
function SettingsWithServiceCheck() {
|
|
160
|
+
const navigation = useNavigation();
|
|
161
|
+
const notificationServiceAvailable = true; // From app state
|
|
162
|
+
|
|
163
|
+
const features = useFeatureDetection(normalizedConfig, navigation, {
|
|
164
|
+
notificationServiceAvailable,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// notifications will only be true if:
|
|
168
|
+
// 1. enabled in config
|
|
169
|
+
// 2. notificationServiceAvailable is true
|
|
170
|
+
// 3. Notifications screen exists
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### With Custom Routes
|
|
175
|
+
|
|
176
|
+
```tsx
|
|
177
|
+
function SettingsWithCustomRoutes() {
|
|
178
|
+
const config = {
|
|
179
|
+
appearance: {
|
|
180
|
+
enabled: true,
|
|
181
|
+
route: 'CustomAppearance', // Custom screen name
|
|
182
|
+
},
|
|
183
|
+
language: {
|
|
184
|
+
enabled: true,
|
|
185
|
+
route: 'LanguagePicker', // Custom screen name
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
const features = useFeatureDetection(
|
|
190
|
+
normalizeSettingsConfig(config),
|
|
191
|
+
navigation
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Explicit Enable/Disable
|
|
197
|
+
|
|
198
|
+
```tsx
|
|
199
|
+
function ExplicitlyConfiguredSettings() {
|
|
200
|
+
const config = {
|
|
201
|
+
appearance: true, // Always show
|
|
202
|
+
language: false, // Never show
|
|
203
|
+
notifications: {
|
|
204
|
+
enabled: true, // Explicitly enabled
|
|
205
|
+
route: 'Notifications', // Will check this route
|
|
206
|
+
},
|
|
207
|
+
about: {
|
|
208
|
+
enabled: false, // Explicitly disabled
|
|
209
|
+
route: 'About', // Won't check even if exists
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
const features = useFeatureDetection(
|
|
214
|
+
normalizeSettingsConfig(config),
|
|
215
|
+
navigation
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
// features.appearance === true
|
|
219
|
+
// features.language === false
|
|
220
|
+
// features.notifications === (has Notifications screen)
|
|
221
|
+
// features.about === false
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Combined Configuration
|
|
226
|
+
|
|
227
|
+
```tsx
|
|
228
|
+
function MixedConfiguration() {
|
|
229
|
+
const config = {
|
|
230
|
+
// Simple boolean
|
|
231
|
+
appearance: true,
|
|
232
|
+
|
|
233
|
+
// Auto-detect
|
|
234
|
+
language: 'auto',
|
|
235
|
+
|
|
236
|
+
// Advanced with explicit enabled
|
|
237
|
+
notifications: {
|
|
238
|
+
enabled: true,
|
|
239
|
+
route: 'Notifications',
|
|
240
|
+
showQuietHours: true,
|
|
241
|
+
},
|
|
242
|
+
|
|
243
|
+
// Advanced with auto-detection
|
|
244
|
+
about: {
|
|
245
|
+
enabled: 'auto',
|
|
246
|
+
route: 'About',
|
|
247
|
+
},
|
|
248
|
+
|
|
249
|
+
// Explicitly disabled
|
|
250
|
+
legal: false,
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
const features = useFeatureDetection(
|
|
254
|
+
normalizeSettingsConfig(config),
|
|
255
|
+
navigation
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Default Routes
|
|
261
|
+
|
|
262
|
+
Default screen routes checked for each feature:
|
|
263
|
+
|
|
264
|
+
| Feature | Default Route |
|
|
265
|
+
|---------|--------------|
|
|
266
|
+
| `appearance` | `'Appearance'` |
|
|
267
|
+
| `language` | `'LanguageSelection'` |
|
|
268
|
+
| `notifications` | `'Notifications'` |
|
|
269
|
+
| `about` | `'About'` |
|
|
270
|
+
| `legal` | `'Legal'` |
|
|
271
|
+
| `disclaimer` | `'Disclaimer'` |
|
|
272
|
+
|
|
273
|
+
## Feature-Specific Logic
|
|
274
|
+
|
|
275
|
+
### Notifications
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
notifications: notifications.enabled && (
|
|
279
|
+
notifications.config?.enabled === true ||
|
|
280
|
+
(notifications.config?.enabled !== false &&
|
|
281
|
+
notificationServiceAvailable &&
|
|
282
|
+
hasNavigationScreen(navigation, 'Notifications'))
|
|
283
|
+
)
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Requires both:
|
|
287
|
+
- Service availability check
|
|
288
|
+
- Navigation screen check
|
|
289
|
+
|
|
290
|
+
### Profile, Feedback, Rating, FAQs
|
|
291
|
+
|
|
292
|
+
These features don't check navigation:
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
userProfile: userProfile.enabled,
|
|
296
|
+
feedback: feedback.enabled,
|
|
297
|
+
rating: rating.enabled,
|
|
298
|
+
faqs: faqs.enabled,
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Performance
|
|
302
|
+
|
|
303
|
+
### Memoization
|
|
304
|
+
|
|
305
|
+
The hook uses `useMemo` to prevent unnecessary recalculations:
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
const features = useMemo(() => {
|
|
309
|
+
// Detection logic
|
|
310
|
+
}, [normalizedConfig, navigation, options]);
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Dependencies
|
|
314
|
+
|
|
315
|
+
Recalculates when:
|
|
316
|
+
- `normalizedConfig` changes
|
|
317
|
+
- `navigation` changes (should be stable)
|
|
318
|
+
- `options` changes
|
|
319
|
+
|
|
320
|
+
## Best Practices
|
|
321
|
+
|
|
322
|
+
1. **Normalize First**: Always normalize config before passing to hook
|
|
323
|
+
2. **Use Auto**: Prefer `'auto'` for automatic detection
|
|
324
|
+
3. **Service Checks**: Provide service availability in options
|
|
325
|
+
4. **Custom Routes**: Define custom routes in config objects
|
|
326
|
+
5. **Explicit Flags**: Use boolean for must-show/must-hide features
|
|
327
|
+
6. **Stable Navigation**: Pass stable navigation reference
|
|
328
|
+
7. **Memoization**: Hook is already memoized for performance
|
|
329
|
+
|
|
330
|
+
## Testing
|
|
331
|
+
|
|
332
|
+
```tsx
|
|
333
|
+
import { renderHook } from '@testing-library/react-native';
|
|
334
|
+
import { useFeatureDetection } from '@umituz/react-native-settings';
|
|
335
|
+
|
|
336
|
+
describe('useFeatureDetection', () => {
|
|
337
|
+
it('detects available screens', () => {
|
|
338
|
+
const navigation = {
|
|
339
|
+
getState: () => ({
|
|
340
|
+
routes: [
|
|
341
|
+
{ name: 'Appearance' },
|
|
342
|
+
{ name: 'LanguageSelection' },
|
|
343
|
+
],
|
|
344
|
+
}),
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
const config = {
|
|
348
|
+
appearance: 'auto',
|
|
349
|
+
language: 'auto',
|
|
350
|
+
notifications: 'auto',
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
const { result } = renderHook(() =>
|
|
354
|
+
useFeatureDetection(normalizeSettingsConfig(config), navigation)
|
|
355
|
+
);
|
|
356
|
+
|
|
357
|
+
expect(result.current.appearance).toBe(true);
|
|
358
|
+
expect(result.current.language).toBe(true);
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
it('respects explicit disabled', () => {
|
|
362
|
+
const config = {
|
|
363
|
+
appearance: false, // Explicitly disabled
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
const { result } = renderHook(() =>
|
|
367
|
+
useFeatureDetection(normalizeSettingsConfig(config), navigation)
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
expect(result.current.appearance).toBe(false);
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
## Related
|
|
376
|
+
|
|
377
|
+
- **normalizeSettingsConfig**: Config normalization
|
|
378
|
+
- **SettingsContent**: Content component
|
|
379
|
+
- **Feature Detection**: Detection utility functions
|
|
380
|
+
|
|
381
|
+
## License
|
|
382
|
+
|
|
383
|
+
MIT
|