@umituz/react-native-settings 4.20.58 → 4.20.60
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/SettingsStackNavigator.tsx +2 -0
- package/src/presentation/navigation/components/README.md +70 -295
- package/src/presentation/navigation/components/wrappers/SettingsScreenWrapper.tsx +3 -0
- package/src/presentation/navigation/hooks/README.md +75 -367
- package/src/presentation/navigation/types.ts +1 -0
- package/src/presentation/navigation/utils/README.md +100 -380
- package/src/presentation/screens/README.md +53 -504
- package/src/presentation/screens/SettingsScreen.tsx +4 -2
- 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,444 +1,78 @@
|
|
|
1
1
|
# Cloud Sync Domain
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
-
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
```tsx
|
|
77
|
-
import { CloudSyncSetting } from '@umituz/react-native-settings';
|
|
78
|
-
import { useState } from 'react';
|
|
79
|
-
|
|
80
|
-
function BasicCloudSync() {
|
|
81
|
-
const [isSyncing, setIsSyncing] = useState(false);
|
|
82
|
-
const [lastSynced, setLastSynced] = useState<Date | null>(null);
|
|
83
|
-
|
|
84
|
-
const handleSync = async () => {
|
|
85
|
-
setIsSyncing(true);
|
|
86
|
-
try {
|
|
87
|
-
await syncData();
|
|
88
|
-
setLastSynced(new Date());
|
|
89
|
-
} catch (error) {
|
|
90
|
-
console.error('Sync failed:', error);
|
|
91
|
-
} finally {
|
|
92
|
-
setIsSyncing(false);
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
return (
|
|
97
|
-
<CloudSyncSetting
|
|
98
|
-
isSyncing={isSyncing}
|
|
99
|
-
lastSynced={lastSynced}
|
|
100
|
-
onPress={handleSync}
|
|
101
|
-
/>
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### With Custom Description
|
|
107
|
-
|
|
108
|
-
```tsx
|
|
109
|
-
function CloudSyncWithDescription() {
|
|
110
|
-
const syncStatus = 'Synced 5 minutes ago';
|
|
111
|
-
|
|
112
|
-
return (
|
|
113
|
-
<CloudSyncSetting
|
|
114
|
-
title="iCloud Sync"
|
|
115
|
-
description={syncStatus}
|
|
116
|
-
onPress={() => console.log('Sync pressed')}
|
|
117
|
-
/>
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
### Disabled State
|
|
123
|
-
|
|
124
|
-
```tsx
|
|
125
|
-
function DisabledCloudSync() {
|
|
126
|
-
return (
|
|
127
|
-
<CloudSyncSetting
|
|
128
|
-
title="Cloud Sync"
|
|
129
|
-
description="Sync disabled"
|
|
130
|
-
disabled={true}
|
|
131
|
-
/>
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
### With Translations
|
|
137
|
-
|
|
138
|
-
```tsx
|
|
139
|
-
import { useTranslation } from 'react-i18next';
|
|
140
|
-
import { CloudSyncSetting } from '@umituz/react-native-settings';
|
|
141
|
-
|
|
142
|
-
function LocalizedCloudSync() {
|
|
143
|
-
const { t } = useTranslation();
|
|
144
|
-
const [isSyncing, setIsSyncing] = useState(false);
|
|
145
|
-
const [lastSynced, setLastSynced] = useState<Date | null>(null);
|
|
146
|
-
|
|
147
|
-
// Get translation key based on state
|
|
148
|
-
const getDescription = () => {
|
|
149
|
-
if (isSyncing) return t('sync.syncing');
|
|
150
|
-
if (!lastSynced) return t('sync.never');
|
|
151
|
-
// Calculate relative time and return appropriate translation key
|
|
152
|
-
const timeAgo = calculateTimeAgo(lastSynced);
|
|
153
|
-
return t(`sync.${timeAgo}`);
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
return (
|
|
157
|
-
<CloudSyncSetting
|
|
158
|
-
title={t('sync.title')}
|
|
159
|
-
description={getDescription()}
|
|
160
|
-
isSyncing={isSyncing}
|
|
161
|
-
lastSynced={lastSynced}
|
|
162
|
-
onPress={handleSync}
|
|
163
|
-
/>
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
### Complete Integration
|
|
169
|
-
|
|
170
|
-
```tsx
|
|
171
|
-
import { CloudSyncSetting } from '@umituz/react-native-settings';
|
|
172
|
-
import { SettingsSection } from '@umituz/react-native-settings';
|
|
173
|
-
|
|
174
|
-
function CloudSyncSettings() {
|
|
175
|
-
const [syncState, setSyncState] = useState({
|
|
176
|
-
isSyncing: false,
|
|
177
|
-
lastSynced: null as Date | null,
|
|
178
|
-
error: null as string | null,
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
const handleSync = async () => {
|
|
182
|
-
setSyncState(prev => ({ ...prev, isSyncing: true, error: null }));
|
|
183
|
-
|
|
184
|
-
try {
|
|
185
|
-
await cloudSyncService.sync();
|
|
186
|
-
setSyncState({
|
|
187
|
-
isSyncing: false,
|
|
188
|
-
lastSynced: new Date(),
|
|
189
|
-
error: null,
|
|
190
|
-
});
|
|
191
|
-
} catch (error) {
|
|
192
|
-
setSyncState(prev => ({
|
|
193
|
-
...prev,
|
|
194
|
-
isSyncing: false,
|
|
195
|
-
error: error.message,
|
|
196
|
-
}));
|
|
197
|
-
}
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
return (
|
|
201
|
-
<SettingsSection title="Sync">
|
|
202
|
-
<CloudSyncSetting
|
|
203
|
-
title="Cloud Backup"
|
|
204
|
-
isSyncing={syncState.isSyncing}
|
|
205
|
-
lastSynced={syncState.lastSynced}
|
|
206
|
-
description={syncState.error || undefined}
|
|
207
|
-
onPress={handleSync}
|
|
208
|
-
disabled={syncState.isSyncing}
|
|
209
|
-
/>
|
|
210
|
-
</SettingsSection>
|
|
211
|
-
);
|
|
212
|
-
}
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
### With Auto-Sync
|
|
216
|
-
|
|
217
|
-
```tsx
|
|
218
|
-
import { useEffect, useState } from 'react';
|
|
219
|
-
import { CloudSyncSetting } from '@umituz/react-native-settings';
|
|
220
|
-
|
|
221
|
-
function AutoSyncCloudSync() {
|
|
222
|
-
const [isSyncing, setIsSyncing] = useState(false);
|
|
223
|
-
const [lastSynced, setLastSynced] = useState<Date | null>(null);
|
|
224
|
-
const [autoSync, setAutoSync] = useState(true);
|
|
225
|
-
|
|
226
|
-
// Auto-sync every 5 minutes
|
|
227
|
-
useEffect(() => {
|
|
228
|
-
if (!autoSync) return;
|
|
229
|
-
|
|
230
|
-
const interval = setInterval(async () => {
|
|
231
|
-
await performSync();
|
|
232
|
-
}, 5 * 60 * 1000);
|
|
233
|
-
|
|
234
|
-
return () => clearInterval(interval);
|
|
235
|
-
}, [autoSync]);
|
|
236
|
-
|
|
237
|
-
const performSync = async () => {
|
|
238
|
-
setIsSyncing(true);
|
|
239
|
-
try {
|
|
240
|
-
await syncData();
|
|
241
|
-
setLastSynced(new Date());
|
|
242
|
-
} finally {
|
|
243
|
-
setIsSyncing(false);
|
|
244
|
-
}
|
|
245
|
-
};
|
|
246
|
-
|
|
247
|
-
return (
|
|
248
|
-
<SettingsSection title="Sync Settings">
|
|
249
|
-
<SettingsItemCard
|
|
250
|
-
title="Auto-Sync"
|
|
251
|
-
value={autoSync ? 'Enabled' : 'Disabled'}
|
|
252
|
-
onPress={() => setAutoSync(!autoSync)}
|
|
253
|
-
/>
|
|
254
|
-
<CloudSyncSetting
|
|
255
|
-
isSyncing={isSyncing}
|
|
256
|
-
lastSynced={lastSynced}
|
|
257
|
-
onPress={performSync}
|
|
258
|
-
/>
|
|
259
|
-
</SettingsSection>
|
|
260
|
-
);
|
|
261
|
-
}
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
### Real-Time Sync Status
|
|
265
|
-
|
|
266
|
-
```tsx
|
|
267
|
-
import { useState, useEffect } from 'react';
|
|
268
|
-
import { CloudSyncSetting } from '@umituz/react-native-settings';
|
|
269
|
-
|
|
270
|
-
function RealTimeCloudSync() {
|
|
271
|
-
const [syncStatus, setSyncStatus] = useState({
|
|
272
|
-
isSyncing: false,
|
|
273
|
-
lastSynced: null as Date | null,
|
|
274
|
-
syncCount: 0,
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
useEffect(() => {
|
|
278
|
-
// Subscribe to sync events
|
|
279
|
-
const unsubscribe = cloudSyncService.onSyncChange((status) => {
|
|
280
|
-
setSyncStatus(status);
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
return unsubscribe;
|
|
284
|
-
}, []);
|
|
285
|
-
|
|
286
|
-
return (
|
|
287
|
-
<CloudSyncSetting
|
|
288
|
-
title="Real-time Sync"
|
|
289
|
-
isSyncing={syncStatus.isSyncing}
|
|
290
|
-
lastSynced={syncStatus.lastSynced}
|
|
291
|
-
onPress={() => cloudSyncService.triggerSync()}
|
|
292
|
-
/>
|
|
293
|
-
);
|
|
294
|
-
}
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
## Architecture
|
|
298
|
-
|
|
299
|
-
```
|
|
300
|
-
src/domains/cloud-sync/
|
|
301
|
-
├── presentation/
|
|
302
|
-
│ └── components/
|
|
303
|
-
│ ├── CloudSyncSetting.tsx # Main sync setting component
|
|
304
|
-
│ └── __tests__/
|
|
305
|
-
│ └── CloudSyncSetting.test.tsx
|
|
306
|
-
└── index.ts # Public API exports
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
## Best Practices
|
|
310
|
-
|
|
311
|
-
1. **Clear Status**: Always show current sync status clearly
|
|
312
|
-
2. **Error Handling**: Display sync errors prominently
|
|
313
|
-
3. **Manual Trigger**: Allow users to manually trigger sync
|
|
314
|
-
4. **Prevent Duplicate Syncs**: Disable sync button while syncing
|
|
315
|
-
5. **Auto-Sync**: Implement automatic sync intervals
|
|
316
|
-
6. **Conflict Resolution**: Handle sync conflicts gracefully
|
|
317
|
-
7. **Background Sync**: Use background sync for better UX
|
|
318
|
-
8. **Progress Indicators**: Show progress for large syncs
|
|
319
|
-
|
|
320
|
-
## Testing
|
|
321
|
-
|
|
322
|
-
```tsx
|
|
323
|
-
import { render, fireEvent, waitFor } from '@testing-library/react-native';
|
|
324
|
-
import { CloudSyncSetting } from '@umituz/react-native-settings';
|
|
325
|
-
|
|
326
|
-
describe('CloudSyncSetting', () => {
|
|
327
|
-
it('displays syncing state', () => {
|
|
328
|
-
const { getByText } = render(
|
|
329
|
-
<CloudSyncSetting
|
|
330
|
-
isSyncing={true}
|
|
331
|
-
onPress={() => {}}
|
|
332
|
-
/>
|
|
333
|
-
);
|
|
334
|
-
|
|
335
|
-
expect(getByText(/syncing/i)).toBeTruthy();
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
it('displays last synced time', () => {
|
|
339
|
-
const lastSynced = new Date(Date.now() - 5 * 60 * 1000); // 5 minutes ago
|
|
340
|
-
const { getByText } = render(
|
|
341
|
-
<CloudSyncSetting
|
|
342
|
-
lastSynced={lastSynced}
|
|
343
|
-
onPress={() => {}}
|
|
344
|
-
/>
|
|
345
|
-
);
|
|
346
|
-
|
|
347
|
-
expect(getByText(/5m_ago/i)).toBeTruthy();
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
it('calls onPress when pressed', () => {
|
|
351
|
-
const mockPress = jest.fn();
|
|
352
|
-
const { getByTestId } = render(
|
|
353
|
-
<CloudSyncSetting
|
|
354
|
-
onPress={mockPress}
|
|
355
|
-
/>
|
|
356
|
-
);
|
|
357
|
-
|
|
358
|
-
fireEvent.press(getByTestId('settings-item-card'));
|
|
359
|
-
expect(mockPress).toHaveBeenCalled();
|
|
360
|
-
});
|
|
361
|
-
|
|
362
|
-
it('does not respond to press when syncing', () => {
|
|
363
|
-
const mockPress = jest.fn();
|
|
364
|
-
const { getByTestId } = render(
|
|
365
|
-
<CloudSyncSetting
|
|
366
|
-
isSyncing={true}
|
|
367
|
-
onPress={mockPress}
|
|
368
|
-
/>
|
|
369
|
-
);
|
|
370
|
-
|
|
371
|
-
fireEvent.press(getByTestId('settings-item-card'));
|
|
372
|
-
expect(mockPress).not.toHaveBeenCalled();
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
it('shows custom description when provided', () => {
|
|
376
|
-
const { getByText } = render(
|
|
377
|
-
<CloudSyncSetting
|
|
378
|
-
description="Custom sync message"
|
|
379
|
-
onPress={() => {}}
|
|
380
|
-
/>
|
|
381
|
-
);
|
|
382
|
-
|
|
383
|
-
expect(getByText('Custom sync message')).toBeTruthy();
|
|
384
|
-
});
|
|
385
|
-
});
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
## Integration Examples
|
|
389
|
-
|
|
390
|
-
### With Cloud Services
|
|
391
|
-
|
|
392
|
-
```tsx
|
|
393
|
-
// iCloud sync (iOS)
|
|
394
|
-
import CloudSyncSetting from '@umituz/react-native-settings';
|
|
395
|
-
|
|
396
|
-
function iCloudSync() {
|
|
397
|
-
const [isSyncing, setIsSyncing] = useState(false);
|
|
398
|
-
const [lastSynced, setLastSynced] = useState<Date | null>(null);
|
|
399
|
-
|
|
400
|
-
const syncWithiCloud = async () => {
|
|
401
|
-
setIsSyncing(true);
|
|
402
|
-
try {
|
|
403
|
-
await CKContainer.defaultContainer().sync();
|
|
404
|
-
setLastSynced(new Date());
|
|
405
|
-
} finally {
|
|
406
|
-
setIsSyncing(false);
|
|
407
|
-
}
|
|
408
|
-
};
|
|
409
|
-
|
|
410
|
-
return (
|
|
411
|
-
<CloudSyncSetting
|
|
412
|
-
title="iCloud"
|
|
413
|
-
isSyncing={isSyncing}
|
|
414
|
-
lastSynced={lastSynced}
|
|
415
|
-
onPress={syncWithiCloud}
|
|
416
|
-
/>
|
|
417
|
-
);
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
// Firebase sync
|
|
421
|
-
function FirebaseSync() {
|
|
422
|
-
const [isSyncing, setIsSyncing] = useState(false);
|
|
423
|
-
|
|
424
|
-
const syncWithFirebase = async () => {
|
|
425
|
-
setIsSyncing(true);
|
|
426
|
-
try {
|
|
427
|
-
await firebase.firestore().sync();
|
|
428
|
-
} finally {
|
|
429
|
-
setIsSyncing(false);
|
|
430
|
-
}
|
|
431
|
-
};
|
|
432
|
-
|
|
433
|
-
return (
|
|
434
|
-
<CloudSyncSetting
|
|
435
|
-
title="Firebase"
|
|
436
|
-
isSyncing={isSyncing}
|
|
437
|
-
onPress={syncWithFirebase}
|
|
438
|
-
/>
|
|
439
|
-
);
|
|
440
|
-
}
|
|
441
|
-
```
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Provides components for displaying and managing cloud synchronization status with relative time display and manual sync triggering.
|
|
6
|
+
|
|
7
|
+
## File Paths
|
|
8
|
+
|
|
9
|
+
**Components:**
|
|
10
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/cloud-sync/presentation/components/CloudSyncSetting.tsx`
|
|
11
|
+
|
|
12
|
+
**Tests:**
|
|
13
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/cloud-sync/presentation/components/__tests__/CloudSyncSetting.test.tsx`
|
|
14
|
+
|
|
15
|
+
**Index:**
|
|
16
|
+
- `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domains/cloud-sync/index.ts`
|
|
17
|
+
|
|
18
|
+
## Strategy
|
|
19
|
+
|
|
20
|
+
1. **Relative Time Display**: Automatically format lastSynced timestamp into relative time strings (5m ago, 2h ago, etc.)
|
|
21
|
+
2. **Sync State Management**: Display current sync status clearly with visual indicators
|
|
22
|
+
3. **Manual Trigger**: Allow users to manually trigger sync with proper state management
|
|
23
|
+
4. **Error Handling**: Display sync errors prominently with user-friendly messages
|
|
24
|
+
5. **Prevent Duplicates**: Disable sync button while syncing is in progress
|
|
25
|
+
|
|
26
|
+
## Restrictions (Forbidden)
|
|
27
|
+
|
|
28
|
+
### DO NOT
|
|
29
|
+
- ❌ DO NOT trigger sync while already syncing (check isSyncing prop)
|
|
30
|
+
- ❌ DO NOT bypass the relative time formatting for lastSynced
|
|
31
|
+
- ❌ DO NOT use CloudSyncSetting without handling onPress callback
|
|
32
|
+
- ❌ DO NOT mix sync logic directly with UI components
|
|
33
|
+
|
|
34
|
+
### NEVER
|
|
35
|
+
- ❌ NEVER allow sync trigger when isSyncing is true
|
|
36
|
+
- ❌ NEVER show sync status without proper error handling
|
|
37
|
+
- ❌ NEVER use custom time formatting when relative time is provided
|
|
38
|
+
- ❌ NEVER create custom sync components when CloudSyncSetting exists
|
|
39
|
+
|
|
40
|
+
### AVOID
|
|
41
|
+
- ❌ AVOID hardcoding sync status messages - use description prop or relative time
|
|
42
|
+
- ❌ AVOID creating custom sync UI when CloudSyncSetting can be configured
|
|
43
|
+
- ❌ AVOID mixing sync logic with business logic
|
|
44
|
+
- ❌ AVOID triggering sync without proper state management
|
|
45
|
+
|
|
46
|
+
## Rules
|
|
47
|
+
|
|
48
|
+
### ALWAYS
|
|
49
|
+
- ✅ ALWAYS provide onPress handler for manual sync triggering
|
|
50
|
+
- ✅ ALWAYS check isSyncing before allowing sync operations
|
|
51
|
+
- ✅ ALWAYS handle sync errors gracefully with user feedback
|
|
52
|
+
- ✅ ALWAYS provide lastSynced timestamp for relative time display
|
|
53
|
+
- ✅ ALWAYS disable interaction when sync is in progress
|
|
54
|
+
|
|
55
|
+
### MUST
|
|
56
|
+
- ✅ MUST use isSyncing prop to prevent duplicate sync operations
|
|
57
|
+
- ✅ MUST provide lastSynced Date object for automatic relative time formatting
|
|
58
|
+
- ✅ MUST handle sync errors and display them to users
|
|
59
|
+
- ✅ MUST update lastSynced timestamp after successful sync
|
|
60
|
+
- ✅ MUST disable CloudSyncSetting while syncing (disabled or isSyncing prop)
|
|
61
|
+
|
|
62
|
+
### SHOULD
|
|
63
|
+
- ✅ SHOULD show clear sync status to users
|
|
64
|
+
- ✅ SHOULD implement automatic sync intervals
|
|
65
|
+
- ✅ SHOULD handle sync conflicts gracefully
|
|
66
|
+
- ✅ SHOULD use background sync for better UX
|
|
67
|
+
- ✅ SHOULD show progress indicators for large syncs
|
|
68
|
+
|
|
69
|
+
## AI Agent Guidelines
|
|
70
|
+
|
|
71
|
+
1. **Component Usage**: Always use CloudSyncSetting for sync status display - never create custom sync components
|
|
72
|
+
2. **State Management**: Always use isSyncing prop to prevent duplicate sync operations
|
|
73
|
+
3. **Time Display**: Always use lastSynced Date object for automatic relative time formatting
|
|
74
|
+
4. **Error Handling**: Always handle sync errors gracefully with user-friendly error messages
|
|
75
|
+
5. **Prevention**: Always disable sync button while syncing is in progress
|
|
442
76
|
|
|
443
77
|
## Related
|
|
444
78
|
|