@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,455 @@
|
|
|
1
|
+
# Appearance Services
|
|
2
|
+
|
|
3
|
+
Service layer for appearance domain including system theme detection, validation, and appearance management.
|
|
4
|
+
|
|
5
|
+
## Services
|
|
6
|
+
|
|
7
|
+
### AppearanceService
|
|
8
|
+
|
|
9
|
+
Main service for managing appearance settings including theme mode, custom colors, and system theme detection.
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { AppearanceService } from '@umituz/react-native-settings';
|
|
13
|
+
|
|
14
|
+
const appearanceService = new AppearanceService();
|
|
15
|
+
|
|
16
|
+
// Get current theme mode
|
|
17
|
+
const themeMode = await appearanceService.getThemeMode();
|
|
18
|
+
|
|
19
|
+
// Set theme mode
|
|
20
|
+
await appearanceService.setThemeMode('dark');
|
|
21
|
+
|
|
22
|
+
// Get custom colors
|
|
23
|
+
const colors = await appearanceService.getCustomColors();
|
|
24
|
+
|
|
25
|
+
// Set custom colors
|
|
26
|
+
await appearanceService.setCustomColors({ primary: '#FF5722' });
|
|
27
|
+
|
|
28
|
+
// Reset to defaults
|
|
29
|
+
await appearanceService.resetColors();
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
#### Methods
|
|
33
|
+
|
|
34
|
+
**getThemeMode(): Promise<'light' | 'dark' | 'auto'>**
|
|
35
|
+
|
|
36
|
+
Gets the current theme mode setting.
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
const themeMode = await appearanceService.getThemeMode();
|
|
40
|
+
console.log(themeMode); // 'light' | 'dark' | 'auto'
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**setThemeMode(mode: 'light' | 'dark' | 'auto'): Promise<void>**
|
|
44
|
+
|
|
45
|
+
Sets the theme mode setting.
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
await appearanceService.setThemeMode('dark');
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**getCustomColors(): Promise<ColorPalette | undefined>**
|
|
52
|
+
|
|
53
|
+
Gets the custom color palette if set.
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
const colors = await appearanceService.getCustomColors();
|
|
57
|
+
if (colors) {
|
|
58
|
+
console.log(colors.primary);
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**setCustomColors(colors: ColorPalette): Promise<void>**
|
|
63
|
+
|
|
64
|
+
Sets the custom color palette.
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
await appearanceService.setCustomColors({
|
|
68
|
+
primary: '#FF5722',
|
|
69
|
+
secondary: '#2196F3',
|
|
70
|
+
accent: '#FFC107',
|
|
71
|
+
background: '#FFFFFF',
|
|
72
|
+
surface: '#F5F5F5',
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**resetColors(): Promise<void>**
|
|
77
|
+
|
|
78
|
+
Resets colors to default theme.
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
await appearanceService.resetColors();
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### SystemThemeDetectionService
|
|
85
|
+
|
|
86
|
+
Service for detecting and monitoring system theme changes.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { SystemThemeDetectionService } from '@umituz/react-native-settings';
|
|
90
|
+
|
|
91
|
+
const detectionService = new SystemThemeDetectionService();
|
|
92
|
+
|
|
93
|
+
// Get current system theme
|
|
94
|
+
const systemTheme = detectionService.getSystemTheme();
|
|
95
|
+
console.log(systemTheme); // 'light' | 'dark' | null
|
|
96
|
+
|
|
97
|
+
// Listen for system theme changes
|
|
98
|
+
const unsubscribe = detectionService.listen((theme) => {
|
|
99
|
+
console.log('System theme changed to:', theme);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Stop listening
|
|
103
|
+
unsubscribe();
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### Methods
|
|
107
|
+
|
|
108
|
+
**getSystemTheme(): 'light' | 'dark' | null**
|
|
109
|
+
|
|
110
|
+
Gets the current system theme preference.
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
const theme = detectionService.getSystemTheme();
|
|
114
|
+
if (theme === 'dark') {
|
|
115
|
+
console.log('System is in dark mode');
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**listen(callback: (theme: 'light' | 'dark') => void): () => void**
|
|
120
|
+
|
|
121
|
+
Listens for system theme changes.
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
const unsubscribe = detectionService.listen((theme) => {
|
|
125
|
+
console.log('Theme changed to:', theme);
|
|
126
|
+
// Update app theme accordingly
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Cleanup on unmount
|
|
130
|
+
useEffect(() => {
|
|
131
|
+
return () => unsubscribe();
|
|
132
|
+
}, []);
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### ValidationService
|
|
136
|
+
|
|
137
|
+
Service for validating appearance settings.
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
import { ValidationService } from '@umituz/react-native-settings';
|
|
141
|
+
|
|
142
|
+
const validationService = new ValidationService();
|
|
143
|
+
|
|
144
|
+
// Validate theme mode
|
|
145
|
+
const themeValid = validationService.validateThemeMode('dark');
|
|
146
|
+
console.log(themeValid); // true
|
|
147
|
+
|
|
148
|
+
const themeInvalid = validationService.validateThemeMode('invalid');
|
|
149
|
+
console.log(themeInvalid); // false
|
|
150
|
+
|
|
151
|
+
// Validate color hex
|
|
152
|
+
const colorValid = validationService.validateColor('#FF5722');
|
|
153
|
+
console.log(colorValid); // true
|
|
154
|
+
|
|
155
|
+
const colorInvalid = validationService.validateColor('invalid');
|
|
156
|
+
console.log(colorInvalid); // false
|
|
157
|
+
|
|
158
|
+
// Validate color palette
|
|
159
|
+
const paletteValid = validationService.validateColorPalette({
|
|
160
|
+
primary: '#FF5722',
|
|
161
|
+
secondary: '#2196F3',
|
|
162
|
+
});
|
|
163
|
+
console.log(paletteValid); // true
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
#### Methods
|
|
167
|
+
|
|
168
|
+
**validateThemeMode(mode: string): boolean**
|
|
169
|
+
|
|
170
|
+
Validates if the provided mode is a valid theme mode.
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
if (validationService.validateThemeMode(themeMode)) {
|
|
174
|
+
await appearanceService.setThemeMode(themeMode);
|
|
175
|
+
} else {
|
|
176
|
+
console.error('Invalid theme mode');
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**validateColor(color: string): boolean**
|
|
181
|
+
|
|
182
|
+
Validates if the provided string is a valid hex color.
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
if (validationService.validateColor('#FF5722')) {
|
|
186
|
+
// Color is valid
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**validateColorPalette(palette: ColorPalette): boolean**
|
|
191
|
+
|
|
192
|
+
Validates a complete color palette.
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
const palette = {
|
|
196
|
+
primary: '#FF5722',
|
|
197
|
+
secondary: '#2196F3',
|
|
198
|
+
accent: '#FFC107',
|
|
199
|
+
background: '#FFFFFF',
|
|
200
|
+
surface: '#F5F5F5',
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
if (validationService.validateColorPalette(palette)) {
|
|
204
|
+
await appearanceService.setCustomColors(palette);
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Usage Examples
|
|
209
|
+
|
|
210
|
+
### Auto Theme with System Detection
|
|
211
|
+
|
|
212
|
+
```tsx
|
|
213
|
+
function useAutoTheme() {
|
|
214
|
+
const [theme, setTheme] = useState<'light' | 'dark'>('light');
|
|
215
|
+
const { themeMode } = useAppearance();
|
|
216
|
+
|
|
217
|
+
useEffect(() => {
|
|
218
|
+
if (themeMode === 'auto') {
|
|
219
|
+
// Use system theme
|
|
220
|
+
const systemTheme = SystemThemeDetectionService.getSystemTheme();
|
|
221
|
+
if (systemTheme) {
|
|
222
|
+
setTheme(systemTheme);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Listen for changes
|
|
226
|
+
const unsubscribe = SystemThemeDetectionService.listen((newTheme) => {
|
|
227
|
+
setTheme(newTheme);
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
return unsubscribe;
|
|
231
|
+
} else {
|
|
232
|
+
// Use explicit theme
|
|
233
|
+
setTheme(themeMode === 'dark' ? 'dark' : 'light');
|
|
234
|
+
}
|
|
235
|
+
}, [themeMode]);
|
|
236
|
+
|
|
237
|
+
return theme;
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Theme Persistence
|
|
242
|
+
|
|
243
|
+
```tsx
|
|
244
|
+
class ThemePersistence {
|
|
245
|
+
private service: AppearanceService;
|
|
246
|
+
|
|
247
|
+
constructor() {
|
|
248
|
+
this.service = new AppearanceService();
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
async loadTheme(): Promise<'light' | 'dark' | 'auto'> {
|
|
252
|
+
const mode = await this.service.getThemeMode();
|
|
253
|
+
return mode;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
async saveTheme(mode: 'light' | 'dark' | 'auto'): Promise<void> {
|
|
257
|
+
await this.service.setThemeMode(mode);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
async loadColors(): Promise<ColorPalette | undefined> {
|
|
261
|
+
return await this.service.getCustomColors();
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
async saveColors(colors: ColorPalette): Promise<void> {
|
|
265
|
+
if (ValidationService.validateColorPalette(colors)) {
|
|
266
|
+
await this.service.setCustomColors(colors);
|
|
267
|
+
} else {
|
|
268
|
+
throw new Error('Invalid color palette');
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Color Validation
|
|
275
|
+
|
|
276
|
+
```tsx
|
|
277
|
+
function ColorInput({ value, onChange }) {
|
|
278
|
+
const validationService = new ValidationService();
|
|
279
|
+
const [error, setError] = useState<string | null>(null);
|
|
280
|
+
|
|
281
|
+
const handleChange = (color: string) => {
|
|
282
|
+
if (validationService.validateColor(color)) {
|
|
283
|
+
setError(null);
|
|
284
|
+
onChange(color);
|
|
285
|
+
} else {
|
|
286
|
+
setError('Invalid color format. Use hex format: #RRGGBB');
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
return (
|
|
291
|
+
<View>
|
|
292
|
+
<TextInput
|
|
293
|
+
value={value}
|
|
294
|
+
onChangeText={handleChange}
|
|
295
|
+
placeholder="#FF5722"
|
|
296
|
+
/>
|
|
297
|
+
{error && <Text style={styles.error}>{error}</Text>}
|
|
298
|
+
</View>
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Theme Switcher with Validation
|
|
304
|
+
|
|
305
|
+
```tsx
|
|
306
|
+
function ThemeSwitcher() {
|
|
307
|
+
const { themeMode, setThemeMode } = useAppearance();
|
|
308
|
+
const validationService = new ValidationService();
|
|
309
|
+
|
|
310
|
+
const handleThemeChange = async (mode: string) => {
|
|
311
|
+
if (validationService.validateThemeMode(mode)) {
|
|
312
|
+
await setThemeMode(mode as 'light' | 'dark' | 'auto');
|
|
313
|
+
} else {
|
|
314
|
+
Alert.alert('Error', 'Invalid theme mode');
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
return (
|
|
319
|
+
<View>
|
|
320
|
+
<Button
|
|
321
|
+
onPress={() => handleThemeChange('light')}
|
|
322
|
+
title="Light Mode"
|
|
323
|
+
/>
|
|
324
|
+
<Button
|
|
325
|
+
onPress={() => handleThemeChange('dark')}
|
|
326
|
+
title="Dark Mode"
|
|
327
|
+
/>
|
|
328
|
+
<Button
|
|
329
|
+
onPress={() => handleThemeChange('auto')}
|
|
330
|
+
title="Auto Mode"
|
|
331
|
+
/>
|
|
332
|
+
</View>
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Complete Appearance Manager
|
|
338
|
+
|
|
339
|
+
```tsx
|
|
340
|
+
class AppearanceManager {
|
|
341
|
+
private appearanceService: AppearanceService;
|
|
342
|
+
private detectionService: SystemThemeDetectionService;
|
|
343
|
+
private validationService: ValidationService;
|
|
344
|
+
|
|
345
|
+
constructor() {
|
|
346
|
+
this.appearanceService = new AppearanceService();
|
|
347
|
+
this.detectionService = new SystemThemeDetectionService();
|
|
348
|
+
this.validationService = new ValidationService();
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
async initialize(): Promise<void> {
|
|
352
|
+
const mode = await this.appearanceService.getThemeMode();
|
|
353
|
+
return mode;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
async setTheme(mode: 'light' | 'dark' | 'auto'): Promise<void> {
|
|
357
|
+
if (!this.validationService.validateThemeMode(mode)) {
|
|
358
|
+
throw new Error('Invalid theme mode');
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
await this.appearanceService.setThemeMode(mode);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
getEffectiveTheme(): 'light' | 'dark' {
|
|
365
|
+
const mode = this.appearanceService.getThemeMode();
|
|
366
|
+
if (mode === 'auto') {
|
|
367
|
+
return this.detectionService.getSystemTheme() || 'light';
|
|
368
|
+
}
|
|
369
|
+
return mode;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
listenToThemeChanges(callback: (theme: 'light' | 'dark') => void): () => void {
|
|
373
|
+
return this.detectionService.listen(callback);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
async setCustomColors(colors: ColorPalette): Promise<void> {
|
|
377
|
+
if (!this.validationService.validateColorPalette(colors)) {
|
|
378
|
+
throw new Error('Invalid color palette');
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
await this.appearanceService.setCustomColors(colors);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
async reset(): Promise<void> {
|
|
385
|
+
await this.appearanceService.resetColors();
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
## Color Palette
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
interface ColorPalette {
|
|
394
|
+
primary: string; // #FF5722
|
|
395
|
+
secondary: string; // #2196F3
|
|
396
|
+
accent: string; // #FFC107
|
|
397
|
+
background: string; // #FFFFFF
|
|
398
|
+
surface: string; // #F5F5F5
|
|
399
|
+
error: string; // #F44336
|
|
400
|
+
success: string; // #4CAF50
|
|
401
|
+
warning: string; // #FF9800
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
## Default Palettes
|
|
406
|
+
|
|
407
|
+
### Light Theme
|
|
408
|
+
|
|
409
|
+
```typescript
|
|
410
|
+
const lightColors: ColorPalette = {
|
|
411
|
+
primary: '#FF5722',
|
|
412
|
+
secondary: '#2196F3',
|
|
413
|
+
accent: '#FFC107',
|
|
414
|
+
background: '#FFFFFF',
|
|
415
|
+
surface: '#F5F5F5',
|
|
416
|
+
error: '#F44336',
|
|
417
|
+
success: '#4CAF50',
|
|
418
|
+
warning: '#FF9800',
|
|
419
|
+
};
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### Dark Theme
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
const darkColors: ColorPalette = {
|
|
426
|
+
primary: '#FF5722',
|
|
427
|
+
secondary: '#2196F3',
|
|
428
|
+
accent: '#FFC107',
|
|
429
|
+
background: '#121212',
|
|
430
|
+
surface: '#1E1E1E',
|
|
431
|
+
error: '#EF5350',
|
|
432
|
+
success: '#66BB6A',
|
|
433
|
+
warning: '#FFA726',
|
|
434
|
+
};
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
## Best Practices
|
|
438
|
+
|
|
439
|
+
1. **Validation**: Always validate colors before saving
|
|
440
|
+
2. **System Theme**: Respect system theme when mode is 'auto'
|
|
441
|
+
3. **Cleanup**: Unsubscribe from theme listeners on unmount
|
|
442
|
+
4. **Error Handling**: Handle invalid colors gracefully
|
|
443
|
+
5. **Hex Format**: Use proper hex color format (#RRGGBB)
|
|
444
|
+
6. **Persistence**: Save theme changes immediately
|
|
445
|
+
7. **Performance**: Cache theme detection results
|
|
446
|
+
|
|
447
|
+
## Related
|
|
448
|
+
|
|
449
|
+
- **Appearance Hooks**: React hooks for appearance
|
|
450
|
+
- **Appearance Components**: UI components for appearance
|
|
451
|
+
- **Appearance Repository**: Data persistence layer
|
|
452
|
+
|
|
453
|
+
## License
|
|
454
|
+
|
|
455
|
+
MIT
|