@umituz/react-native-settings 4.20.58 → 4.20.59
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/.github/ISSUE_TEMPLATE/bug_report.md +51 -0
- package/.github/ISSUE_TEMPLATE/documentation.md +52 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +63 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +84 -0
- package/AI_AGENT_GUIDELINES.md +367 -0
- package/ARCHITECTURE.md +246 -0
- package/CHANGELOG.md +67 -0
- package/CODE_OF_CONDUCT.md +75 -0
- package/CONTRIBUTING.md +107 -0
- package/DOCUMENTATION_MIGRATION.md +319 -0
- package/DOCUMENTATION_TEMPLATE.md +155 -0
- package/LICENSE +21 -0
- package/README.md +321 -498
- package/SECURITY.md +98 -0
- package/SETTINGS_SCREEN_GUIDE.md +185 -0
- package/TESTING.md +358 -0
- package/package.json +13 -2
- package/src/application/README.md +85 -271
- package/src/domains/about/README.md +85 -440
- package/src/domains/about/presentation/hooks/README.md +93 -348
- package/src/domains/appearance/README.md +95 -584
- package/src/domains/appearance/hooks/README.md +95 -303
- package/src/domains/appearance/infrastructure/services/README.md +83 -397
- package/src/domains/appearance/presentation/components/README.md +95 -489
- package/src/domains/cloud-sync/README.md +73 -439
- package/src/domains/cloud-sync/presentation/components/README.md +95 -493
- package/src/domains/dev/README.md +71 -457
- package/src/domains/disclaimer/README.md +77 -411
- package/src/domains/disclaimer/presentation/components/README.md +95 -392
- package/src/domains/faqs/README.md +86 -574
- package/src/domains/feedback/README.md +79 -553
- package/src/domains/feedback/presentation/hooks/README.md +93 -426
- package/src/domains/legal/README.md +88 -537
- package/src/domains/rating/README.md +73 -440
- package/src/domains/rating/presentation/components/README.md +95 -475
- package/src/domains/video-tutorials/README.md +77 -470
- package/src/domains/video-tutorials/presentation/components/README.md +95 -431
- package/src/infrastructure/README.md +78 -425
- package/src/infrastructure/repositories/README.md +88 -420
- package/src/infrastructure/services/README.md +74 -460
- package/src/presentation/components/README.md +97 -480
- package/src/presentation/components/SettingsErrorBoundary/README.md +48 -436
- package/src/presentation/components/SettingsFooter/README.md +48 -427
- package/src/presentation/components/SettingsItemCard/README.md +152 -391
- package/src/presentation/components/SettingsItemCard/STRATEGY.md +164 -0
- package/src/presentation/components/SettingsSection/README.md +47 -401
- package/src/presentation/hooks/README.md +95 -389
- package/src/presentation/hooks/mutations/README.md +99 -376
- package/src/presentation/hooks/queries/README.md +111 -353
- package/src/presentation/navigation/README.md +70 -502
- package/src/presentation/navigation/components/README.md +70 -295
- package/src/presentation/navigation/hooks/README.md +75 -367
- package/src/presentation/navigation/utils/README.md +100 -380
- package/src/presentation/screens/README.md +53 -504
- package/src/presentation/screens/components/SettingsContent/README.md +53 -382
- package/src/presentation/screens/components/SettingsHeader/README.md +48 -303
- package/src/presentation/screens/components/sections/CustomSettingsList/README.md +47 -359
- package/src/presentation/screens/components/sections/FeatureSettingsSection/README.md +81 -176
- package/src/presentation/screens/components/sections/IdentitySettingsSection/README.md +40 -297
- package/src/presentation/screens/components/sections/ProfileSectionLoader/README.md +47 -451
- package/src/presentation/screens/components/sections/SupportSettingsSection/README.md +45 -361
- package/src/presentation/screens/hooks/README.md +64 -354
- package/src/presentation/screens/types/README.md +79 -409
- package/src/presentation/screens/utils/README.md +65 -255
|
@@ -1,413 +1,119 @@
|
|
|
1
1
|
# Presentation Hooks
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Purpose
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Custom React hooks for managing settings state, queries, and mutations in the presentation layer with TanStack Query integration.
|
|
6
|
+
|
|
7
|
+
## File Paths
|
|
8
|
+
|
|
9
|
+
- **Main Hook**: `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/presentation/hooks/useSettings.ts`
|
|
10
|
+
- **Queries**: `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/presentation/hooks/queries/useSettingsQuery.ts`
|
|
11
|
+
- **Mutations**: `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/presentation/hooks/mutations/useSettingsMutations.ts`
|
|
12
|
+
|
|
13
|
+
## Strategy
|
|
14
|
+
|
|
15
|
+
1. **TanStack Query Integration**: Leverages TanStack Query for caching, background updates, and error handling
|
|
16
|
+
2. **Simplified API**: Provides simple, high-level API for common settings operations
|
|
17
|
+
3. **Automatic Refetching**: Automatically refetches settings when data changes
|
|
18
|
+
4. **Optimistic Updates**: Supports optimistic updates for better UX
|
|
19
|
+
5. **Error Handling**: Built-in error management and loading states
|
|
20
|
+
|
|
21
|
+
## Restrictions (Forbidden)
|
|
22
|
+
|
|
23
|
+
### DO NOT
|
|
24
|
+
- ❌ DO NOT use these hooks without proper TanStack Query provider setup
|
|
25
|
+
- ❌ DO NOT call updateSettings with partial objects (must merge properly)
|
|
26
|
+
- ❌ DO NOT use mutations outside of component context
|
|
27
|
+
|
|
28
|
+
### NEVER
|
|
29
|
+
- ❌ NEVER use hooks outside React components or custom hooks
|
|
30
|
+
- ❌ NEVER mutate settings state directly (use updateSettings)
|
|
31
|
+
- ❌ NEVER ignore error states from hooks
|
|
32
|
+
|
|
33
|
+
### AVOID
|
|
34
|
+
- ❌ AVOID calling updateSettings in rapid succession (debounce if needed)
|
|
35
|
+
- ❌ AVOID resetting settings without user confirmation
|
|
36
|
+
- ❌ AVOID using raw query hooks (use useSettings instead)
|
|
37
|
+
|
|
38
|
+
## Rules (Mandatory)
|
|
39
|
+
|
|
40
|
+
### ALWAYS
|
|
41
|
+
- ✅ ALWAYS handle loading and error states
|
|
42
|
+
- ✅ ALWAYS wrap settings provider at app root
|
|
43
|
+
- ✅ MUST use updateSettings for changes (not direct mutation)
|
|
44
|
+
- ✅ MUST confirm before resetting settings
|
|
45
|
+
|
|
46
|
+
### MUST
|
|
47
|
+
- ✅ MUST provide user ID to useSettings hook
|
|
48
|
+
- ✅ MUST handle network errors gracefully
|
|
49
|
+
- ✅ MUST show loading states during initial fetch
|
|
50
|
+
|
|
51
|
+
### SHOULD
|
|
52
|
+
- ✅ SHOULD use optimistic updates for immediate UI feedback
|
|
53
|
+
- ✅ SHOULD show success/error messages after updates
|
|
54
|
+
- ✅ SHOULD debounce rapid settings changes
|
|
55
|
+
|
|
56
|
+
## AI Agent Guidelines
|
|
57
|
+
|
|
58
|
+
1. **File Reference**: When modifying hooks, refer to `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/presentation/hooks/`
|
|
59
|
+
2. **Provider Setup**: Always wrap app with SettingsProvider at root level
|
|
60
|
+
3. **Query Client**: Ensure TanStack QueryClient is properly configured
|
|
61
|
+
4. **Error Handling**: Always handle error states in UI
|
|
62
|
+
5. **Performance**: Hooks are already optimized with useMemo and useCallback
|
|
63
|
+
|
|
64
|
+
## Hook Reference
|
|
6
65
|
|
|
7
66
|
### useSettings
|
|
8
67
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
```tsx
|
|
12
|
-
import { useSettings } from '@umituz/react-native-settings';
|
|
13
|
-
|
|
14
|
-
function SettingsComponent() {
|
|
15
|
-
const { settings, loading, error, updateSettings, resetSettings } = useSettings('user123');
|
|
16
|
-
|
|
17
|
-
if (loading) return <LoadingSpinner />;
|
|
18
|
-
if (error) return <ErrorMessage message={error} />;
|
|
19
|
-
|
|
20
|
-
return (
|
|
21
|
-
<View>
|
|
22
|
-
<Text>Theme: {settings?.theme}</Text>
|
|
23
|
-
<Button
|
|
24
|
-
title="Toggle Dark Mode"
|
|
25
|
-
onPress={() => updateSettings({ theme: 'dark' })}
|
|
26
|
-
/>
|
|
27
|
-
</View>
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
#### Return Value
|
|
33
|
-
|
|
34
|
-
| Property | Type | Description |
|
|
35
|
-
|----------|------|-------------|
|
|
36
|
-
| `settings` | `UserSettings \| null` | Current user settings |
|
|
37
|
-
| `loading` | `boolean` | Loading state |
|
|
38
|
-
| `error` | `string \| null` | Error message |
|
|
39
|
-
| `updateSettings` | `(updates) => Promise<void>` | Update settings function |
|
|
40
|
-
| `resetSettings` | `() => Promise<void>` | Reset to defaults function |
|
|
41
|
-
|
|
42
|
-
#### Example
|
|
43
|
-
|
|
44
|
-
```tsx
|
|
45
|
-
function ThemeToggle() {
|
|
46
|
-
const { settings, updateSettings } = useSettings(userId);
|
|
47
|
-
|
|
48
|
-
const toggleTheme = () => {
|
|
49
|
-
const newTheme = settings?.theme === 'light' ? 'dark' : 'light';
|
|
50
|
-
updateSettings({ theme: newTheme });
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
return (
|
|
54
|
-
<Switch
|
|
55
|
-
value={settings?.theme === 'dark'}
|
|
56
|
-
onValueChange={toggleTheme}
|
|
57
|
-
/>
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
```
|
|
68
|
+
**Purpose**: Main hook for accessing and managing user settings
|
|
61
69
|
|
|
62
|
-
|
|
70
|
+
**Parameters**:
|
|
71
|
+
- `userId`: User identifier string
|
|
63
72
|
|
|
64
|
-
|
|
73
|
+
**Returns**:
|
|
74
|
+
- `settings`: Current user settings object
|
|
75
|
+
- `loading`: Boolean loading state
|
|
76
|
+
- `error`: Error message or null
|
|
77
|
+
- `updateSettings`: Function to update settings
|
|
78
|
+
- `resetSettings`: Function to reset to defaults
|
|
65
79
|
|
|
66
|
-
|
|
67
|
-
import { useSettingsQuery } from '@umituz/react-native-settings';
|
|
80
|
+
**Usage**: Primary hook for most settings operations
|
|
68
81
|
|
|
69
|
-
|
|
70
|
-
const { data, isLoading, error } = useSettingsQuery('user123');
|
|
82
|
+
### useSettingsQuery
|
|
71
83
|
|
|
72
|
-
|
|
73
|
-
if (error) return <Text>Error loading settings</Text>;
|
|
84
|
+
**Purpose**: TanStack Query integration for fetching settings
|
|
74
85
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
```
|
|
86
|
+
**Parameters**:
|
|
87
|
+
- `userId`: User identifier string
|
|
78
88
|
|
|
79
|
-
|
|
89
|
+
**Returns**: TanStack Query result object
|
|
90
|
+
|
|
91
|
+
**Usage**: Use when you need direct query access
|
|
80
92
|
|
|
81
|
-
|
|
93
|
+
### useUpdateSettingsMutation
|
|
82
94
|
|
|
83
|
-
|
|
84
|
-
import { useUpdateSettingsMutation } from '@umituz/react-native-settings';
|
|
95
|
+
**Purpose**: Mutation hook for updating settings
|
|
85
96
|
|
|
86
|
-
|
|
87
|
-
|
|
97
|
+
**Parameters**:
|
|
98
|
+
- `userId`: User identifier string
|
|
88
99
|
|
|
89
|
-
|
|
90
|
-
await mutation.mutateAsync({ theme: 'dark' });
|
|
91
|
-
};
|
|
100
|
+
**Returns**: TanStack Query mutation object
|
|
92
101
|
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
```
|
|
102
|
+
**Usage**: Use for update operations with mutation callbacks
|
|
96
103
|
|
|
97
104
|
### useResetSettingsMutation
|
|
98
105
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
```tsx
|
|
102
|
-
import { useResetSettingsMutation } from '@umituz/react-native-settings';
|
|
103
|
-
|
|
104
|
-
function ResetButton() {
|
|
105
|
-
const mutation = useResetSettingsMutation('user123');
|
|
106
|
-
|
|
107
|
-
return (
|
|
108
|
-
<Button
|
|
109
|
-
onPress={() => mutation.mutateAsync()}
|
|
110
|
-
title="Reset to Defaults"
|
|
111
|
-
/>
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
## Usage Examples
|
|
117
|
-
|
|
118
|
-
### Complete Settings Management
|
|
119
|
-
|
|
120
|
-
```tsx
|
|
121
|
-
import { useSettings } from '@umituz/react-native-settings';
|
|
122
|
-
|
|
123
|
-
function SettingsManager() {
|
|
124
|
-
const { settings, loading, error, updateSettings, resetSettings } = useSettings(userId);
|
|
125
|
-
|
|
126
|
-
const handleThemeChange = (theme: 'light' | 'dark') => {
|
|
127
|
-
updateSettings({ theme });
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
const handleLanguageChange = (language: string) => {
|
|
131
|
-
updateSettings({ language });
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
const handleNotificationsToggle = () => {
|
|
135
|
-
updateSettings({
|
|
136
|
-
notificationsEnabled: !settings?.notificationsEnabled,
|
|
137
|
-
});
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
const handleReset = async () => {
|
|
141
|
-
Alert.alert(
|
|
142
|
-
'Reset Settings',
|
|
143
|
-
'Are you sure you want to reset all settings?',
|
|
144
|
-
[
|
|
145
|
-
{ text: 'Cancel', style: 'cancel' },
|
|
146
|
-
{
|
|
147
|
-
text: 'Reset',
|
|
148
|
-
style: 'destructive',
|
|
149
|
-
onPress: async () => {
|
|
150
|
-
await resetSettings();
|
|
151
|
-
Alert.alert('Success', 'Settings have been reset');
|
|
152
|
-
},
|
|
153
|
-
},
|
|
154
|
-
]
|
|
155
|
-
);
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
if (loading) return <LoadingScreen />;
|
|
159
|
-
if (error) return <ErrorScreen message={error} />;
|
|
160
|
-
|
|
161
|
-
return (
|
|
162
|
-
<ScreenLayout>
|
|
163
|
-
<SettingsSection title="APPEARANCE">
|
|
164
|
-
<SettingsItemCard
|
|
165
|
-
icon="moon-outline"
|
|
166
|
-
title="Dark Mode"
|
|
167
|
-
showSwitch={true}
|
|
168
|
-
switchValue={settings?.theme === 'dark'}
|
|
169
|
-
onSwitchChange={() => handleThemeChange('dark')}
|
|
170
|
-
/>
|
|
171
|
-
<SettingsItemCard
|
|
172
|
-
icon="globe-outline"
|
|
173
|
-
title="Language"
|
|
174
|
-
description={settings?.language}
|
|
175
|
-
onPress={() => setShowLanguageSelector(true)}
|
|
176
|
-
/>
|
|
177
|
-
</SettingsSection>
|
|
178
|
-
|
|
179
|
-
<SettingsSection title="NOTIFICATIONS">
|
|
180
|
-
<SettingsItemCard
|
|
181
|
-
icon="notifications-outline"
|
|
182
|
-
title="Enable Notifications"
|
|
183
|
-
showSwitch={true}
|
|
184
|
-
switchValue={settings?.notificationsEnabled}
|
|
185
|
-
onSwitchChange={handleNotificationsToggle}
|
|
186
|
-
/>
|
|
187
|
-
</SettingsSection>
|
|
188
|
-
|
|
189
|
-
<SettingsSection title="DANGER ZONE">
|
|
190
|
-
<SettingsItemCard
|
|
191
|
-
icon="refresh-outline"
|
|
192
|
-
title="Reset Settings"
|
|
193
|
-
description="Reset all settings to defaults"
|
|
194
|
-
onPress={handleReset}
|
|
195
|
-
iconColor="#DC2626"
|
|
196
|
-
/>
|
|
197
|
-
</SettingsSection>
|
|
198
|
-
</ScreenLayout>
|
|
199
|
-
);
|
|
200
|
-
}
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
### Multiple Settings Updates
|
|
204
|
-
|
|
205
|
-
```tsx
|
|
206
|
-
function BulkUpdate() {
|
|
207
|
-
const { updateSettings, settings } = useSettings(userId);
|
|
208
|
-
|
|
209
|
-
const enableAllFeatures = async () => {
|
|
210
|
-
await updateSettings({
|
|
211
|
-
notificationsEnabled: true,
|
|
212
|
-
soundEnabled: true,
|
|
213
|
-
vibrationEnabled: true,
|
|
214
|
-
emailNotifications: true,
|
|
215
|
-
pushNotifications: true,
|
|
216
|
-
});
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
const disableAllFeatures = async () => {
|
|
220
|
-
await updateSettings({
|
|
221
|
-
notificationsEnabled: false,
|
|
222
|
-
soundEnabled: false,
|
|
223
|
-
vibrationEnabled: false,
|
|
224
|
-
emailNotifications: false,
|
|
225
|
-
pushNotifications: false,
|
|
226
|
-
});
|
|
227
|
-
};
|
|
228
|
-
|
|
229
|
-
return (
|
|
230
|
-
<View>
|
|
231
|
-
<Button title="Enable All" onPress={enableAllFeatures} />
|
|
232
|
-
<Button title="Disable All" onPress={disableAllFeatures} />
|
|
233
|
-
</View>
|
|
234
|
-
);
|
|
235
|
-
}
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
### Optimistic Updates
|
|
239
|
-
|
|
240
|
-
```tsx
|
|
241
|
-
function OptimisticThemeToggle() {
|
|
242
|
-
const { settings, updateSettings } = useSettings(userId);
|
|
243
|
-
const [localTheme, setLocalTheme] = useState(settings?.theme);
|
|
244
|
-
|
|
245
|
-
const handleToggle = async () => {
|
|
246
|
-
const newTheme = localTheme === 'light' ? 'dark' : 'light';
|
|
247
|
-
|
|
248
|
-
// Optimistic update
|
|
249
|
-
setLocalTheme(newTheme);
|
|
250
|
-
|
|
251
|
-
try {
|
|
252
|
-
await updateSettings({ theme: newTheme });
|
|
253
|
-
} catch (error) {
|
|
254
|
-
// Revert on error
|
|
255
|
-
setLocalTheme(settings?.theme);
|
|
256
|
-
Alert.alert('Error', 'Failed to update theme');
|
|
257
|
-
}
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
return (
|
|
261
|
-
<Switch
|
|
262
|
-
value={localTheme === 'dark'}
|
|
263
|
-
onValueChange={handleToggle}
|
|
264
|
-
/>
|
|
265
|
-
);
|
|
266
|
-
}
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
### Error Handling
|
|
270
|
-
|
|
271
|
-
```tsx
|
|
272
|
-
function SettingsWithErrorHandling() {
|
|
273
|
-
const { settings, updateSettings, error } = useSettings(userId);
|
|
274
|
-
|
|
275
|
-
const handleUpdate = async () => {
|
|
276
|
-
try {
|
|
277
|
-
await updateSettings({ theme: 'dark' });
|
|
278
|
-
Alert.alert('Success', 'Settings updated');
|
|
279
|
-
} catch (err) {
|
|
280
|
-
Alert.alert('Error', 'Failed to update settings');
|
|
281
|
-
}
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
useEffect(() => {
|
|
285
|
-
if (error) {
|
|
286
|
-
Alert.alert('Settings Error', error);
|
|
287
|
-
}
|
|
288
|
-
}, [error]);
|
|
289
|
-
|
|
290
|
-
return (
|
|
291
|
-
<Button
|
|
292
|
-
title="Update Theme"
|
|
293
|
-
onPress={handleUpdate}
|
|
294
|
-
disabled={!settings}
|
|
295
|
-
/>
|
|
296
|
-
);
|
|
297
|
-
}
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
### Loading States
|
|
301
|
-
|
|
302
|
-
```tsx
|
|
303
|
-
function SettingsWithLoadingStates() {
|
|
304
|
-
const { settings, loading, updateSettings } = useSettings(userId);
|
|
305
|
-
const [isUpdating, setIsUpdating] = useState(false);
|
|
306
|
-
|
|
307
|
-
const handleUpdate = async () => {
|
|
308
|
-
setIsUpdating(true);
|
|
309
|
-
try {
|
|
310
|
-
await updateSettings({ theme: 'dark' });
|
|
311
|
-
} finally {
|
|
312
|
-
setIsUpdating(false);
|
|
313
|
-
}
|
|
314
|
-
};
|
|
315
|
-
|
|
316
|
-
if (loading) {
|
|
317
|
-
return (
|
|
318
|
-
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
|
|
319
|
-
<ActivityIndicator size="large" />
|
|
320
|
-
<Text style={{ marginTop: 16 }}>Loading settings...</Text>
|
|
321
|
-
</View>
|
|
322
|
-
);
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
return (
|
|
326
|
-
<Button
|
|
327
|
-
title={isUpdating ? 'Updating...' : 'Update Theme'}
|
|
328
|
-
onPress={handleUpdate}
|
|
329
|
-
disabled={loading || isUpdating}
|
|
330
|
-
/>
|
|
331
|
-
);
|
|
332
|
-
}
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
## Hook Dependencies
|
|
336
|
-
|
|
337
|
-
```
|
|
338
|
-
presentation/hooks/
|
|
339
|
-
├── useSettings.ts # Main settings hook
|
|
340
|
-
├── queries/
|
|
341
|
-
│ └── useSettingsQuery.ts # TanStack Query integration
|
|
342
|
-
└── mutations/
|
|
343
|
-
└── useSettingsMutations.ts # Mutation hooks
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
## Integration with TanStack Query
|
|
347
|
-
|
|
348
|
-
These hooks use TanStack Query for:
|
|
349
|
-
|
|
350
|
-
- **Caching**: Automatic caching of settings data
|
|
351
|
-
- **Background Updates**: Automatic refetching
|
|
352
|
-
- **Optimistic Updates**: UI updates before server confirmation
|
|
353
|
-
- **Error Handling**: Built-in error management
|
|
354
|
-
- **Loading States**: Automatic loading state management
|
|
355
|
-
|
|
356
|
-
## Best Practices
|
|
357
|
-
|
|
358
|
-
1. **Use useSettings**: Prefer the main hook for most use cases
|
|
359
|
-
2. **Handle Loading**: Always handle loading state
|
|
360
|
-
3. **Error Handling**: Implement proper error handling
|
|
361
|
-
4. **Optimistic Updates**: Use optimistic updates for better UX
|
|
362
|
-
5. **Partial Updates**: Use partial updates to only change needed fields
|
|
363
|
-
6. **Reset Confirmation**: Always confirm before resetting settings
|
|
364
|
-
|
|
365
|
-
## Testing
|
|
366
|
-
|
|
367
|
-
```tsx
|
|
368
|
-
import { renderHook, act, waitFor } from '@testing-library/react-native';
|
|
369
|
-
import { useSettings } from '@umituz/react-native-settings';
|
|
370
|
-
|
|
371
|
-
describe('useSettings', () => {
|
|
372
|
-
it('loads settings for user', async () => {
|
|
373
|
-
const { result } = renderHook(() => useSettings('user123'));
|
|
374
|
-
|
|
375
|
-
expect(result.current.loading).toBe(true);
|
|
376
|
-
|
|
377
|
-
await waitFor(() => {
|
|
378
|
-
expect(result.current.loading).toBe(false);
|
|
379
|
-
expect(result.current.settings).toBeDefined();
|
|
380
|
-
});
|
|
381
|
-
});
|
|
382
|
-
|
|
383
|
-
it('updates settings', async () => {
|
|
384
|
-
const { result } = renderHook(() => useSettings('user123'));
|
|
385
|
-
|
|
386
|
-
await act(async () => {
|
|
387
|
-
await result.current.updateSettings({ theme: 'dark' });
|
|
388
|
-
});
|
|
389
|
-
|
|
390
|
-
expect(result.current.settings?.theme).toBe('dark');
|
|
391
|
-
});
|
|
392
|
-
|
|
393
|
-
it('resets settings', async () => {
|
|
394
|
-
const { result } = renderHook(() => useSettings('user123'));
|
|
395
|
-
|
|
396
|
-
await act(async () => {
|
|
397
|
-
await result.current.resetSettings();
|
|
398
|
-
});
|
|
399
|
-
|
|
400
|
-
expect(result.current.settings?.theme).toBe('auto');
|
|
401
|
-
});
|
|
402
|
-
});
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
## Related
|
|
106
|
+
**Purpose**: Mutation hook for resetting settings
|
|
406
107
|
|
|
407
|
-
|
|
408
|
-
-
|
|
409
|
-
|
|
108
|
+
**Parameters**:
|
|
109
|
+
- `userId`: User identifier string
|
|
110
|
+
|
|
111
|
+
**Returns**: TanStack Query mutation object
|
|
410
112
|
|
|
411
|
-
|
|
113
|
+
**Usage**: Use for reset operations with confirmation
|
|
412
114
|
|
|
413
|
-
|
|
115
|
+
## Related Components
|
|
116
|
+
|
|
117
|
+
- **Application Layer**: Repository interfaces and types
|
|
118
|
+
- **Infrastructure**: Storage implementation
|
|
119
|
+
- **Presentation Components**: UI components that use these hooks
|