@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.
- package/lib/commonjs/core/OxyServices.js +159 -0
- package/lib/commonjs/core/OxyServices.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +1 -47
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/screens/PrivacySettingsScreen.js +239 -1
- package/lib/commonjs/ui/screens/PrivacySettingsScreen.js.map +1 -1
- package/lib/commonjs/utils/apiUtils.js +0 -14
- package/lib/commonjs/utils/apiUtils.js.map +1 -1
- package/lib/commonjs/utils/asyncUtils.js +0 -20
- package/lib/commonjs/utils/asyncUtils.js.map +1 -1
- package/lib/module/core/OxyServices.js +159 -0
- package/lib/module/core/OxyServices.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +1 -47
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/navigation/types.js.map +1 -1
- package/lib/module/ui/screens/PrivacySettingsScreen.js +241 -3
- package/lib/module/ui/screens/PrivacySettingsScreen.js.map +1 -1
- package/lib/module/utils/apiUtils.js +0 -13
- package/lib/module/utils/apiUtils.js.map +1 -1
- package/lib/module/utils/asyncUtils.js +0 -20
- package/lib/module/utils/asyncUtils.js.map +1 -1
- package/lib/typescript/core/OxyServices.d.ts +65 -1
- package/lib/typescript/core/OxyServices.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +1 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/models/interfaces.d.ts +26 -0
- package/lib/typescript/models/interfaces.d.ts.map +1 -1
- package/lib/typescript/ui/context/OxyContext.d.ts +0 -6
- package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/ui/navigation/types.d.ts +0 -1
- package/lib/typescript/ui/navigation/types.d.ts.map +1 -1
- package/lib/typescript/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
- package/lib/typescript/utils/apiUtils.d.ts +0 -7
- package/lib/typescript/utils/apiUtils.d.ts.map +1 -1
- package/lib/typescript/utils/asyncUtils.d.ts +0 -11
- package/lib/typescript/utils/asyncUtils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/core/OxyServices.ts +174 -1
- package/src/index.ts +4 -0
- package/src/models/interfaces.ts +28 -0
- package/src/ui/context/OxyContext.tsx +0 -54
- package/src/ui/navigation/types.ts +0 -1
- package/src/ui/screens/PrivacySettingsScreen.tsx +240 -2
- package/src/utils/apiUtils.ts +0 -14
- package/src/utils/asyncUtils.ts +0 -20
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js +0 -192
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js.map +0 -1
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js +0 -142
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js.map +0 -1
- package/lib/commonjs/ui/screens/internal/SignUpIdentityStep.js +0 -113
- package/lib/commonjs/ui/screens/internal/SignUpIdentityStep.js.map +0 -1
- package/lib/commonjs/ui/screens/internal/SignUpSecurityStep.js +0 -132
- package/lib/commonjs/ui/screens/internal/SignUpSecurityStep.js.map +0 -1
- package/lib/commonjs/ui/screens/internal/SignUpSummaryStep.js +0 -83
- package/lib/commonjs/ui/screens/internal/SignUpSummaryStep.js.map +0 -1
- package/lib/commonjs/ui/screens/internal/SignUpWelcomeStep.js +0 -58
- package/lib/commonjs/ui/screens/internal/SignUpWelcomeStep.js.map +0 -1
- package/lib/module/ui/screens/internal/SignInPasswordStep.js +0 -186
- package/lib/module/ui/screens/internal/SignInPasswordStep.js.map +0 -1
- package/lib/module/ui/screens/internal/SignInUsernameStep.js +0 -136
- package/lib/module/ui/screens/internal/SignInUsernameStep.js.map +0 -1
- package/lib/module/ui/screens/internal/SignUpIdentityStep.js +0 -108
- package/lib/module/ui/screens/internal/SignUpIdentityStep.js.map +0 -1
- package/lib/module/ui/screens/internal/SignUpSecurityStep.js +0 -127
- package/lib/module/ui/screens/internal/SignUpSecurityStep.js.map +0 -1
- package/lib/module/ui/screens/internal/SignUpSummaryStep.js +0 -78
- package/lib/module/ui/screens/internal/SignUpSummaryStep.js.map +0 -1
- package/lib/module/ui/screens/internal/SignUpWelcomeStep.js +0 -53
- package/lib/module/ui/screens/internal/SignUpWelcomeStep.js.map +0 -1
- package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts +0 -28
- package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts.map +0 -1
- package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts +0 -25
- package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts.map +0 -1
- package/lib/typescript/ui/screens/internal/SignUpIdentityStep.d.ts +0 -20
- package/lib/typescript/ui/screens/internal/SignUpIdentityStep.d.ts.map +0 -1
- package/lib/typescript/ui/screens/internal/SignUpSecurityStep.d.ts +0 -24
- package/lib/typescript/ui/screens/internal/SignUpSecurityStep.d.ts.map +0 -1
- package/lib/typescript/ui/screens/internal/SignUpSummaryStep.d.ts +0 -15
- package/lib/typescript/ui/screens/internal/SignUpSummaryStep.d.ts.map +0 -1
- package/lib/typescript/ui/screens/internal/SignUpWelcomeStep.d.ts +0 -13
- package/lib/typescript/ui/screens/internal/SignUpWelcomeStep.d.ts.map +0 -1
- package/src/ui/screens/internal/SignInPasswordStep.tsx +0 -184
- package/src/ui/screens/internal/SignInUsernameStep.tsx +0 -145
- package/src/ui/screens/internal/SignUpIdentityStep.tsx +0 -112
- package/src/ui/screens/internal/SignUpSecurityStep.tsx +0 -132
- package/src/ui/screens/internal/SignUpSummaryStep.tsx +0 -66
- 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);
|
package/src/utils/apiUtils.ts
CHANGED
|
@@ -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
|
package/src/utils/asyncUtils.ts
CHANGED
|
@@ -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":[]}
|