@oxyhq/services 5.13.12 → 5.13.15

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.
Files changed (89) hide show
  1. package/lib/commonjs/core/OxyServices.js +159 -0
  2. package/lib/commonjs/core/OxyServices.js.map +1 -1
  3. package/lib/commonjs/index.js.map +1 -1
  4. package/lib/commonjs/ui/context/OxyContext.js +1 -47
  5. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  6. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js +239 -1
  7. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js.map +1 -1
  8. package/lib/commonjs/utils/apiUtils.js +0 -14
  9. package/lib/commonjs/utils/apiUtils.js.map +1 -1
  10. package/lib/commonjs/utils/asyncUtils.js +0 -20
  11. package/lib/commonjs/utils/asyncUtils.js.map +1 -1
  12. package/lib/module/core/OxyServices.js +159 -0
  13. package/lib/module/core/OxyServices.js.map +1 -1
  14. package/lib/module/index.js.map +1 -1
  15. package/lib/module/ui/context/OxyContext.js +1 -47
  16. package/lib/module/ui/context/OxyContext.js.map +1 -1
  17. package/lib/module/ui/navigation/types.js.map +1 -1
  18. package/lib/module/ui/screens/PrivacySettingsScreen.js +241 -3
  19. package/lib/module/ui/screens/PrivacySettingsScreen.js.map +1 -1
  20. package/lib/module/utils/apiUtils.js +0 -13
  21. package/lib/module/utils/apiUtils.js.map +1 -1
  22. package/lib/module/utils/asyncUtils.js +0 -20
  23. package/lib/module/utils/asyncUtils.js.map +1 -1
  24. package/lib/typescript/core/OxyServices.d.ts +65 -1
  25. package/lib/typescript/core/OxyServices.d.ts.map +1 -1
  26. package/lib/typescript/index.d.ts +1 -1
  27. package/lib/typescript/index.d.ts.map +1 -1
  28. package/lib/typescript/models/interfaces.d.ts +26 -0
  29. package/lib/typescript/models/interfaces.d.ts.map +1 -1
  30. package/lib/typescript/ui/context/OxyContext.d.ts +0 -6
  31. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  32. package/lib/typescript/ui/navigation/types.d.ts +0 -1
  33. package/lib/typescript/ui/navigation/types.d.ts.map +1 -1
  34. package/lib/typescript/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
  35. package/lib/typescript/utils/apiUtils.d.ts +0 -7
  36. package/lib/typescript/utils/apiUtils.d.ts.map +1 -1
  37. package/lib/typescript/utils/asyncUtils.d.ts +0 -11
  38. package/lib/typescript/utils/asyncUtils.d.ts.map +1 -1
  39. package/package.json +1 -1
  40. package/src/core/OxyServices.ts +174 -1
  41. package/src/index.ts +4 -0
  42. package/src/models/interfaces.ts +28 -0
  43. package/src/ui/context/OxyContext.tsx +0 -54
  44. package/src/ui/navigation/types.ts +0 -1
  45. package/src/ui/screens/PrivacySettingsScreen.tsx +240 -2
  46. package/src/utils/apiUtils.ts +0 -14
  47. package/src/utils/asyncUtils.ts +0 -20
  48. package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js +0 -192
  49. package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js.map +0 -1
  50. package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js +0 -142
  51. package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js.map +0 -1
  52. package/lib/commonjs/ui/screens/internal/SignUpIdentityStep.js +0 -113
  53. package/lib/commonjs/ui/screens/internal/SignUpIdentityStep.js.map +0 -1
  54. package/lib/commonjs/ui/screens/internal/SignUpSecurityStep.js +0 -132
  55. package/lib/commonjs/ui/screens/internal/SignUpSecurityStep.js.map +0 -1
  56. package/lib/commonjs/ui/screens/internal/SignUpSummaryStep.js +0 -83
  57. package/lib/commonjs/ui/screens/internal/SignUpSummaryStep.js.map +0 -1
  58. package/lib/commonjs/ui/screens/internal/SignUpWelcomeStep.js +0 -58
  59. package/lib/commonjs/ui/screens/internal/SignUpWelcomeStep.js.map +0 -1
  60. package/lib/module/ui/screens/internal/SignInPasswordStep.js +0 -186
  61. package/lib/module/ui/screens/internal/SignInPasswordStep.js.map +0 -1
  62. package/lib/module/ui/screens/internal/SignInUsernameStep.js +0 -136
  63. package/lib/module/ui/screens/internal/SignInUsernameStep.js.map +0 -1
  64. package/lib/module/ui/screens/internal/SignUpIdentityStep.js +0 -108
  65. package/lib/module/ui/screens/internal/SignUpIdentityStep.js.map +0 -1
  66. package/lib/module/ui/screens/internal/SignUpSecurityStep.js +0 -127
  67. package/lib/module/ui/screens/internal/SignUpSecurityStep.js.map +0 -1
  68. package/lib/module/ui/screens/internal/SignUpSummaryStep.js +0 -78
  69. package/lib/module/ui/screens/internal/SignUpSummaryStep.js.map +0 -1
  70. package/lib/module/ui/screens/internal/SignUpWelcomeStep.js +0 -53
  71. package/lib/module/ui/screens/internal/SignUpWelcomeStep.js.map +0 -1
  72. package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts +0 -28
  73. package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts.map +0 -1
  74. package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts +0 -25
  75. package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts.map +0 -1
  76. package/lib/typescript/ui/screens/internal/SignUpIdentityStep.d.ts +0 -20
  77. package/lib/typescript/ui/screens/internal/SignUpIdentityStep.d.ts.map +0 -1
  78. package/lib/typescript/ui/screens/internal/SignUpSecurityStep.d.ts +0 -24
  79. package/lib/typescript/ui/screens/internal/SignUpSecurityStep.d.ts.map +0 -1
  80. package/lib/typescript/ui/screens/internal/SignUpSummaryStep.d.ts +0 -15
  81. package/lib/typescript/ui/screens/internal/SignUpSummaryStep.d.ts.map +0 -1
  82. package/lib/typescript/ui/screens/internal/SignUpWelcomeStep.d.ts +0 -13
  83. package/lib/typescript/ui/screens/internal/SignUpWelcomeStep.d.ts.map +0 -1
  84. package/src/ui/screens/internal/SignInPasswordStep.tsx +0 -184
  85. package/src/ui/screens/internal/SignInUsernameStep.tsx +0 -145
  86. package/src/ui/screens/internal/SignUpIdentityStep.tsx +0 -112
  87. package/src/ui/screens/internal/SignUpSecurityStep.tsx +0 -132
  88. package/src/ui/screens/internal/SignUpSummaryStep.tsx +0 -66
  89. package/src/ui/screens/internal/SignUpWelcomeStep.tsx +0 -52
