@umituz/react-native-settings 4.20.56 → 4.20.58
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 +146 -4
- package/package.json +1 -2
- package/src/__tests__/setup.ts +1 -4
- 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/appearance/presentation/components/README.md +493 -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 +455 -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,475 @@
|
|
|
1
|
+
# Settings Repository
|
|
2
|
+
|
|
3
|
+
Repository implementation for settings data persistence using `@umituz/react-native-storage`.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Data Persistence**: Stores and retrieves user settings
|
|
8
|
+
- **Automatic Defaults**: Creates default settings for new users
|
|
9
|
+
- **Type Safety**: Full TypeScript support
|
|
10
|
+
- **Error Handling**: Comprehensive error catching
|
|
11
|
+
- **Storage Integration**: Uses storage repository
|
|
12
|
+
- **Performance**: Optimized for frequent reads
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
This repository is part of `@umituz/react-native-settings`.
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
### Basic Usage
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { SettingsRepository } from '@umituz/react-native-settings';
|
|
24
|
+
|
|
25
|
+
const repository = new SettingsRepository();
|
|
26
|
+
|
|
27
|
+
// Get settings
|
|
28
|
+
const settings = await repository.get('user123');
|
|
29
|
+
|
|
30
|
+
// Update settings
|
|
31
|
+
const updated = await repository.update('user123', {
|
|
32
|
+
theme: 'dark',
|
|
33
|
+
language: 'tr-TR',
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Reset settings
|
|
37
|
+
const defaults = await repository.reset('user123');
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### With Custom Storage
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { StorageRepository } from '@umituz/react-native-storage';
|
|
44
|
+
|
|
45
|
+
const storage = new StorageRepository();
|
|
46
|
+
const repository = new SettingsRepository(storage);
|
|
47
|
+
|
|
48
|
+
const settings = await repository.get('user123');
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Methods
|
|
52
|
+
|
|
53
|
+
### get(userId: string): Promise<UserSettings>
|
|
54
|
+
|
|
55
|
+
Retrieves settings for a user. Creates defaults if not found.
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
const settings = await repository.get('user123');
|
|
59
|
+
|
|
60
|
+
console.log(settings.theme); // 'light' | 'dark' | 'auto'
|
|
61
|
+
console.log(settings.language); // 'en-US'
|
|
62
|
+
console.log(settings.notificationsEnabled); // true
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Returns**: Complete UserSettings object.
|
|
66
|
+
|
|
67
|
+
**Example**:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
async function loadSettings(userId: string) {
|
|
71
|
+
try {
|
|
72
|
+
const settings = await repository.get(userId);
|
|
73
|
+
return settings;
|
|
74
|
+
} catch (error) {
|
|
75
|
+
console.error('Failed to load settings:', error);
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### update(userId: string, updates: Partial<UserSettings>): Promise<UserSettings>
|
|
82
|
+
|
|
83
|
+
Updates settings for a user.
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
const updated = await repository.update('user123', {
|
|
87
|
+
theme: 'dark',
|
|
88
|
+
notificationsEnabled: false,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
console.log(updated.theme); // 'dark'
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Returns**: Updated complete UserSettings object.
|
|
95
|
+
|
|
96
|
+
**Example**:
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
async function updateTheme(userId: string, theme: 'light' | 'dark') {
|
|
100
|
+
try {
|
|
101
|
+
const updated = await repository.update(userId, { theme });
|
|
102
|
+
return updated;
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.error('Failed to update theme:', error);
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### reset(userId: string): Promise<UserSettings>
|
|
111
|
+
|
|
112
|
+
Resets settings to default values.
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
const defaults = await repository.reset('user123');
|
|
116
|
+
|
|
117
|
+
console.log(defaults.theme); // 'light' (default)
|
|
118
|
+
console.log(defaults.language); // 'en-US' (default)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**Returns**: Default UserSettings object.
|
|
122
|
+
|
|
123
|
+
**Example**:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
async function clearUserData(userId: string) {
|
|
127
|
+
try {
|
|
128
|
+
const defaults = await repository.reset(userId);
|
|
129
|
+
return defaults;
|
|
130
|
+
} catch (error) {
|
|
131
|
+
console.error('Failed to reset settings:', error);
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Data Structure
|
|
138
|
+
|
|
139
|
+
### UserSettings
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
interface UserSettings {
|
|
143
|
+
userId: string; // Unique user identifier
|
|
144
|
+
theme: 'light' | 'dark' | 'auto'; // Theme preference
|
|
145
|
+
language: string; // Language code (e.g., 'en-US')
|
|
146
|
+
notificationsEnabled: boolean; // Master notification switch
|
|
147
|
+
emailNotifications: boolean; // Email notification preference
|
|
148
|
+
pushNotifications: boolean; // Push notification preference
|
|
149
|
+
soundEnabled: boolean; // Sound effects toggle
|
|
150
|
+
vibrationEnabled: boolean; // Haptic feedback toggle
|
|
151
|
+
quietHoursEnabled: boolean; // Quiet hours feature
|
|
152
|
+
quietHoursStart: string; // Start time (HH:MM format)
|
|
153
|
+
quietHoursEnd: string; // End time (HH:MM format)
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Storage Format
|
|
158
|
+
|
|
159
|
+
Settings are stored in the following format:
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
{
|
|
163
|
+
"settings:user123": {
|
|
164
|
+
"userId": "user123",
|
|
165
|
+
"theme": "dark",
|
|
166
|
+
"language": "tr-TR",
|
|
167
|
+
"notificationsEnabled": true,
|
|
168
|
+
"emailNotifications": true,
|
|
169
|
+
"pushNotifications": true,
|
|
170
|
+
"soundEnabled": true,
|
|
171
|
+
"vibrationEnabled": true,
|
|
172
|
+
"quietHoursEnabled": false,
|
|
173
|
+
"quietHoursStart": "22:00",
|
|
174
|
+
"quietHoursEnd": "08:00"
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Default Values
|
|
180
|
+
|
|
181
|
+
### Default Settings
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
const defaultSettings: UserSettings = {
|
|
185
|
+
userId: '',
|
|
186
|
+
theme: 'auto',
|
|
187
|
+
language: 'en-US',
|
|
188
|
+
notificationsEnabled: true,
|
|
189
|
+
emailNotifications: true,
|
|
190
|
+
pushNotifications: true,
|
|
191
|
+
soundEnabled: true,
|
|
192
|
+
vibrationEnabled: true,
|
|
193
|
+
quietHoursEnabled: false,
|
|
194
|
+
quietHoursStart: '22:00',
|
|
195
|
+
quietHoursEnd: '08:00',
|
|
196
|
+
};
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Applying Defaults
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
function applyDefaults(
|
|
203
|
+
userId: string,
|
|
204
|
+
existing?: Partial<UserSettings>
|
|
205
|
+
): UserSettings {
|
|
206
|
+
return {
|
|
207
|
+
...defaultSettings,
|
|
208
|
+
userId,
|
|
209
|
+
...existing,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Storage Keys
|
|
215
|
+
|
|
216
|
+
### Key Format
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
function getStorageKey(userId: string): string {
|
|
220
|
+
return `settings:${userId}`;
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**Examples**:
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
getStorageKey('user123'); // 'settings:user123'
|
|
228
|
+
getStorageKey('admin'); // 'settings:admin'
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Error Handling
|
|
232
|
+
|
|
233
|
+
### Storage Errors
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
try {
|
|
237
|
+
const settings = await repository.get('user123');
|
|
238
|
+
} catch (error) {
|
|
239
|
+
if (error.code === 'STORAGE_ERROR') {
|
|
240
|
+
console.error('Storage operation failed:', error.message);
|
|
241
|
+
} else if (error.code === 'NETWORK_ERROR') {
|
|
242
|
+
console.error('Network error:', error.message);
|
|
243
|
+
} else {
|
|
244
|
+
console.error('Unknown error:', error.message);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Error Types
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
enum SettingsErrorCode {
|
|
253
|
+
NOT_FOUND = 'NOT_FOUND',
|
|
254
|
+
STORAGE_ERROR = 'STORAGE_ERROR',
|
|
255
|
+
NETWORK_ERROR = 'NETWORK_ERROR',
|
|
256
|
+
VALIDATION_ERROR = 'VALIDATION_ERROR',
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
class SettingsRepositoryError extends Error {
|
|
260
|
+
constructor(
|
|
261
|
+
message: string,
|
|
262
|
+
public code: SettingsErrorCode,
|
|
263
|
+
public originalError?: Error
|
|
264
|
+
) {
|
|
265
|
+
super(message);
|
|
266
|
+
this.name = 'SettingsRepositoryError';
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Performance
|
|
272
|
+
|
|
273
|
+
### Optimized Reads
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
class SettingsRepository {
|
|
277
|
+
private cache = new Map<string, UserSettings>();
|
|
278
|
+
|
|
279
|
+
async get(userId: string): Promise<UserSettings> {
|
|
280
|
+
// Check cache first
|
|
281
|
+
if (this.cache.has(userId)) {
|
|
282
|
+
return this.cache.get(userId)!;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Load from storage
|
|
286
|
+
const settings = await this.loadFromStorage(userId);
|
|
287
|
+
|
|
288
|
+
// Cache result
|
|
289
|
+
this.cache.set(userId, settings);
|
|
290
|
+
|
|
291
|
+
return settings;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
async update(
|
|
295
|
+
userId: string,
|
|
296
|
+
updates: Partial<UserSettings>
|
|
297
|
+
): Promise<UserSettings> {
|
|
298
|
+
const settings = await this.get(userId);
|
|
299
|
+
|
|
300
|
+
const updated = {
|
|
301
|
+
...settings,
|
|
302
|
+
...updates,
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
// Save to storage
|
|
306
|
+
await this.saveToStorage(userId, updated);
|
|
307
|
+
|
|
308
|
+
// Update cache
|
|
309
|
+
this.cache.set(userId, updated);
|
|
310
|
+
|
|
311
|
+
return updated;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
invalidateCache(userId?: string): void {
|
|
315
|
+
if (userId) {
|
|
316
|
+
this.cache.delete(userId);
|
|
317
|
+
} else {
|
|
318
|
+
this.cache.clear();
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## Migrations
|
|
325
|
+
|
|
326
|
+
### Schema Versioning
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
interface SettingsSchema {
|
|
330
|
+
version: number;
|
|
331
|
+
settings: UserSettings;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
async function migrateSettings(
|
|
335
|
+
oldVersion: number,
|
|
336
|
+
newVersion: number,
|
|
337
|
+
settings: any
|
|
338
|
+
): Promise<UserSettings> {
|
|
339
|
+
if (oldVersion === 1 && newVersion === 2) {
|
|
340
|
+
// Migration from v1 to v2
|
|
341
|
+
return {
|
|
342
|
+
...settings,
|
|
343
|
+
newField: defaultSettings.newField,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
return settings;
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### Running Migrations
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
class SettingsRepository {
|
|
355
|
+
private readonly CURRENT_VERSION = 2;
|
|
356
|
+
|
|
357
|
+
async get(userId: string): Promise<UserSettings> {
|
|
358
|
+
const stored = await storage.get(`settings:${userId}`);
|
|
359
|
+
|
|
360
|
+
if (!stored) {
|
|
361
|
+
return this.createDefaults(userId);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Check version
|
|
365
|
+
if (stored.version < this.CURRENT_VERSION) {
|
|
366
|
+
return this.migrate(stored);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return stored.settings;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
private async migrate(stored: any): Promise<UserSettings> {
|
|
373
|
+
const settings = await migrateSettings(
|
|
374
|
+
stored.version,
|
|
375
|
+
this.CURRENT_VERSION,
|
|
376
|
+
stored.settings
|
|
377
|
+
);
|
|
378
|
+
|
|
379
|
+
// Save migrated settings
|
|
380
|
+
await this.saveToStorage(stored.userId, settings);
|
|
381
|
+
|
|
382
|
+
return settings;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
## Testing
|
|
388
|
+
|
|
389
|
+
### Mock Repository
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
class MockSettingsRepository implements ISettingsRepository {
|
|
393
|
+
private storage = new Map<string, UserSettings>();
|
|
394
|
+
|
|
395
|
+
async get(userId: string): Promise<UserSettings> {
|
|
396
|
+
if (!this.storage.has(userId)) {
|
|
397
|
+
const defaults = applyDefaults(userId);
|
|
398
|
+
this.storage.set(userId, defaults);
|
|
399
|
+
}
|
|
400
|
+
return this.storage.get(userId)!;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
async update(
|
|
404
|
+
userId: string,
|
|
405
|
+
updates: Partial<UserSettings>
|
|
406
|
+
): Promise<UserSettings> {
|
|
407
|
+
const current = await this.get(userId);
|
|
408
|
+
const updated = { ...current, ...updates };
|
|
409
|
+
this.storage.set(userId, updated);
|
|
410
|
+
return updated;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
async reset(userId: string): Promise<UserSettings> {
|
|
414
|
+
const defaults = applyDefaults(userId);
|
|
415
|
+
this.storage.set(userId, defaults);
|
|
416
|
+
return defaults;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
clear(): void {
|
|
420
|
+
this.storage.clear();
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### Usage in Tests
|
|
426
|
+
|
|
427
|
+
```typescript
|
|
428
|
+
describe('SettingsService', () => {
|
|
429
|
+
let repository: MockSettingsRepository;
|
|
430
|
+
let service: SettingsService;
|
|
431
|
+
|
|
432
|
+
beforeEach(() => {
|
|
433
|
+
repository = new MockSettingsRepository();
|
|
434
|
+
service = new SettingsService(repository);
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
afterEach(() => {
|
|
438
|
+
repository.clear();
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
it('should return default settings for new user', async () => {
|
|
442
|
+
const settings = await repository.get('new-user');
|
|
443
|
+
|
|
444
|
+
expect(settings.theme).toBe('auto');
|
|
445
|
+
expect(settings.language).toBe('en-US');
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
it('should update settings', async () => {
|
|
449
|
+
await repository.update('user123', { theme: 'dark' });
|
|
450
|
+
|
|
451
|
+
const settings = await repository.get('user123');
|
|
452
|
+
expect(settings.theme).toBe('dark');
|
|
453
|
+
});
|
|
454
|
+
});
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
## Best Practices
|
|
458
|
+
|
|
459
|
+
1. **Defaults**: Always provide defaults for new users
|
|
460
|
+
2. **Validation**: Validate data before storage
|
|
461
|
+
3. **Error Handling**: Handle storage errors gracefully
|
|
462
|
+
4. **Caching**: Cache frequently accessed settings
|
|
463
|
+
5. **Type Safety**: Use TypeScript for type checking
|
|
464
|
+
6. **Immutability**: Don't mutate stored objects
|
|
465
|
+
7. **Migrations**: Handle schema changes gracefully
|
|
466
|
+
|
|
467
|
+
## Related
|
|
468
|
+
|
|
469
|
+
- **Settings Service**: Business logic layer
|
|
470
|
+
- **Application Layer**: Interface definitions
|
|
471
|
+
- **Storage Package**: Data persistence
|
|
472
|
+
|
|
473
|
+
## License
|
|
474
|
+
|
|
475
|
+
MIT
|