@@ -1,6 +1,5 @@
1
1
  import type React from 'react';
2
2
  import { createContext, useContext, useEffect, useCallback, useMemo, useRef, useState, type ReactNode } from 'react';
3
- import type { UseFollowHook } from '../hooks/useFollow.types';
4
3
  import { OxyServices } from '../../core';
5
4
  import type { User, ApiError } from '../../models/interfaces';
6
5
  import type { SessionLoginResponse, ClientSession, MinimalUserData } from '../../models/session';
@@ -15,9 +14,6 @@ import { getLanguageMetadata, getLanguageName, getNativeLanguageName, normalizeL
15
14
  import type { LanguageMetadata } from '../../utils/languageUtils';
16
15
 
17
16
  // Define the context shape
18
- // NOTE: We intentionally avoid importing useFollow here to prevent a require cycle.
19
- // If consumers relied on `const { useFollow } = useOxy()`, we provide a lazy proxy below.
20
-
21
17
  export interface OxyContextState {
22
18
  // Authentication state
23
19
  user: User | null; // Current active user (loaded from server)
@@ -62,34 +58,8 @@ export interface OxyContextState {
62
58
  // Methods to directly control the bottom sheet
63
59
  showBottomSheet?: (screenOrConfig?: RouteName | string | { screen: RouteName | string; props?: Record<string, any> }) => void;
64
60
  hideBottomSheet?: () => void;
65
-
66
- /**
67
- * (Deprecated) useFollow hook access via context. Prefer: import { useFollow } from '@oxyhq/services';
68
- * Kept for backward compatibility; implemented as a lazy dynamic require to avoid circular dependency.
69
- */
70
- useFollow: UseFollowHook; // Back-compat; prefer direct import
71
61
  }
72
62
 
73
- // Empty follow hook fallback
74
- const createEmptyFollowHook = (): UseFollowHook => {
75
- const emptyResult = {
76
- isFollowing: false,
77
- isLoading: false,
78
- error: null,
79
- toggleFollow: async () => { },
80
- setFollowStatus: () => { },
81
- fetchStatus: async () => { },
82
- clearError: () => { },
83
- followerCount: null,
84
- followingCount: null,
85
- isLoadingCounts: false,
86
- fetchUserCounts: async () => { },
87
- setFollowerCount: () => { },
88
- setFollowingCount: () => { },
89
- };
90
- return () => emptyResult;
91
- };
92
-
93
63
  // Create the context with default values
94
64
  const OxyContext = createContext<OxyContextState | null>(null);
95
65
 
@@ -903,29 +873,6 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
903
873
  }, [logout]),
904
874
  });
905
875
 
906
- // Context value - optimized to prevent unnecessary re-renders
907
- // Lazy proxy to load the hook only when accessed, breaking the static import cycle.
908
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
909
- const useFollowProxy: UseFollowHook = (userId?: string | string[]) => {
910
- try {
911
- // Dynamically require to avoid top-level cycle
912
- // eslint-disable-next-line @typescript-eslint/no-var-requires
913
- const mod = require('../hooks/useFollow');
914
- if (mod && typeof mod.useFollow === 'function') {
915
- return mod.useFollow(userId);
916
- }
917
- if (__DEV__) {
918
- console.warn('useFollow module did not export a function as expected');
919
- }
920
- return createEmptyFollowHook()(userId);
921
- } catch (e) {
922
- if (__DEV__) {
923
- console.warn('Failed to dynamically load useFollow hook:', e);
924
- }
925
- return createEmptyFollowHook()(userId);
926
- }
927
- };
928
-
929
876
  // Compute language metadata from currentLanguage
930
877
  const languageMetadata = useMemo(() => getLanguageMetadata(currentLanguage), [currentLanguage]);
931
878
  const languageName = useMemo(() => getLanguageName(currentLanguage), [currentLanguage]);
@@ -960,7 +907,6 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
960
907
  bottomSheetRef,
961
908
  showBottomSheet,
962
909
  hideBottomSheet,
963
- useFollow: useFollowProxy,
964
910
  }), [
965
911
  user?.id, // Only depend on user ID, not the entire user object
966
912
  minimalUser?.id,
@@ -80,7 +80,6 @@ export interface OxyProviderProps {
80
80
  /**
81
81
  * @internal
82
82
  * Reference to the bottom sheet component (for internal use only)
83
- * @deprecated External bottom sheet ref is no longer required as OxyProvider handles the bottom sheet internally
84
83
  * @hidden
85
84
  */
86
85
  bottomSheetRef?: React.RefObject<BottomSheetController | null>;
@@ -6,12 +6,14 @@ import {
6
6
  ScrollView,
7
7
  Switch,
8
8
  ActivityIndicator,
9
+ TouchableOpacity,
9
10
  } from 'react-native';
10
11
  import type { BaseScreenProps } from '../navigation/types';
11
12
  import { useOxy } from '../context/OxyContext';
12
13
  import { toast } from '../../lib/sonner';
13
- import { Header, Section } from '../components';
14
+ import { Header, Section, Avatar } from '../components';
14
15
  import { useI18n } from '../hooks/useI18n';
16
+ import type { BlockedUser, RestrictedUser } from '../../models/interfaces';
15
17
 
16
18
  interface PrivacySettings {
17
19
  isPrivateAccount: boolean;
@@ -67,8 +69,11 @@ const PrivacySettingsScreen: React.FC<BaseScreenProps> = ({
67
69
  });
68
70
  const [isLoading, setIsLoading] = useState(true);
69
71
  const [isSaving, setIsSaving] = useState(false);
72
+ const [blockedUsers, setBlockedUsers] = useState<BlockedUser[]>([]);
73
+ const [restrictedUsers, setRestrictedUsers] = useState<RestrictedUser[]>([]);
74
+ const [isLoadingUsers, setIsLoadingUsers] = useState(false);
70
75
 
71
- // Load settings
76
+ // Load settings and users
72
77
  useEffect(() => {
73
78
  const loadSettings = async () => {
74
79
  try {
@@ -90,6 +95,28 @@ const PrivacySettingsScreen: React.FC<BaseScreenProps> = ({
90
95
  loadSettings();
91
96
  }, [user?.id, oxyServices, t]);
92
97
 
98
+ // Load blocked and restricted users
99
+ useEffect(() => {
100
+ const loadUsers = async () => {
101
+ if (!oxyServices) return;
102
+ try {
103
+ setIsLoadingUsers(true);
104
+ const [blocked, restricted] = await Promise.all([
105
+ oxyServices.getBlockedUsers(),
106
+ oxyServices.getRestrictedUsers(),
107
+ ]);
108
+ setBlockedUsers(blocked);
109
+ setRestrictedUsers(restricted);
110
+ } catch (error) {
111
+ console.error('Failed to load blocked/restricted users:', error);
112
+ } finally {
113
+ setIsLoadingUsers(false);
114
+ }
115
+ };
116
+
117
+ loadUsers();
118
+ }, [oxyServices]);
119
+
93
120
  const updateSetting = useCallback(async (key: keyof PrivacySettings, value: boolean) => {
94
121
  try {
95
122
  setIsSaving(true);
@@ -110,6 +137,113 @@ const PrivacySettingsScreen: React.FC<BaseScreenProps> = ({
110
137
  }
111
138
  }, [settings, user?.id, oxyServices, t]);
112
139
 
140
+ const handleUnblock = useCallback(async (userId: string) => {
141
+ if (!oxyServices) return;
142
+ try {
143
+ await oxyServices.unblockUser(userId);
144
+ setBlockedUsers(prev => prev.filter(u => {
145
+ const id = typeof u.blockedId === 'string' ? u.blockedId : u.blockedId._id;
146
+ return id !== userId;
147
+ }));
148
+ toast.success(t('privacySettings.userUnblocked') || 'User unblocked');
149
+ } catch (error) {
150
+ console.error('Failed to unblock user:', error);
151
+ toast.error(t('privacySettings.unblockError') || 'Failed to unblock user');
152
+ }
153
+ }, [oxyServices, t]);
154
+
155
+ const handleUnrestrict = useCallback(async (userId: string) => {
156
+ if (!oxyServices) return;
157
+ try {
158
+ await oxyServices.unrestrictUser(userId);
159
+ setRestrictedUsers(prev => prev.filter(u => {
160
+ const id = typeof u.restrictedId === 'string' ? u.restrictedId : u.restrictedId._id;
161
+ return id !== userId;
162
+ }));
163
+ toast.success(t('privacySettings.userUnrestricted') || 'User unrestricted');
164
+ } catch (error) {
165
+ console.error('Failed to unrestrict user:', error);
166
+ toast.error(t('privacySettings.unrestrictError') || 'Failed to unrestrict user');
167
+ }
168
+ }, [oxyServices, t]);
169
+
170
+ // Helper to extract user info from blocked/restricted objects
171
+ const extractUserInfo = useCallback((
172
+ item: BlockedUser | RestrictedUser,
173
+ idField: 'blockedId' | 'restrictedId'
174
+ ) => {
175
+ let userIdField: string | { _id: string; username?: string; avatar?: string };
176
+ let username: string;
177
+ let avatar: string | undefined;
178
+
179
+ if (idField === 'blockedId' && 'blockedId' in item) {
180
+ userIdField = item.blockedId;
181
+ username = typeof item.blockedId === 'string'
182
+ ? (item.username || 'Unknown')
183
+ : (item.blockedId.username || 'Unknown');
184
+ avatar = typeof item.blockedId === 'string' ? item.avatar : item.blockedId.avatar;
185
+ } else if (idField === 'restrictedId' && 'restrictedId' in item) {
186
+ userIdField = item.restrictedId;
187
+ username = typeof item.restrictedId === 'string'
188
+ ? (item.username || 'Unknown')
189
+ : (item.restrictedId.username || 'Unknown');
190
+ avatar = typeof item.restrictedId === 'string' ? item.avatar : item.restrictedId.avatar;
191
+ } else {
192
+ // Fallback (should not happen)
193
+ return { userId: '', username: 'Unknown', avatar: undefined };
194
+ }
195
+
196
+ const userId = typeof userIdField === 'string' ? userIdField : userIdField._id;
197
+ return { userId, username, avatar };
198
+ }, []);
199
+
200
+ // Reusable user list item component
201
+ const UserListItem: React.FC<{
202
+ item: BlockedUser | RestrictedUser;
203
+ idField: 'blockedId' | 'restrictedId';
204
+ onAction: (userId: string) => void;
205
+ actionLabel: string;
206
+ actionColor: string;
207
+ subtitle?: string;
208
+ }> = ({ item, idField, onAction, actionLabel, actionColor, subtitle }) => {
209
+ const { userId, username, avatar } = extractUserInfo(item, idField);
210
+ // Convert avatar file ID to URI if needed
211
+ const avatarUri = avatar && oxyServices
212
+ ? oxyServices.getFileDownloadUrl(avatar, 'thumb')
213
+ : undefined;
214
+
215
+ return (
216
+ <View style={[styles.userRow, { borderBottomColor: themeStyles.borderColor }]}>
217
+ <View style={styles.userInfo}>
218
+ <Avatar
219
+ uri={avatarUri}
220
+ name={username}
221
+ size={40}
222
+ theme={theme}
223
+ />
224
+ <View style={styles.userDetails}>
225
+ <Text style={[styles.username, { color: themeStyles.textColor }]}>
226
+ {username}
227
+ </Text>
228
+ {subtitle && (
229
+ <Text style={[styles.userSubtext, { color: themeStyles.mutedTextColor }]}>
230
+ {subtitle}
231
+ </Text>
232
+ )}
233
+ </View>
234
+ </View>
235
+ <TouchableOpacity
236
+ onPress={() => onAction(userId)}
237
+ style={[styles.actionButton, { backgroundColor: themeStyles.secondaryBackgroundColor }]}
238
+ >
239
+ <Text style={[styles.actionButtonText, { color: actionColor }]}>
240
+ {actionLabel}
241
+ </Text>
242
+ </TouchableOpacity>
243
+ </View>
244
+ );
245
+ };
246
+
113
247
  const themeStyles = useMemo(() => {
114
248
  const isDarkTheme = theme === 'dark';
115
249
  return {
@@ -288,6 +422,65 @@ const PrivacySettingsScreen: React.FC<BaseScreenProps> = ({
288
422
  onValueChange={(value) => updateSetting('blockScreenshots', value)}
289
423
  />
290
424
  </Section>
425
+
426
+ {/* Blocked Users */}
427
+ <Section title={t('privacySettings.sections.blockedUsers') || 'BLOCKED USERS'} theme={theme}>
428
+ {isLoadingUsers ? (
429
+ <View style={styles.loadingUsersContainer}>
430
+ <ActivityIndicator size="small" color={themeStyles.textColor} />
431
+ </View>
432
+ ) : blockedUsers.length === 0 ? (
433
+ <View style={styles.emptyContainer}>
434
+ <Text style={[styles.emptyText, { color: themeStyles.mutedTextColor }]}>
435
+ {t('privacySettings.noBlockedUsers') || 'No blocked users'}
436
+ </Text>
437
+ </View>
438
+ ) : (
439
+ blockedUsers.map((blocked) => {
440
+ const { userId } = extractUserInfo(blocked, 'blockedId');
441
+ return (
442
+ <UserListItem
443
+ key={userId}
444
+ item={blocked}
445
+ idField="blockedId"
446
+ onAction={handleUnblock}
447
+ actionLabel={t('privacySettings.unblock') || 'Unblock'}
448
+ actionColor="#FF3B30"
449
+ />
450
+ );
451
+ })
452
+ )}
453
+ </Section>
454
+
455
+ {/* Restricted Users */}
456
+ <Section title={t('privacySettings.sections.restrictedUsers') || 'RESTRICTED USERS'} theme={theme}>
457
+ {isLoadingUsers ? (
458
+ <View style={styles.loadingUsersContainer}>
459
+ <ActivityIndicator size="small" color={themeStyles.textColor} />
460
+ </View>
461
+ ) : restrictedUsers.length === 0 ? (
462
+ <View style={styles.emptyContainer}>
463
+ <Text style={[styles.emptyText, { color: themeStyles.mutedTextColor }]}>
464
+ {t('privacySettings.noRestrictedUsers') || 'No restricted users'}
465
+ </Text>
466
+ </View>
467
+ ) : (
468
+ restrictedUsers.map((restricted) => {
469
+ const { userId } = extractUserInfo(restricted, 'restrictedId');
470
+ return (
471
+ <UserListItem
472
+ key={userId}
473
+ item={restricted}
474
+ idField="restrictedId"
475
+ onAction={handleUnrestrict}
476
+ actionLabel={t('privacySettings.unrestrict') || 'Unrestrict'}
477
+ actionColor="#007AFF"
478
+ subtitle={t('privacySettings.restrictedDescription') || 'Limited interactions'}
479
+ />
480
+ );
481
+ })
482
+ )}
483
+ </Section>
291
484
  </ScrollView>
292
485
  </View>
293
486
  );
@@ -326,6 +519,51 @@ const styles = StyleSheet.create({
326
519
  fontSize: 14,
327
520
  opacity: 0.7,
328
521
  },
522
+ loadingUsersContainer: {
523
+ paddingVertical: 20,
524
+ alignItems: 'center',
525
+ },
526
+ emptyContainer: {
527
+ paddingVertical: 20,
528
+ alignItems: 'center',
529
+ },
530
+ emptyText: {
531
+ fontSize: 14,
532
+ },
533
+ userRow: {
534
+ flexDirection: 'row',
535
+ justifyContent: 'space-between',
536
+ alignItems: 'center',
537
+ paddingVertical: 12,
538
+ borderBottomWidth: 1,
539
+ },
540
+ userInfo: {
541
+ flexDirection: 'row',
542
+ alignItems: 'center',
543
+ flex: 1,
544
+ marginRight: 12,
545
+ },
546
+ userDetails: {
547
+ marginLeft: 12,
548
+ flex: 1,
549
+ },
550
+ username: {
551
+ fontSize: 16,
552
+ fontWeight: '500',
553
+ marginBottom: 2,
554
+ },
555
+ userSubtext: {
556
+ fontSize: 13,
557
+ },
558
+ actionButton: {
559
+ paddingHorizontal: 16,
560
+ paddingVertical: 8,
561
+ borderRadius: 8,
562
+ },
563
+ actionButtonText: {
564
+ fontSize: 14,
565
+ fontWeight: '600',
566
+ },
329
567
  });
330
568
 
331
569
  export default React.memo(PrivacySettingsScreen);
@@ -70,20 +70,6 @@ export interface ErrorResponse {
70
70
  details?: any;
71
71
  }
72
72
 
73
- /**
74
- * Validate required parameters
75
- * @param params Object to validate
76
- * @param requiredKeys Array of required keys
77
- * @throws Error if any required key is missing
78
- */
79
- export function validateRequiredParams(params: Record<string, any>, requiredKeys: string[]): void {
80
- const missing = requiredKeys.filter(key => params[key] === undefined || params[key] === null);
81
-
82
- if (missing.length > 0) {
83
- throw new Error(`Missing required parameters: ${missing.join(', ')}`);
84
- }
85
- }
86
-
87
73
  /**
88
74
  * Safe JSON parsing with error handling
89
75
  * @param data Data to parse
@@ -196,26 +196,6 @@ export async function withTimeout<T>(
196
196
  return Promise.race([operation, timeoutPromise]);
197
197
  }
198
198
 
199
- /**
200
- * Cache async operation results
201
- * @deprecated Use TTLCache from '../utils/cache' instead
202
- * This function is kept for backward compatibility but will be removed in a future version
203
- */
204
- export function createAsyncCache<T>(
205
- ttl: number = 5 * 60 * 1000 // 5 minutes default
206
- ) {
207
- // Re-export from centralized cache utility
208
- const cache = new TTLCache<T>(ttl);
209
- registerCacheForCleanup(cache);
210
-
211
- return {
212
- get: (key: string): T | null => cache.get(key),
213
- set: (key: string, data: T): void => cache.set(key, data),
214
- clear: (): void => cache.clear(),
215
- delete: (key: string): boolean => cache.delete(key),
216
- };
217
- }
218
-
219
199
  /**
220
200
  * Execute async operation with loading state
221
201
  */
@@ -1,192 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
- var _react = require("react");
8
- var _reactNative = require("react-native");
9
- var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
10
- var _vectorIcons = require("@expo/vector-icons");
11
- var _Avatar = _interopRequireDefault(require("../../components/Avatar"));
12
- var _useI18n = require("../../hooks/useI18n");
13
- var _OxyContext = require("../../context/OxyContext");
14
- var _GroupedPillButtons = _interopRequireDefault(require("../../components/internal/GroupedPillButtons"));
15
- var _TextField = _interopRequireDefault(require("../../components/internal/TextField"));
16
- var _jsxRuntime = require("react/jsx-runtime");
17
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
18
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
19
- const SignInPasswordStep = ({
20
- styles,
21
- fadeAnim,
22
- slideAnim,
23
- scaleAnim,
24
- colors,
25
- userProfile,
26
- username,
27
- theme,
28
- logoAnim,
29
- errorMessage,
30
- isInputFocused,
31
- password,
32
- showPassword,
33
- handleInputFocus,
34
- handleInputBlur,
35
- handlePasswordChange,
36
- handleSignIn: parentHandleSignIn,
37
- isLoading,
38
- prevStep,
39
- navigate
40
- }) => {
41
- const inputRef = (0, _react.useRef)(null);
42
- const {
43
- t
44
- } = (0, _useI18n.useI18n)();
45
- const {
46
- oxyServices
47
- } = (0, _OxyContext.useOxy)();
48
-
49
- // Animated styles - properly memoized to prevent re-renders
50
- const containerAnimatedStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
51
- return {
52
- opacity: fadeAnim.value,
53
- transform: [{
54
- translateX: slideAnim.value
55
- }, {
56
- scale: scaleAnim.value
57
- }]
58
- };
59
- });
60
- const logoAnimatedStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
61
- return {
62
- transform: [{
63
- scale: logoAnim.value
64
- }]
65
- };
66
- });
67
-
68
- // Focus password input on error or when step becomes active
69
- (0, _react.useEffect)(() => {
70
- if (errorMessage) {
71
- setTimeout(() => {
72
- inputRef.current?.focus();
73
- }, 0);
74
- }
75
- }, [errorMessage]);
76
- const handleSignIn = (0, _react.useCallback)(() => {
77
- if (!password || errorMessage) {
78
- setTimeout(() => {
79
- inputRef.current?.focus();
80
- }, 0);
81
- }
82
- parentHandleSignIn();
83
- }, [password, errorMessage, parentHandleSignIn]);
84
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeReanimated.default.View, {
85
- style: [styles.stepContainer, containerAnimatedStyle],
86
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
87
- style: styles.modernUserProfileContainer,
88
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
89
- style: logoAnimatedStyle,
90
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Avatar.default, {
91
- name: userProfile?.displayName || userProfile?.name || username,
92
- size: 100,
93
- theme: theme,
94
- backgroundColor: colors.primary + '20',
95
- uri: userProfile?.avatar && oxyServices ? oxyServices.getFileDownloadUrl(userProfile.avatar, 'thumb') : undefined
96
- })
97
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
98
- style: [styles.modernUserDisplayName, {
99
- color: colors.text
100
- }],
101
- children: userProfile?.displayName || userProfile?.name || username
102
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
103
- style: [styles.modernUsernameSubtext, {
104
- color: colors.secondaryText
105
- }],
106
- children: ["@", username]
107
- })]
108
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
109
- style: styles.modernInputContainer,
110
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_TextField.default, {
111
- ref: inputRef,
112
- label: t('common.labels.password'),
113
- leading: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
114
- name: "lock-closed-outline",
115
- size: 24,
116
- color: colors.secondaryText
117
- }),
118
- value: password,
119
- onChangeText: handlePasswordChange,
120
- onFocus: handleInputFocus,
121
- onBlur: handleInputBlur,
122
- secureTextEntry: !showPassword,
123
- autoCapitalize: "none",
124
- autoCorrect: false,
125
- testID: "password-input",
126
- variant: "filled",
127
- error: errorMessage || undefined,
128
- onSubmitEditing: handleSignIn,
129
- autoFocus: true
130
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
131
- style: {
132
- flexDirection: 'row',
133
- alignItems: 'center',
134
- marginBottom: 16
135
- },
136
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
137
- style: [styles.footerText, {
138
- color: colors.text
139
- }],
140
- children: [t('signin.forgotPrompt') || 'Forgot your password?', " "]
141
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
142
- onPress: () => navigate('RecoverAccount', {
143
- returnTo: 'SignIn',
144
- returnStep: 1,
145
- returnData: {
146
- username,
147
- userProfile
148
- }
149
- }),
150
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
151
- style: [styles.modernLinkText, {
152
- color: colors.primary
153
- }],
154
- children: t('common.links.recoverAccount')
155
- })
156
- })]
157
- })]
158
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_GroupedPillButtons.default, {
159
- buttons: [{
160
- text: t('common.actions.back'),
161
- onPress: prevStep,
162
- icon: 'arrow-back',
163
- variant: 'transparent'
164
- }, {
165
- text: t('common.actions.signIn'),
166
- onPress: handleSignIn,
167
- icon: 'log-in',
168
- variant: 'primary',
169
- loading: isLoading,
170
- testID: 'login-button'
171
- }],
172
- colors: colors
173
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
174
- style: styles.securityNotice,
175
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
176
- name: "shield-checkmark",
177
- size: 14,
178
- color: colors.secondaryText
179
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
180
- style: [styles.securityText, {
181
- color: colors.secondaryText
182
- }],
183
- children: t('signin.security.dataSecure') || 'Your data is encrypted and secure'
184
- })]
185
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.StatusBar, {
186
- barStyle: theme === 'dark' ? 'light-content' : 'dark-content',
187
- backgroundColor: colors.background
188
- })]
189
- });
190
- };
191
- var _default = exports.default = SignInPasswordStep;
192
- //# sourceMappingURL=SignInPasswordStep.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["_react","require","_reactNative","_reactNativeReanimated","_interopRequireWildcard","_vectorIcons","_Avatar","_interopRequireDefault","_useI18n","_OxyContext","_GroupedPillButtons","_TextField","_jsxRuntime","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","SignInPasswordStep","styles","fadeAnim","slideAnim","scaleAnim","colors","userProfile","username","theme","logoAnim","errorMessage","isInputFocused","password","showPassword","handleInputFocus","handleInputBlur","handlePasswordChange","handleSignIn","parentHandleSignIn","isLoading","prevStep","navigate","inputRef","useRef","useI18n","oxyServices","useOxy","containerAnimatedStyle","useAnimatedStyle","opacity","value","transform","translateX","scale","logoAnimatedStyle","useEffect","setTimeout","current","focus","useCallback","jsxs","View","style","stepContainer","children","modernUserProfileContainer","jsx","name","displayName","size","backgroundColor","primary","uri","avatar","getFileDownloadUrl","undefined","Text","modernUserDisplayName","color","text","modernUsernameSubtext","secondaryText","modernInputContainer","ref","label","leading","Ionicons","onChangeText","onFocus","onBlur","secureTextEntry","autoCapitalize","autoCorrect","testID","variant","error","onSubmitEditing","autoFocus","flexDirection","alignItems","marginBottom","footerText","TouchableOpacity","onPress","returnTo","returnStep","returnData","modernLinkText","buttons","icon","loading","securityNotice","securityText","StatusBar","barStyle","background","_default","exports"],"sourceRoot":"../../../../../src","sources":["ui/screens/internal/SignInPasswordStep.tsx"],"mappings":"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","ignoreList":[]}