@oxyhq/services 5.13.4 → 5.13.10
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/HttpClient.js +1 -1
- package/lib/commonjs/core/HttpClient.js.map +1 -1
- package/lib/commonjs/core/OxyServices.js +83 -30
- package/lib/commonjs/core/OxyServices.js.map +1 -1
- package/lib/commonjs/core/index.js +0 -7
- package/lib/commonjs/core/index.js.map +1 -1
- package/lib/commonjs/i18n/locales/en-US.json +222 -6
- package/lib/commonjs/index.js +0 -7
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/lib/sonner.js.map +1 -1
- package/lib/commonjs/ui/components/GroupedItem.js +24 -22
- package/lib/commonjs/ui/components/GroupedItem.js.map +1 -1
- package/lib/commonjs/ui/components/OxyProvider.js +35 -14
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/navigation/routes.js +36 -1
- package/lib/commonjs/ui/navigation/routes.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js +150 -5
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js +475 -319
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountVerificationScreen.js +217 -0
- package/lib/commonjs/ui/screens/AccountVerificationScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/FileManagementScreen.js +911 -213
- package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/HelpSupportScreen.js +131 -0
- package/lib/commonjs/ui/screens/HelpSupportScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/HistoryViewScreen.js +258 -0
- package/lib/commonjs/ui/screens/HistoryViewScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/LegalDocumentsScreen.js +211 -0
- package/lib/commonjs/ui/screens/LegalDocumentsScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +0 -1
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PrivacySettingsScreen.js +307 -0
- package/lib/commonjs/ui/screens/PrivacySettingsScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/ProfileScreen.js +1 -7
- package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SavesCollectionsScreen.js +205 -0
- package/lib/commonjs/ui/screens/SavesCollectionsScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/SearchSettingsScreen.js +239 -0
- package/lib/commonjs/ui/screens/SearchSettingsScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/SignInScreen.js +14 -29
- package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
- package/lib/commonjs/utils/asyncUtils.js +1 -0
- package/lib/commonjs/utils/asyncUtils.js.map +1 -1
- package/lib/commonjs/utils/cache.js +4 -4
- package/lib/commonjs/utils/cache.js.map +1 -1
- package/lib/commonjs/utils/index.js +0 -6
- package/lib/commonjs/utils/index.js.map +1 -1
- package/lib/module/core/HttpClient.js +1 -1
- package/lib/module/core/HttpClient.js.map +1 -1
- package/lib/module/core/OxyServices.js +82 -29
- package/lib/module/core/OxyServices.js.map +1 -1
- package/lib/module/core/index.js +1 -1
- package/lib/module/core/index.js.map +1 -1
- package/lib/module/i18n/locales/en-US.json +222 -6
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/lib/sonner.js.map +1 -1
- package/lib/module/ui/components/GroupedItem.js +24 -22
- package/lib/module/ui/components/GroupedItem.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +40 -17
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/navigation/routes.js +36 -1
- package/lib/module/ui/navigation/routes.js.map +1 -1
- package/lib/module/ui/screens/AccountOverviewScreen.js +151 -6
- package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSettingsScreen.js +475 -319
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountVerificationScreen.js +212 -0
- package/lib/module/ui/screens/AccountVerificationScreen.js.map +1 -0
- package/lib/module/ui/screens/FileManagementScreen.js +913 -212
- package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/HelpSupportScreen.js +126 -0
- package/lib/module/ui/screens/HelpSupportScreen.js.map +1 -0
- package/lib/module/ui/screens/HistoryViewScreen.js +253 -0
- package/lib/module/ui/screens/HistoryViewScreen.js.map +1 -0
- package/lib/module/ui/screens/LegalDocumentsScreen.js +206 -0
- package/lib/module/ui/screens/LegalDocumentsScreen.js.map +1 -0
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js +0 -1
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/module/ui/screens/PrivacySettingsScreen.js +302 -0
- package/lib/module/ui/screens/PrivacySettingsScreen.js.map +1 -0
- package/lib/module/ui/screens/ProfileScreen.js +1 -7
- package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/module/ui/screens/SavesCollectionsScreen.js +200 -0
- package/lib/module/ui/screens/SavesCollectionsScreen.js.map +1 -0
- package/lib/module/ui/screens/SearchSettingsScreen.js +234 -0
- package/lib/module/ui/screens/SearchSettingsScreen.js.map +1 -0
- package/lib/module/ui/screens/SignInScreen.js +14 -29
- package/lib/module/ui/screens/SignInScreen.js.map +1 -1
- package/lib/module/utils/asyncUtils.js +1 -0
- package/lib/module/utils/asyncUtils.js.map +1 -1
- package/lib/module/utils/cache.js +3 -3
- package/lib/module/utils/cache.js.map +1 -1
- package/lib/module/utils/index.js +1 -1
- package/lib/module/utils/index.js.map +1 -1
- package/lib/typescript/core/OxyServices.d.ts +30 -24
- package/lib/typescript/core/OxyServices.d.ts.map +1 -1
- package/lib/typescript/core/index.d.ts +1 -1
- package/lib/typescript/core/index.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/lib/sonner.d.ts +1 -0
- package/lib/typescript/lib/sonner.d.ts.map +1 -1
- package/lib/typescript/types/expo-document-picker.d.ts +36 -0
- package/lib/typescript/ui/components/GroupedItem.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/ui/navigation/routes.d.ts +1 -1
- package/lib/typescript/ui/navigation/routes.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountVerificationScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/AccountVerificationScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/FileManagementScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/HelpSupportScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/HelpSupportScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/HistoryViewScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/HistoryViewScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/LegalDocumentsScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/LegalDocumentsScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/PrivacySettingsScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/PrivacySettingsScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/ProfileScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SavesCollectionsScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/SavesCollectionsScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/SearchSettingsScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/SearchSettingsScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
- package/lib/typescript/utils/asyncUtils.d.ts.map +1 -1
- package/lib/typescript/utils/cache.d.ts +3 -3
- package/lib/typescript/utils/cache.d.ts.map +1 -1
- package/lib/typescript/utils/index.d.ts +1 -1
- package/lib/typescript/utils/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/core/HttpClient.ts +1 -1
- package/src/core/OxyServices.ts +80 -30
- package/src/core/index.ts +1 -1
- package/src/i18n/locales/en-US.json +222 -6
- package/src/index.ts +1 -1
- package/src/lib/sonner.ts +1 -0
- package/src/types/expo-document-picker.d.ts +36 -0
- package/src/ui/components/GroupedItem.tsx +23 -21
- package/src/ui/components/OxyProvider.tsx +33 -11
- package/src/ui/navigation/routes.ts +42 -0
- package/src/ui/screens/AccountOverviewScreen.tsx +175 -5
- package/src/ui/screens/AccountSettingsScreen.tsx +521 -360
- package/src/ui/screens/AccountVerificationScreen.tsx +235 -0
- package/src/ui/screens/FileManagementScreen.tsx +934 -208
- package/src/ui/screens/HelpSupportScreen.tsx +143 -0
- package/src/ui/screens/HistoryViewScreen.tsx +280 -0
- package/src/ui/screens/LegalDocumentsScreen.tsx +220 -0
- package/src/ui/screens/PremiumSubscriptionScreen.tsx +0 -1
- package/src/ui/screens/PrivacySettingsScreen.tsx +332 -0
- package/src/ui/screens/ProfileScreen.tsx +1 -8
- package/src/ui/screens/SavesCollectionsScreen.tsx +222 -0
- package/src/ui/screens/SearchSettingsScreen.tsx +219 -0
- package/src/ui/screens/SignInScreen.tsx +19 -35
- package/src/utils/asyncUtils.ts +1 -0
- package/src/utils/cache.ts +3 -3
- package/src/utils/index.ts +1 -1
- package/lib/commonjs/ui/components/StepBasedScreen.README.md +0 -337
- package/lib/commonjs/ui/components/internal/TextField.md +0 -436
- package/lib/commonjs/ui/styles/FONTS.md +0 -126
- package/lib/module/ui/components/StepBasedScreen.README.md +0 -337
- package/lib/module/ui/components/internal/TextField.md +0 -436
- package/lib/module/ui/styles/FONTS.md +0 -126
- package/src/ui/components/StepBasedScreen.README.md +0 -337
- package/src/ui/components/internal/TextField.md +0 -436
- package/src/ui/styles/FONTS.md +0 -126
|
@@ -32,7 +32,7 @@ const AccountSettingsScreen = ({
|
|
|
32
32
|
navigate
|
|
33
33
|
}) => {
|
|
34
34
|
const {
|
|
35
|
-
user,
|
|
35
|
+
user: userFromContext,
|
|
36
36
|
oxyServices,
|
|
37
37
|
isLoading: authLoading,
|
|
38
38
|
isAuthenticated,
|
|
@@ -43,8 +43,15 @@ const AccountSettingsScreen = ({
|
|
|
43
43
|
t
|
|
44
44
|
} = (0, _useI18n.useI18n)();
|
|
45
45
|
const updateUser = (0, _authStore.useAuthStore)(state => state.updateUser);
|
|
46
|
+
// Get user directly from store to ensure reactivity to avatar changes
|
|
47
|
+
const user = (0, _authStore.useAuthStore)(state => state.user) || userFromContext;
|
|
46
48
|
const [isLoading, setIsLoading] = (0, _react.useState)(false);
|
|
47
49
|
const [isSaving, setIsSaving] = (0, _react.useState)(false);
|
|
50
|
+
const [isUpdatingAvatar, setIsUpdatingAvatar] = (0, _react.useState)(false);
|
|
51
|
+
const [optimisticAvatarId, setOptimisticAvatarId] = (0, _react.useState)(null);
|
|
52
|
+
const scrollViewRef = (0, _react.useRef)(null);
|
|
53
|
+
const avatarSectionRef = (0, _react.useRef)(null);
|
|
54
|
+
const [avatarSectionY, setAvatarSectionY] = (0, _react.useState)(null);
|
|
48
55
|
|
|
49
56
|
// Two-Factor (TOTP) state
|
|
50
57
|
const [totpSetupUrl, setTotpSetupUrl] = (0, _react.useState)(null);
|
|
@@ -69,8 +76,6 @@ const AccountSettingsScreen = ({
|
|
|
69
76
|
|
|
70
77
|
// Editing states
|
|
71
78
|
const [editingField, setEditingField] = (0, _react.useState)(null);
|
|
72
|
-
|
|
73
|
-
// Temporary input states for inline editing
|
|
74
79
|
const [tempDisplayName, setTempDisplayName] = (0, _react.useState)('');
|
|
75
80
|
const [tempLastName, setTempLastName] = (0, _react.useState)('');
|
|
76
81
|
const [tempUsername, setTempUsername] = (0, _react.useState)('');
|
|
@@ -101,82 +106,118 @@ const AccountSettingsScreen = ({
|
|
|
101
106
|
}, [theme]);
|
|
102
107
|
|
|
103
108
|
// Memoize animation function to prevent recreation on every render
|
|
104
|
-
const animateSaveButton = (0, _react.useCallback)(toValue => {
|
|
109
|
+
const animateSaveButton = (0, _react.useCallback)((toValue, onComplete) => {
|
|
105
110
|
_reactNative.Animated.spring(saveButtonScale, {
|
|
106
111
|
toValue,
|
|
107
112
|
useNativeDriver: _reactNative.Platform.OS !== 'web',
|
|
108
113
|
tension: 150,
|
|
109
114
|
friction: 8
|
|
110
|
-
}).start(
|
|
115
|
+
}).start(onComplete ? finished => {
|
|
116
|
+
if (finished) {
|
|
117
|
+
onComplete();
|
|
118
|
+
}
|
|
119
|
+
} : undefined);
|
|
111
120
|
}, [saveButtonScale]);
|
|
112
121
|
|
|
113
|
-
//
|
|
122
|
+
// Track initialization to prevent unnecessary resets
|
|
123
|
+
const isInitializedRef = (0, _react.useRef)(false);
|
|
124
|
+
const previousUserIdRef = (0, _react.useRef)(null);
|
|
125
|
+
const previousAvatarRef = (0, _react.useRef)(null);
|
|
126
|
+
|
|
127
|
+
// Load user data - only reset fields when user actually changes (not just avatar)
|
|
114
128
|
(0, _react.useEffect)(() => {
|
|
115
129
|
if (user) {
|
|
116
|
-
const
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
130
|
+
const currentUserId = user.id;
|
|
131
|
+
const currentAvatar = typeof user.avatar === 'string' ? user.avatar : '';
|
|
132
|
+
const isNewUser = previousUserIdRef.current !== currentUserId;
|
|
133
|
+
const isAvatarOnlyUpdate = !isNewUser && previousUserIdRef.current === currentUserId && previousAvatarRef.current !== currentAvatar && previousAvatarRef.current !== null;
|
|
134
|
+
const shouldInitialize = !isInitializedRef.current || isNewUser;
|
|
135
|
+
|
|
136
|
+
// Only reset all fields if it's a new user or first load
|
|
137
|
+
// Skip reset if it's just an avatar update
|
|
138
|
+
if (shouldInitialize && !isAvatarOnlyUpdate) {
|
|
139
|
+
const userDisplayName = typeof user.name === 'string' ? user.name : user.name?.first || user.name?.full || '';
|
|
140
|
+
const userLastName = typeof user.name === 'object' ? user.name?.last || '' : '';
|
|
141
|
+
setDisplayName(userDisplayName);
|
|
142
|
+
setLastName(userLastName);
|
|
143
|
+
setUsername(user.username || '');
|
|
144
|
+
setEmail(user.email || '');
|
|
145
|
+
setBio(user.bio || '');
|
|
146
|
+
setLocation(user.location || '');
|
|
124
147
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
148
|
+
// Handle locations - convert single location to array format
|
|
149
|
+
if (user.locations && Array.isArray(user.locations)) {
|
|
150
|
+
setTempLocations(user.locations.map((loc, index) => ({
|
|
151
|
+
id: loc.id || `existing-${index}`,
|
|
152
|
+
name: loc.name,
|
|
153
|
+
label: loc.label,
|
|
154
|
+
coordinates: loc.coordinates
|
|
155
|
+
})));
|
|
156
|
+
} else if (user.location) {
|
|
157
|
+
// Convert single location string to array format
|
|
158
|
+
setTempLocations([{
|
|
159
|
+
id: 'existing-0',
|
|
160
|
+
name: user.location,
|
|
161
|
+
label: 'Location'
|
|
162
|
+
}]);
|
|
163
|
+
} else {
|
|
164
|
+
setTempLocations([]);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Handle links - simple and direct like other fields
|
|
168
|
+
if (user.linksMetadata && Array.isArray(user.linksMetadata)) {
|
|
169
|
+
const urls = user.linksMetadata.map(l => l.url);
|
|
170
|
+
setLinks(urls);
|
|
171
|
+
const metadataWithIds = user.linksMetadata.map((link, index) => ({
|
|
172
|
+
...link,
|
|
173
|
+
id: link.id || `existing-${index}`
|
|
174
|
+
}));
|
|
175
|
+
setTempLinksWithMetadata(metadataWithIds);
|
|
176
|
+
} else if (Array.isArray(user.links)) {
|
|
177
|
+
const simpleLinks = user.links.map(l => typeof l === 'string' ? l : l.link).filter(Boolean);
|
|
178
|
+
setLinks(simpleLinks);
|
|
179
|
+
const linksWithMetadata = simpleLinks.map((url, index) => ({
|
|
180
|
+
url,
|
|
181
|
+
title: url.replace(/^https?:\/\//, '').replace(/\/$/, ''),
|
|
182
|
+
description: `Link to ${url}`,
|
|
183
|
+
image: undefined,
|
|
184
|
+
id: `existing-${index}`
|
|
185
|
+
}));
|
|
186
|
+
setTempLinksWithMetadata(linksWithMetadata);
|
|
187
|
+
} else if (user.website) {
|
|
188
|
+
setLinks([user.website]);
|
|
189
|
+
setTempLinksWithMetadata([{
|
|
190
|
+
url: user.website,
|
|
191
|
+
title: user.website.replace(/^https?:\/\//, '').replace(/\/$/, ''),
|
|
192
|
+
description: `Link to ${user.website}`,
|
|
193
|
+
image: undefined,
|
|
194
|
+
id: 'existing-0'
|
|
195
|
+
}]);
|
|
196
|
+
} else {
|
|
197
|
+
setLinks([]);
|
|
198
|
+
setTempLinksWithMetadata([]);
|
|
199
|
+
}
|
|
200
|
+
isInitializedRef.current = true;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Update avatar only if it changed and we're not in optimistic/updating state
|
|
204
|
+
// This allows the server response to update the avatar without resetting other fields
|
|
205
|
+
// But don't override if we have a pending optimistic update
|
|
206
|
+
if (currentAvatar !== avatarFileId && !isUpdatingAvatar && !optimisticAvatarId) {
|
|
207
|
+
setAvatarFileId(currentAvatar);
|
|
142
208
|
}
|
|
143
209
|
|
|
144
|
-
//
|
|
145
|
-
if
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
id: link.id || `existing-${index}`
|
|
151
|
-
}));
|
|
152
|
-
setTempLinksWithMetadata(metadataWithIds);
|
|
153
|
-
} else if (Array.isArray(user.links)) {
|
|
154
|
-
const simpleLinks = user.links.map(l => typeof l === 'string' ? l : l.link).filter(Boolean);
|
|
155
|
-
setLinks(simpleLinks);
|
|
156
|
-
const linksWithMetadata = simpleLinks.map((url, index) => ({
|
|
157
|
-
url,
|
|
158
|
-
title: url.replace(/^https?:\/\//, '').replace(/\/$/, ''),
|
|
159
|
-
description: `Link to ${url}`,
|
|
160
|
-
image: undefined,
|
|
161
|
-
id: `existing-${index}`
|
|
162
|
-
}));
|
|
163
|
-
setTempLinksWithMetadata(linksWithMetadata);
|
|
164
|
-
} else if (user.website) {
|
|
165
|
-
setLinks([user.website]);
|
|
166
|
-
setTempLinksWithMetadata([{
|
|
167
|
-
url: user.website,
|
|
168
|
-
title: user.website.replace(/^https?:\/\//, '').replace(/\/$/, ''),
|
|
169
|
-
description: `Link to ${user.website}`,
|
|
170
|
-
image: undefined,
|
|
171
|
-
id: 'existing-0'
|
|
172
|
-
}]);
|
|
173
|
-
} else {
|
|
174
|
-
setLinks([]);
|
|
175
|
-
setTempLinksWithMetadata([]);
|
|
210
|
+
// If we just finished updating and the server avatar matches our optimistic one, clear optimistic state
|
|
211
|
+
// Also clear if the server avatar matches our current avatarFileId (update completed)
|
|
212
|
+
if (isUpdatingAvatar === false && optimisticAvatarId) {
|
|
213
|
+
if (currentAvatar === optimisticAvatarId || currentAvatar === avatarFileId) {
|
|
214
|
+
setOptimisticAvatarId(null);
|
|
215
|
+
}
|
|
176
216
|
}
|
|
177
|
-
|
|
217
|
+
previousUserIdRef.current = currentUserId;
|
|
218
|
+
previousAvatarRef.current = currentAvatar;
|
|
178
219
|
}
|
|
179
|
-
}, [user]);
|
|
220
|
+
}, [user, avatarFileId, isUpdatingAvatar, optimisticAvatarId]);
|
|
180
221
|
const handleSave = async () => {
|
|
181
222
|
if (!user) return;
|
|
182
223
|
try {
|
|
@@ -193,8 +234,6 @@ const AccountSettingsScreen = ({
|
|
|
193
234
|
links,
|
|
194
235
|
linksMetadata: tempLinksWithMetadata.length > 0 ? tempLinksWithMetadata : undefined
|
|
195
236
|
};
|
|
196
|
-
console.log('Saving updates:', updates);
|
|
197
|
-
console.log('Links metadata being saved:', tempLinksWithMetadata);
|
|
198
237
|
|
|
199
238
|
// Handle name field
|
|
200
239
|
if (displayName || lastName) {
|
|
@@ -247,33 +286,74 @@ const AccountSettingsScreen = ({
|
|
|
247
286
|
_sonner.toast.info?.(t('editProfile.toasts.avatarUnchanged') || 'Avatar unchanged');
|
|
248
287
|
return;
|
|
249
288
|
}
|
|
289
|
+
|
|
290
|
+
// Optimistically update UI immediately
|
|
291
|
+
setOptimisticAvatarId(file.id);
|
|
250
292
|
setAvatarFileId(file.id);
|
|
251
|
-
|
|
293
|
+
|
|
252
294
|
// Auto-save avatar immediately (does not close edit profile screen)
|
|
253
295
|
(async () => {
|
|
254
296
|
try {
|
|
255
|
-
|
|
256
|
-
setIsSaving(true);
|
|
297
|
+
setIsUpdatingAvatar(true);
|
|
257
298
|
|
|
258
299
|
// Update file visibility to public for avatar
|
|
259
300
|
try {
|
|
260
301
|
await oxyServices.assetUpdateVisibility(file.id, 'public');
|
|
261
|
-
console.log('[AccountSettings] Avatar visibility updated to public');
|
|
262
302
|
} catch (visError) {
|
|
263
|
-
console.warn('[AccountSettings] Failed to update avatar visibility, continuing anyway:', visError);
|
|
264
303
|
// Continue with avatar update even if visibility update fails
|
|
265
304
|
}
|
|
266
|
-
|
|
305
|
+
|
|
306
|
+
// Update on server directly without using updateUser (which triggers fetchUser)
|
|
307
|
+
// This prevents the entire component from re-rendering
|
|
308
|
+
await oxyServices.updateProfile({
|
|
267
309
|
avatar: file.id
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
//
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
// Update the user object in store directly without triggering fetchUser
|
|
313
|
+
// This prevents isLoading from being set to true, which would show loading screen
|
|
314
|
+
const currentUser = _authStore.useAuthStore.getState().user;
|
|
315
|
+
if (currentUser) {
|
|
316
|
+
_authStore.useAuthStore.setState({
|
|
317
|
+
user: {
|
|
318
|
+
...currentUser,
|
|
319
|
+
avatar: file.id
|
|
320
|
+
}
|
|
321
|
+
// Don't update lastUserFetch to avoid cache issues
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Update local state - keep avatarFileId set to the new value
|
|
326
|
+
// Don't clear optimisticAvatarId yet - let it persist until user object updates
|
|
327
|
+
// This ensures the avatar displays correctly
|
|
328
|
+
setAvatarFileId(file.id);
|
|
271
329
|
_sonner.toast.success(t('editProfile.toasts.avatarUpdated') || 'Avatar updated');
|
|
330
|
+
|
|
331
|
+
// Scroll to avatar section after a brief delay to ensure UI is updated
|
|
332
|
+
requestAnimationFrame(() => {
|
|
333
|
+
requestAnimationFrame(() => {
|
|
334
|
+
if (avatarSectionY !== null) {
|
|
335
|
+
scrollViewRef.current?.scrollTo({
|
|
336
|
+
y: Math.max(0, avatarSectionY - 100),
|
|
337
|
+
// Offset to show section near top
|
|
338
|
+
animated: true
|
|
339
|
+
});
|
|
340
|
+
} else {
|
|
341
|
+
// Fallback: scroll to approximate position
|
|
342
|
+
scrollViewRef.current?.scrollTo({
|
|
343
|
+
y: 200,
|
|
344
|
+
// Approximate position of avatar section
|
|
345
|
+
animated: true
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
});
|
|
272
350
|
} catch (e) {
|
|
273
|
-
|
|
351
|
+
// Revert optimistic update on error
|
|
352
|
+
setAvatarFileId(typeof user?.avatar === 'string' ? user.avatar : '');
|
|
353
|
+
setOptimisticAvatarId(null);
|
|
274
354
|
_sonner.toast.error(e.message || t('editProfile.toasts.updateAvatarFailed') || 'Failed to update avatar');
|
|
275
355
|
} finally {
|
|
276
|
-
|
|
356
|
+
setIsUpdatingAvatar(false);
|
|
277
357
|
}
|
|
278
358
|
})();
|
|
279
359
|
},
|
|
@@ -281,7 +361,7 @@ const AccountSettingsScreen = ({
|
|
|
281
361
|
disabledMimeTypes: ['video/', 'audio/', 'application/pdf']
|
|
282
362
|
}
|
|
283
363
|
});
|
|
284
|
-
}, [showBottomSheet, oxyServices, avatarFileId, updateUser]);
|
|
364
|
+
}, [showBottomSheet, oxyServices, avatarFileId, updateUser, user]);
|
|
285
365
|
const startEditing = (type, currentValue) => {
|
|
286
366
|
switch (type) {
|
|
287
367
|
case 'displayName':
|
|
@@ -340,11 +420,10 @@ const AccountSettingsScreen = ({
|
|
|
340
420
|
break;
|
|
341
421
|
}
|
|
342
422
|
|
|
343
|
-
//
|
|
344
|
-
|
|
345
|
-
animateSaveButton(1);
|
|
423
|
+
// Complete animation, then reset and close editing
|
|
424
|
+
animateSaveButton(1, () => {
|
|
346
425
|
setEditingField(null);
|
|
347
|
-
}
|
|
426
|
+
});
|
|
348
427
|
};
|
|
349
428
|
const cancelEditing = () => {
|
|
350
429
|
setEditingField(null);
|
|
@@ -358,11 +437,9 @@ const AccountSettingsScreen = ({
|
|
|
358
437
|
}
|
|
359
438
|
try {
|
|
360
439
|
setIsFetchingMetadata(true);
|
|
361
|
-
console.log('Fetching metadata for URL:', url);
|
|
362
440
|
|
|
363
441
|
// Use the backend API to fetch metadata
|
|
364
442
|
const metadata = await oxyServices.fetchLinkMetadata(url);
|
|
365
|
-
console.log('Received metadata:', metadata);
|
|
366
443
|
const result = {
|
|
367
444
|
...metadata,
|
|
368
445
|
id: Date.now().toString()
|
|
@@ -372,7 +449,6 @@ const AccountSettingsScreen = ({
|
|
|
372
449
|
linkMetadataCache.set(cacheKey, result);
|
|
373
450
|
return result;
|
|
374
451
|
} catch (error) {
|
|
375
|
-
console.error('Error fetching metadata:', error);
|
|
376
452
|
// Fallback to basic metadata
|
|
377
453
|
const fallback = {
|
|
378
454
|
url: url.startsWith('http') ? url : 'https://' + url,
|
|
@@ -410,7 +486,6 @@ const AccountSettingsScreen = ({
|
|
|
410
486
|
locationSearchCache.set(cacheKey, data);
|
|
411
487
|
setLocationSearchResults(data);
|
|
412
488
|
} catch (error) {
|
|
413
|
-
console.error('Error searching locations:', error);
|
|
414
489
|
setLocationSearchResults([]);
|
|
415
490
|
} finally {
|
|
416
491
|
setIsSearchingLocations(false);
|
|
@@ -445,9 +520,7 @@ const AccountSettingsScreen = ({
|
|
|
445
520
|
const addLink = async () => {
|
|
446
521
|
if (!newLinkUrl.trim()) return;
|
|
447
522
|
const url = newLinkUrl.trim();
|
|
448
|
-
console.log('Adding link:', url);
|
|
449
523
|
const metadata = await fetchLinkMetadata(url);
|
|
450
|
-
console.log('Final metadata for adding:', metadata);
|
|
451
524
|
setTempLinksWithMetadata(prev => [...prev, metadata]);
|
|
452
525
|
setNewLinkUrl('');
|
|
453
526
|
setIsAddingLink(false);
|
|
@@ -523,7 +596,7 @@ const AccountSettingsScreen = ({
|
|
|
523
596
|
style: {
|
|
524
597
|
padding: 16,
|
|
525
598
|
backgroundColor: '#fff',
|
|
526
|
-
borderRadius:
|
|
599
|
+
borderRadius: 16
|
|
527
600
|
},
|
|
528
601
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeQrcodeSvg.default, {
|
|
529
602
|
value: totpSetupUrl,
|
|
@@ -652,7 +725,7 @@ const AccountSettingsScreen = ({
|
|
|
652
725
|
style: [styles.editingFieldLabel, {
|
|
653
726
|
color: themeStyles.isDarkTheme ? '#FFFFFF' : '#1A1A1A'
|
|
654
727
|
}],
|
|
655
|
-
children: "Edit
|
|
728
|
+
children: "Edit Full Name"
|
|
656
729
|
})
|
|
657
730
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
658
731
|
style: {
|
|
@@ -1084,7 +1157,7 @@ const AccountSettingsScreen = ({
|
|
|
1084
1157
|
};
|
|
1085
1158
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1086
1159
|
style: [styles.editingFieldContainer, {
|
|
1087
|
-
backgroundColor: themeStyles.
|
|
1160
|
+
backgroundColor: themeStyles.isDarkTheme ? '#000000' : '#FFFFFF'
|
|
1088
1161
|
}],
|
|
1089
1162
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1090
1163
|
style: styles.editingFieldContent,
|
|
@@ -1094,20 +1167,20 @@ const AccountSettingsScreen = ({
|
|
|
1094
1167
|
style: styles.editingFieldHeader,
|
|
1095
1168
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1096
1169
|
style: [styles.editingFieldLabel, {
|
|
1097
|
-
color: themeStyles.isDarkTheme ? '#FFFFFF' : '#
|
|
1170
|
+
color: themeStyles.isDarkTheme ? '#FFFFFF' : '#000000'
|
|
1098
1171
|
}],
|
|
1099
|
-
children:
|
|
1172
|
+
children: config.label
|
|
1100
1173
|
})
|
|
1101
1174
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
|
|
1102
1175
|
style: [config.multiline ? styles.editingFieldTextArea : styles.editingFieldInput, {
|
|
1103
|
-
backgroundColor: themeStyles.isDarkTheme ? '#
|
|
1104
|
-
color: themeStyles.isDarkTheme ? '#
|
|
1105
|
-
borderColor: themeStyles.
|
|
1176
|
+
backgroundColor: themeStyles.isDarkTheme ? '#1C1C1E' : '#F2F2F7',
|
|
1177
|
+
color: themeStyles.isDarkTheme ? '#FFFFFF' : '#000000',
|
|
1178
|
+
borderColor: themeStyles.isDarkTheme ? '#38383A' : '#E5E5EA'
|
|
1106
1179
|
}],
|
|
1107
1180
|
value: tempValue,
|
|
1108
1181
|
onChangeText: setTempValue,
|
|
1109
1182
|
placeholder: config.placeholder,
|
|
1110
|
-
placeholderTextColor: themeStyles.isDarkTheme ? '#
|
|
1183
|
+
placeholderTextColor: themeStyles.isDarkTheme ? '#636366' : '#8E8E93',
|
|
1111
1184
|
multiline: config.multiline,
|
|
1112
1185
|
numberOfLines: config.multiline ? 6 : 1,
|
|
1113
1186
|
keyboardType: config.keyboardType,
|
|
@@ -1121,7 +1194,7 @@ const AccountSettingsScreen = ({
|
|
|
1121
1194
|
if (authLoading || !isAuthenticated) {
|
|
1122
1195
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1123
1196
|
style: [styles.container, {
|
|
1124
|
-
backgroundColor: themeStyles.
|
|
1197
|
+
backgroundColor: themeStyles.isDarkTheme ? '#000000' : '#F5F5F7',
|
|
1125
1198
|
justifyContent: 'center'
|
|
1126
1199
|
}],
|
|
1127
1200
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
|
|
@@ -1132,19 +1205,21 @@ const AccountSettingsScreen = ({
|
|
|
1132
1205
|
}
|
|
1133
1206
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1134
1207
|
style: [styles.container, {
|
|
1135
|
-
backgroundColor: themeStyles.
|
|
1208
|
+
backgroundColor: themeStyles.isDarkTheme ? '#000000' : '#F5F5F7'
|
|
1136
1209
|
}],
|
|
1137
1210
|
children: [editingField ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1138
1211
|
style: [styles.editingHeader, {
|
|
1139
|
-
backgroundColor: '#FFFFFF',
|
|
1140
|
-
borderBottomColor: themeStyles.isDarkTheme ? '#38383A' : '#
|
|
1212
|
+
backgroundColor: themeStyles.isDarkTheme ? '#000000' : '#FFFFFF',
|
|
1213
|
+
borderBottomColor: themeStyles.isDarkTheme ? '#38383A' : '#E5E5EA'
|
|
1141
1214
|
}],
|
|
1142
1215
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1143
1216
|
style: styles.editingHeaderContent,
|
|
1144
1217
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
1145
|
-
style: styles.editingBackButton,
|
|
1218
|
+
style: [styles.editingBackButton, {
|
|
1219
|
+
backgroundColor: themeStyles.isDarkTheme ? '#1C1C1E' : '#F2F2F7'
|
|
1220
|
+
}],
|
|
1146
1221
|
onPress: cancelEditing,
|
|
1147
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
1222
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
|
|
1148
1223
|
name: "chevron-back",
|
|
1149
1224
|
size: 20,
|
|
1150
1225
|
color: themeStyles.primaryColor
|
|
@@ -1153,7 +1228,8 @@ const AccountSettingsScreen = ({
|
|
|
1153
1228
|
style: styles.editingTitleContainer
|
|
1154
1229
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
1155
1230
|
style: [styles.editingSaveButton, {
|
|
1156
|
-
opacity: isSaving ? 0.5 : 1
|
|
1231
|
+
opacity: isSaving ? 0.5 : 1,
|
|
1232
|
+
backgroundColor: themeStyles.isDarkTheme ? '#1C1C1E' : '#F2F2F7'
|
|
1157
1233
|
}],
|
|
1158
1234
|
onPress: () => saveField(editingField),
|
|
1159
1235
|
disabled: isSaving,
|
|
@@ -1169,14 +1245,18 @@ const AccountSettingsScreen = ({
|
|
|
1169
1245
|
})]
|
|
1170
1246
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1171
1247
|
style: styles.editingHeaderBottom,
|
|
1172
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1248
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1249
|
+
style: [styles.editingIconContainer, {
|
|
1250
|
+
backgroundColor: editingField === 'displayName' ? '#007AFF20' : editingField === 'username' ? '#5856D620' : editingField === 'email' ? '#FF950020' : editingField === 'bio' ? '#34C75920' : editingField === 'location' ? '#FF3B3020' : editingField === 'links' ? '#32D74B20' : '#007AFF20'
|
|
1251
|
+
}],
|
|
1252
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
|
|
1253
|
+
name: editingField === 'displayName' ? 'person' : editingField === 'username' ? 'at' : editingField === 'email' ? 'mail' : editingField === 'bio' ? 'document-text' : editingField === 'location' ? 'location' : editingField === 'links' ? 'link' : 'person',
|
|
1254
|
+
size: 28,
|
|
1255
|
+
color: editingField === 'displayName' ? '#007AFF' : editingField === 'username' ? '#5856D6' : editingField === 'email' ? '#FF9500' : editingField === 'bio' ? '#34C759' : editingField === 'location' ? '#FF3B30' : editingField === 'links' ? '#32D74B' : '#007AFF'
|
|
1256
|
+
})
|
|
1177
1257
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1178
1258
|
style: [styles.editingBottomTitle, {
|
|
1179
|
-
color: themeStyles.isDarkTheme ? '#FFFFFF' : '#
|
|
1259
|
+
color: themeStyles.isDarkTheme ? '#FFFFFF' : '#000000'
|
|
1180
1260
|
}],
|
|
1181
1261
|
children: editingField === 'displayName' ? t('editProfile.items.displayName.title') || 'Display Name' : editingField === 'username' ? t('editProfile.items.username.title') || 'Username' : editingField === 'email' ? t('editProfile.items.email.title') || 'Email' : editingField === 'bio' ? t('editProfile.items.bio.title') || 'Bio' : editingField === 'location' ? t('editProfile.items.locations.title') || 'Location' : editingField === 'links' ? t('editProfile.items.links.title') || 'Links' : 'Field'
|
|
1182
1262
|
})]
|
|
@@ -1193,6 +1273,7 @@ const AccountSettingsScreen = ({
|
|
|
1193
1273
|
},
|
|
1194
1274
|
elevation: "subtle"
|
|
1195
1275
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
|
|
1276
|
+
ref: scrollViewRef,
|
|
1196
1277
|
style: editingField ? styles.contentEditing : styles.content,
|
|
1197
1278
|
children: editingField ?
|
|
1198
1279
|
/*#__PURE__*/
|
|
@@ -1219,7 +1300,7 @@ const AccountSettingsScreen = ({
|
|
|
1219
1300
|
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1220
1301
|
style: {
|
|
1221
1302
|
backgroundColor: '#fff',
|
|
1222
|
-
borderRadius:
|
|
1303
|
+
borderRadius: 20,
|
|
1223
1304
|
padding: 20,
|
|
1224
1305
|
maxHeight: '80%'
|
|
1225
1306
|
},
|
|
@@ -1251,7 +1332,7 @@ const AccountSettingsScreen = ({
|
|
|
1251
1332
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1252
1333
|
style: {
|
|
1253
1334
|
backgroundColor: '#F8F9FA',
|
|
1254
|
-
borderRadius:
|
|
1335
|
+
borderRadius: 12,
|
|
1255
1336
|
padding: 12
|
|
1256
1337
|
},
|
|
1257
1338
|
children: generatedBackupCodes.map((c, idx) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
@@ -1277,7 +1358,7 @@ const AccountSettingsScreen = ({
|
|
|
1277
1358
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1278
1359
|
style: {
|
|
1279
1360
|
backgroundColor: '#F8F9FA',
|
|
1280
|
-
borderRadius:
|
|
1361
|
+
borderRadius: 12,
|
|
1281
1362
|
padding: 12
|
|
1282
1363
|
},
|
|
1283
1364
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
@@ -1309,198 +1390,265 @@ const AccountSettingsScreen = ({
|
|
|
1309
1390
|
})]
|
|
1310
1391
|
})
|
|
1311
1392
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1393
|
+
ref: avatarSectionRef,
|
|
1312
1394
|
style: styles.section,
|
|
1395
|
+
onLayout: event => {
|
|
1396
|
+
const {
|
|
1397
|
+
y
|
|
1398
|
+
} = event.nativeEvent.layout;
|
|
1399
|
+
setAvatarSectionY(y);
|
|
1400
|
+
},
|
|
1313
1401
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1314
|
-
style: styles.sectionTitle,
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1402
|
+
style: [styles.sectionTitle, {
|
|
1403
|
+
color: themeStyles.isDarkTheme ? '#8E8E93' : '#8E8E93'
|
|
1404
|
+
}],
|
|
1405
|
+
children: t('editProfile.sections.profilePicture') || 'PROFILE PICTURE'
|
|
1406
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1407
|
+
style: styles.groupedSectionWrapper,
|
|
1408
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.GroupedSection, {
|
|
1409
|
+
items: [{
|
|
1410
|
+
id: 'profile-photo',
|
|
1411
|
+
icon: avatarFileId ? undefined : 'person',
|
|
1412
|
+
iconColor: '#007AFF',
|
|
1413
|
+
// Use optimistic avatar ID if available, otherwise use saved one
|
|
1414
|
+
image: optimisticAvatarId || avatarFileId ? oxyServices.getFileDownloadUrl(optimisticAvatarId || avatarFileId, 'thumb') : undefined,
|
|
1415
|
+
imageSize: 40,
|
|
1416
|
+
title: 'Profile Photo',
|
|
1417
|
+
subtitle: isUpdatingAvatar ? 'Updating profile picture...' : avatarFileId ? 'Tap to change your profile picture' : 'Tap to add a profile picture',
|
|
1418
|
+
onPress: isUpdatingAvatar ? undefined : openAvatarPicker,
|
|
1419
|
+
disabled: isUpdatingAvatar,
|
|
1420
|
+
customIcon: isUpdatingAvatar ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
|
|
1421
|
+
style: {
|
|
1422
|
+
position: 'relative',
|
|
1423
|
+
width: 40,
|
|
1424
|
+
height: 40
|
|
1425
|
+
},
|
|
1426
|
+
children: [(optimisticAvatarId || avatarFileId) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.Image, {
|
|
1427
|
+
source: {
|
|
1428
|
+
uri: oxyServices.getFileDownloadUrl(optimisticAvatarId || avatarFileId, 'thumb')
|
|
1429
|
+
},
|
|
1430
|
+
style: {
|
|
1431
|
+
width: 40,
|
|
1432
|
+
height: 40,
|
|
1433
|
+
borderRadius: 22,
|
|
1434
|
+
opacity: 0.6
|
|
1435
|
+
}
|
|
1436
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1437
|
+
style: {
|
|
1438
|
+
position: 'absolute',
|
|
1439
|
+
top: 0,
|
|
1440
|
+
left: 0,
|
|
1441
|
+
right: 0,
|
|
1442
|
+
bottom: 0,
|
|
1443
|
+
justifyContent: 'center',
|
|
1444
|
+
alignItems: 'center',
|
|
1445
|
+
backgroundColor: themeStyles.isDarkTheme ? 'rgba(0, 0, 0, 0.4)' : 'rgba(255, 255, 255, 0.7)',
|
|
1446
|
+
borderRadius: 22
|
|
1447
|
+
},
|
|
1448
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
|
|
1449
|
+
size: "small",
|
|
1450
|
+
color: themeStyles.primaryColor
|
|
1451
|
+
})
|
|
1452
|
+
})]
|
|
1453
|
+
}) : undefined
|
|
1454
|
+
}, ...(avatarFileId && !isUpdatingAvatar ? [{
|
|
1455
|
+
id: 'remove-profile-photo',
|
|
1456
|
+
icon: 'trash',
|
|
1457
|
+
iconColor: '#FF3B30',
|
|
1458
|
+
title: 'Remove Photo',
|
|
1459
|
+
subtitle: 'Delete current profile picture',
|
|
1460
|
+
onPress: handleAvatarRemove
|
|
1461
|
+
}] : [])],
|
|
1462
|
+
theme: theme
|
|
1463
|
+
})
|
|
1336
1464
|
})]
|
|
1337
1465
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1338
1466
|
style: styles.section,
|
|
1339
1467
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1340
|
-
style: styles.sectionTitle,
|
|
1341
|
-
|
|
1342
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.GroupedSection, {
|
|
1343
|
-
items: [{
|
|
1344
|
-
id: 'display-name',
|
|
1345
|
-
icon: 'person',
|
|
1346
|
-
iconColor: '#007AFF',
|
|
1347
|
-
title: t('editProfile.items.displayName.title') || 'Display Name',
|
|
1348
|
-
subtitle: [displayName, lastName].filter(Boolean).join(' ') || t('editProfile.items.displayName.add') || 'Add your display name',
|
|
1349
|
-
onPress: () => startEditing('displayName', '')
|
|
1350
|
-
}, {
|
|
1351
|
-
id: 'username',
|
|
1352
|
-
icon: 'at',
|
|
1353
|
-
iconColor: '#5856D6',
|
|
1354
|
-
title: t('editProfile.items.username.title') || 'Username',
|
|
1355
|
-
subtitle: username || t('editProfile.items.username.choose') || 'Choose a username',
|
|
1356
|
-
onPress: () => startEditing('username', username)
|
|
1357
|
-
}, {
|
|
1358
|
-
id: 'email',
|
|
1359
|
-
icon: 'mail',
|
|
1360
|
-
iconColor: '#FF9500',
|
|
1361
|
-
title: t('editProfile.items.email.title') || 'Email',
|
|
1362
|
-
subtitle: email || t('editProfile.items.email.add') || 'Add your email address',
|
|
1363
|
-
onPress: () => startEditing('email', email)
|
|
1468
|
+
style: [styles.sectionTitle, {
|
|
1469
|
+
color: themeStyles.isDarkTheme ? '#8E8E93' : '#8E8E93'
|
|
1364
1470
|
}],
|
|
1365
|
-
|
|
1471
|
+
children: t('editProfile.sections.basicInfo') || 'BASIC INFORMATION'
|
|
1472
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1473
|
+
style: styles.groupedSectionWrapper,
|
|
1474
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.GroupedSection, {
|
|
1475
|
+
items: [{
|
|
1476
|
+
id: 'display-name',
|
|
1477
|
+
icon: 'person',
|
|
1478
|
+
iconColor: '#007AFF',
|
|
1479
|
+
title: t('editProfile.items.displayName.title') || 'Display Name',
|
|
1480
|
+
subtitle: [displayName, lastName].filter(Boolean).join(' ') || t('editProfile.items.displayName.add') || 'Add your display name',
|
|
1481
|
+
onPress: () => startEditing('displayName', '')
|
|
1482
|
+
}, {
|
|
1483
|
+
id: 'username',
|
|
1484
|
+
icon: 'at',
|
|
1485
|
+
iconColor: '#5856D6',
|
|
1486
|
+
title: t('editProfile.items.username.title') || 'Username',
|
|
1487
|
+
subtitle: username || t('editProfile.items.username.choose') || 'Choose a username',
|
|
1488
|
+
onPress: () => startEditing('username', username)
|
|
1489
|
+
}, {
|
|
1490
|
+
id: 'email',
|
|
1491
|
+
icon: 'mail',
|
|
1492
|
+
iconColor: '#FF9500',
|
|
1493
|
+
title: t('editProfile.items.email.title') || 'Email',
|
|
1494
|
+
subtitle: email || t('editProfile.items.email.add') || 'Add your email address',
|
|
1495
|
+
onPress: () => startEditing('email', email)
|
|
1496
|
+
}],
|
|
1497
|
+
theme: theme
|
|
1498
|
+
})
|
|
1366
1499
|
})]
|
|
1367
1500
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1368
1501
|
style: styles.section,
|
|
1369
1502
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1370
|
-
style: styles.sectionTitle,
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1503
|
+
style: [styles.sectionTitle, {
|
|
1504
|
+
color: themeStyles.isDarkTheme ? '#8E8E93' : '#8E8E93'
|
|
1505
|
+
}],
|
|
1506
|
+
children: t('editProfile.sections.about') || 'ABOUT YOU'
|
|
1507
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1508
|
+
style: styles.groupedSectionWrapper,
|
|
1509
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.GroupedSection, {
|
|
1510
|
+
items: [{
|
|
1511
|
+
id: 'bio',
|
|
1512
|
+
icon: 'document-text',
|
|
1513
|
+
iconColor: '#34C759',
|
|
1514
|
+
title: t('editProfile.items.bio.title') || 'Bio',
|
|
1515
|
+
subtitle: bio || t('editProfile.items.bio.placeholder') || 'Tell people about yourself',
|
|
1516
|
+
onPress: () => startEditing('bio', bio)
|
|
1517
|
+
}, {
|
|
1518
|
+
id: 'locations',
|
|
1519
|
+
icon: 'location',
|
|
1520
|
+
iconColor: '#FF3B30',
|
|
1521
|
+
title: t('editProfile.items.locations.title') || 'Locations',
|
|
1522
|
+
subtitle: tempLocations.length > 0 ? tempLocations.length === 1 ? t('editProfile.items.locations.count', {
|
|
1523
|
+
count: tempLocations.length
|
|
1524
|
+
}) || `${tempLocations.length} location added` : t('editProfile.items.locations.count_plural', {
|
|
1525
|
+
count: tempLocations.length
|
|
1526
|
+
}) || `${tempLocations.length} locations added` : t('editProfile.items.locations.add') || 'Add your locations',
|
|
1527
|
+
onPress: () => startEditing('location', ''),
|
|
1528
|
+
customContentBelow: tempLocations.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1529
|
+
style: styles.linksPreviewContainer,
|
|
1530
|
+
children: [tempLocations.slice(0, 2).map((location, index) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1531
|
+
style: styles.linkPreviewItem,
|
|
1532
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1533
|
+
style: styles.linkPreviewImage,
|
|
1534
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1535
|
+
style: styles.linkPreviewImageText,
|
|
1536
|
+
children: location.name.charAt(0).toUpperCase()
|
|
1537
|
+
})
|
|
1538
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1539
|
+
style: styles.linkPreviewContent,
|
|
1540
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1541
|
+
style: styles.linkPreviewTitle,
|
|
1542
|
+
numberOfLines: 1,
|
|
1543
|
+
children: location.name
|
|
1544
|
+
}), location.label && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1545
|
+
style: styles.linkPreviewSubtitle,
|
|
1546
|
+
children: location.label
|
|
1547
|
+
})]
|
|
1548
|
+
})]
|
|
1549
|
+
}, location.id || index)), tempLocations.length > 2 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
1550
|
+
style: styles.linkPreviewMore,
|
|
1551
|
+
children: ["+", tempLocations.length - 2, " more"]
|
|
1552
|
+
})]
|
|
1553
|
+
})
|
|
1554
|
+
}, {
|
|
1555
|
+
id: 'links',
|
|
1556
|
+
icon: 'link',
|
|
1557
|
+
iconColor: '#32D74B',
|
|
1558
|
+
title: t('editProfile.items.links.title') || 'Links',
|
|
1559
|
+
subtitle: tempLinksWithMetadata.length > 0 ? tempLinksWithMetadata.length === 1 ? t('editProfile.items.links.count', {
|
|
1560
|
+
count: tempLinksWithMetadata.length
|
|
1561
|
+
}) || `${tempLinksWithMetadata.length} link added` : t('editProfile.items.links.count_plural', {
|
|
1562
|
+
count: tempLinksWithMetadata.length
|
|
1563
|
+
}) || `${tempLinksWithMetadata.length} links added` : t('editProfile.items.links.add') || 'Add your links',
|
|
1564
|
+
onPress: () => startEditing('links', ''),
|
|
1565
|
+
multiRow: true,
|
|
1566
|
+
customContentBelow: tempLinksWithMetadata.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1567
|
+
style: styles.linksPreviewContainer,
|
|
1568
|
+
children: [tempLinksWithMetadata.slice(0, 2).map((link, index) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1569
|
+
style: styles.linkPreviewItem,
|
|
1570
|
+
children: [link.image ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Image, {
|
|
1571
|
+
source: {
|
|
1572
|
+
uri: link.image
|
|
1573
|
+
},
|
|
1574
|
+
style: styles.linkPreviewImage
|
|
1575
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1576
|
+
style: styles.linkPreviewImage,
|
|
1577
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1578
|
+
style: styles.linkPreviewImageText,
|
|
1579
|
+
children: link.title?.charAt(0).toUpperCase() || link.url.charAt(0).toUpperCase()
|
|
1580
|
+
})
|
|
1581
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1404
1582
|
style: styles.linkPreviewTitle,
|
|
1405
1583
|
numberOfLines: 1,
|
|
1406
|
-
children:
|
|
1407
|
-
}), location.label && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1408
|
-
style: styles.linkPreviewSubtitle,
|
|
1409
|
-
children: location.label
|
|
1584
|
+
children: link.title || link.url
|
|
1410
1585
|
})]
|
|
1586
|
+
}, link.id || index)), tempLinksWithMetadata.length > 2 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
1587
|
+
style: styles.linkPreviewMore,
|
|
1588
|
+
children: ["+", tempLinksWithMetadata.length - 2, " more"]
|
|
1411
1589
|
})]
|
|
1412
|
-
}
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
})
|
|
1417
|
-
}, {
|
|
1418
|
-
id: 'links',
|
|
1419
|
-
icon: 'link',
|
|
1420
|
-
iconColor: '#32D74B',
|
|
1421
|
-
title: t('editProfile.items.links.title') || 'Links',
|
|
1422
|
-
subtitle: tempLinksWithMetadata.length > 0 ? tempLinksWithMetadata.length === 1 ? t('editProfile.items.links.count', {
|
|
1423
|
-
count: tempLinksWithMetadata.length
|
|
1424
|
-
}) || `${tempLinksWithMetadata.length} link added` : t('editProfile.items.links.count_plural', {
|
|
1425
|
-
count: tempLinksWithMetadata.length
|
|
1426
|
-
}) || `${tempLinksWithMetadata.length} links added` : t('editProfile.items.links.add') || 'Add your links',
|
|
1427
|
-
onPress: () => startEditing('links', ''),
|
|
1428
|
-
multiRow: true,
|
|
1429
|
-
customContentBelow: tempLinksWithMetadata.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1430
|
-
style: styles.linksPreviewContainer,
|
|
1431
|
-
children: [tempLinksWithMetadata.slice(0, 2).map((link, index) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1432
|
-
style: styles.linkPreviewItem,
|
|
1433
|
-
children: [link.image ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Image, {
|
|
1434
|
-
source: {
|
|
1435
|
-
uri: link.image
|
|
1436
|
-
},
|
|
1437
|
-
style: styles.linkPreviewImage
|
|
1438
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1439
|
-
style: styles.linkPreviewImage,
|
|
1440
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1441
|
-
style: styles.linkPreviewImageText,
|
|
1442
|
-
children: link.title?.charAt(0).toUpperCase() || link.url.charAt(0).toUpperCase()
|
|
1443
|
-
})
|
|
1444
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1445
|
-
style: styles.linkPreviewTitle,
|
|
1446
|
-
numberOfLines: 1,
|
|
1447
|
-
children: link.title || link.url
|
|
1448
|
-
})]
|
|
1449
|
-
}, link.id || index)), tempLinksWithMetadata.length > 2 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
1450
|
-
style: styles.linkPreviewMore,
|
|
1451
|
-
children: ["+", tempLinksWithMetadata.length - 2, " more"]
|
|
1452
|
-
})]
|
|
1453
|
-
})
|
|
1454
|
-
}],
|
|
1455
|
-
theme: theme
|
|
1590
|
+
})
|
|
1591
|
+
}],
|
|
1592
|
+
theme: theme
|
|
1593
|
+
})
|
|
1456
1594
|
})]
|
|
1457
1595
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1458
1596
|
style: styles.section,
|
|
1459
1597
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1460
|
-
style: styles.sectionTitle,
|
|
1461
|
-
|
|
1462
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.GroupedSection, {
|
|
1463
|
-
items: [{
|
|
1464
|
-
id: 'preview-profile',
|
|
1465
|
-
icon: 'eye',
|
|
1466
|
-
iconColor: '#007AFF',
|
|
1467
|
-
title: t('editProfile.items.previewProfile.title') || 'Preview Profile',
|
|
1468
|
-
subtitle: t('editProfile.items.previewProfile.subtitle') || 'See how your profile looks to others',
|
|
1469
|
-
onPress: () => navigate?.('Profile', {
|
|
1470
|
-
userId: user?.id
|
|
1471
|
-
})
|
|
1472
|
-
}, {
|
|
1473
|
-
id: 'privacy-settings',
|
|
1474
|
-
icon: 'shield-checkmark',
|
|
1475
|
-
iconColor: '#8E8E93',
|
|
1476
|
-
title: t('editProfile.items.privacySettings.title') || 'Privacy Settings',
|
|
1477
|
-
subtitle: t('editProfile.items.privacySettings.subtitle') || 'Control who can see your profile',
|
|
1478
|
-
onPress: () => _sonner.toast.info(t('editProfile.items.privacySettings.coming') || 'Privacy settings coming soon!')
|
|
1479
|
-
}, {
|
|
1480
|
-
id: 'verify-account',
|
|
1481
|
-
icon: 'checkmark-circle',
|
|
1482
|
-
iconColor: '#30D158',
|
|
1483
|
-
title: t('editProfile.items.verifyAccount.title') || 'Verify Account',
|
|
1484
|
-
subtitle: t('editProfile.items.verifyAccount.subtitle') || 'Get a verified badge',
|
|
1485
|
-
onPress: () => _sonner.toast.info(t('editProfile.items.verifyAccount.coming') || 'Account verification coming soon!')
|
|
1598
|
+
style: [styles.sectionTitle, {
|
|
1599
|
+
color: themeStyles.isDarkTheme ? '#8E8E93' : '#8E8E93'
|
|
1486
1600
|
}],
|
|
1487
|
-
|
|
1601
|
+
children: t('editProfile.sections.quickActions') || 'QUICK ACTIONS'
|
|
1602
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1603
|
+
style: styles.groupedSectionWrapper,
|
|
1604
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.GroupedSection, {
|
|
1605
|
+
items: [{
|
|
1606
|
+
id: 'preview-profile',
|
|
1607
|
+
icon: 'eye',
|
|
1608
|
+
iconColor: '#007AFF',
|
|
1609
|
+
title: t('editProfile.items.previewProfile.title') || 'Preview Profile',
|
|
1610
|
+
subtitle: t('editProfile.items.previewProfile.subtitle') || 'See how your profile looks to others',
|
|
1611
|
+
onPress: () => navigate?.('Profile', {
|
|
1612
|
+
userId: user?.id
|
|
1613
|
+
})
|
|
1614
|
+
}, {
|
|
1615
|
+
id: 'privacy-settings',
|
|
1616
|
+
icon: 'shield-checkmark',
|
|
1617
|
+
iconColor: '#8E8E93',
|
|
1618
|
+
title: t('editProfile.items.privacySettings.title') || 'Privacy Settings',
|
|
1619
|
+
subtitle: t('editProfile.items.privacySettings.subtitle') || 'Control who can see your profile',
|
|
1620
|
+
onPress: () => navigate?.('PrivacySettings')
|
|
1621
|
+
}, {
|
|
1622
|
+
id: 'verify-account',
|
|
1623
|
+
icon: 'checkmark-circle',
|
|
1624
|
+
iconColor: '#30D158',
|
|
1625
|
+
title: t('editProfile.items.verifyAccount.title') || 'Verify Account',
|
|
1626
|
+
subtitle: t('editProfile.items.verifyAccount.subtitle') || 'Get a verified badge',
|
|
1627
|
+
onPress: () => navigate?.('AccountVerification')
|
|
1628
|
+
}],
|
|
1629
|
+
theme: theme
|
|
1630
|
+
})
|
|
1488
1631
|
})]
|
|
1489
1632
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1490
1633
|
style: styles.section,
|
|
1491
1634
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1492
|
-
style: styles.sectionTitle,
|
|
1493
|
-
|
|
1494
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.GroupedSection, {
|
|
1495
|
-
items: [{
|
|
1496
|
-
id: 'two-factor',
|
|
1497
|
-
icon: 'shield-checkmark',
|
|
1498
|
-
iconColor: '#007AFF',
|
|
1499
|
-
title: t('editProfile.items.twoFactor.title') || 'Two‑Factor Authentication',
|
|
1500
|
-
subtitle: user?.privacySettings?.twoFactorEnabled ? t('editProfile.items.twoFactor.enabled') || 'Enabled' : t('editProfile.items.twoFactor.disabled') || 'Disabled (recommended)',
|
|
1501
|
-
onPress: () => startEditing('twoFactor', '')
|
|
1635
|
+
style: [styles.sectionTitle, {
|
|
1636
|
+
color: themeStyles.isDarkTheme ? '#8E8E93' : '#8E8E93'
|
|
1502
1637
|
}],
|
|
1503
|
-
|
|
1638
|
+
children: t('editProfile.sections.security') || 'SECURITY'
|
|
1639
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1640
|
+
style: styles.groupedSectionWrapper,
|
|
1641
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.GroupedSection, {
|
|
1642
|
+
items: [{
|
|
1643
|
+
id: 'two-factor',
|
|
1644
|
+
icon: 'shield-checkmark',
|
|
1645
|
+
iconColor: '#007AFF',
|
|
1646
|
+
title: t('editProfile.items.twoFactor.title') || 'Two‑Factor Authentication',
|
|
1647
|
+
subtitle: user?.privacySettings?.twoFactorEnabled ? t('editProfile.items.twoFactor.enabled') || 'Enabled' : t('editProfile.items.twoFactor.disabled') || 'Disabled (recommended)',
|
|
1648
|
+
onPress: () => startEditing('twoFactor', '')
|
|
1649
|
+
}],
|
|
1650
|
+
theme: theme
|
|
1651
|
+
})
|
|
1504
1652
|
})]
|
|
1505
1653
|
})]
|
|
1506
1654
|
})
|
|
@@ -1509,27 +1657,35 @@ const AccountSettingsScreen = ({
|
|
|
1509
1657
|
};
|
|
1510
1658
|
const styles = _reactNative.StyleSheet.create({
|
|
1511
1659
|
container: {
|
|
1512
|
-
flex: 1
|
|
1513
|
-
backgroundColor: '#f2f2f2'
|
|
1660
|
+
flex: 1
|
|
1514
1661
|
},
|
|
1515
1662
|
content: {
|
|
1516
1663
|
flex: 1,
|
|
1517
|
-
|
|
1664
|
+
paddingTop: 8,
|
|
1665
|
+
paddingBottom: 24
|
|
1518
1666
|
},
|
|
1519
1667
|
contentEditing: {
|
|
1520
1668
|
flex: 1,
|
|
1521
1669
|
padding: 0
|
|
1522
1670
|
},
|
|
1523
1671
|
section: {
|
|
1524
|
-
marginBottom:
|
|
1672
|
+
marginBottom: 32
|
|
1525
1673
|
},
|
|
1526
1674
|
sectionTitle: {
|
|
1527
|
-
fontSize:
|
|
1675
|
+
fontSize: 13,
|
|
1528
1676
|
fontWeight: '600',
|
|
1529
|
-
color: '#
|
|
1530
|
-
marginBottom:
|
|
1677
|
+
color: '#8E8E93',
|
|
1678
|
+
marginBottom: 8,
|
|
1679
|
+
marginTop: 4,
|
|
1680
|
+
marginHorizontal: 16,
|
|
1681
|
+
textTransform: 'uppercase',
|
|
1682
|
+
letterSpacing: 0.5,
|
|
1531
1683
|
fontFamily: _fonts.fontFamilies.phuduSemiBold
|
|
1532
1684
|
},
|
|
1685
|
+
groupedSectionWrapper: {
|
|
1686
|
+
marginHorizontal: 16,
|
|
1687
|
+
backgroundColor: 'transparent'
|
|
1688
|
+
},
|
|
1533
1689
|
userIcon: {
|
|
1534
1690
|
marginRight: 12
|
|
1535
1691
|
},
|
|
@@ -1566,21 +1722,21 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
1566
1722
|
flex: 1
|
|
1567
1723
|
},
|
|
1568
1724
|
editingFieldLabel: {
|
|
1569
|
-
fontSize:
|
|
1725
|
+
fontSize: 13,
|
|
1570
1726
|
fontWeight: '600',
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1727
|
+
marginBottom: 8,
|
|
1728
|
+
fontFamily: _fonts.fontFamilies.phuduSemiBold,
|
|
1729
|
+
textTransform: 'uppercase',
|
|
1730
|
+
letterSpacing: 0.5
|
|
1574
1731
|
},
|
|
1575
1732
|
editingFieldInput: {
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
borderColor: '#e0e0e0',
|
|
1579
|
-
borderRadius: 12,
|
|
1733
|
+
borderWidth: _reactNative.StyleSheet.hairlineWidth,
|
|
1734
|
+
borderRadius: 14,
|
|
1580
1735
|
padding: 16,
|
|
1581
1736
|
fontSize: 17,
|
|
1582
1737
|
minHeight: 52,
|
|
1583
|
-
fontWeight: '400'
|
|
1738
|
+
fontWeight: '400',
|
|
1739
|
+
letterSpacing: -0.2
|
|
1584
1740
|
},
|
|
1585
1741
|
editingFieldDescription: {
|
|
1586
1742
|
fontSize: 14,
|
|
@@ -1603,22 +1759,20 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
1603
1759
|
fontWeight: '600'
|
|
1604
1760
|
},
|
|
1605
1761
|
editingFieldTextArea: {
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
borderColor: '#e0e0e0',
|
|
1609
|
-
borderRadius: 12,
|
|
1762
|
+
borderWidth: _reactNative.StyleSheet.hairlineWidth,
|
|
1763
|
+
borderRadius: 14,
|
|
1610
1764
|
padding: 16,
|
|
1611
1765
|
fontSize: 17,
|
|
1612
1766
|
minHeight: 120,
|
|
1613
1767
|
textAlignVertical: 'top',
|
|
1614
|
-
fontWeight: '400'
|
|
1768
|
+
fontWeight: '400',
|
|
1769
|
+
letterSpacing: -0.2
|
|
1615
1770
|
},
|
|
1616
1771
|
// Custom editing header styles
|
|
1617
1772
|
editingHeader: {
|
|
1618
1773
|
paddingTop: _reactNative.Platform.OS === 'ios' ? 50 : 16,
|
|
1619
1774
|
paddingBottom: 0,
|
|
1620
|
-
borderBottomWidth:
|
|
1621
|
-
backgroundColor: '#fff'
|
|
1775
|
+
borderBottomWidth: _reactNative.StyleSheet.hairlineWidth
|
|
1622
1776
|
},
|
|
1623
1777
|
editingHeaderContent: {
|
|
1624
1778
|
flexDirection: 'row',
|
|
@@ -1627,10 +1781,9 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
1627
1781
|
minHeight: 44
|
|
1628
1782
|
},
|
|
1629
1783
|
editingBackButton: {
|
|
1630
|
-
width:
|
|
1631
|
-
height:
|
|
1632
|
-
borderRadius:
|
|
1633
|
-
backgroundColor: '#F8F9FA',
|
|
1784
|
+
width: 36,
|
|
1785
|
+
height: 36,
|
|
1786
|
+
borderRadius: 20,
|
|
1634
1787
|
alignItems: 'center',
|
|
1635
1788
|
justifyContent: 'center',
|
|
1636
1789
|
marginRight: 12
|
|
@@ -1658,8 +1811,7 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
1658
1811
|
editingSaveButton: {
|
|
1659
1812
|
paddingHorizontal: 16,
|
|
1660
1813
|
paddingVertical: 8,
|
|
1661
|
-
borderRadius:
|
|
1662
|
-
backgroundColor: '#F8F9FA',
|
|
1814
|
+
borderRadius: 20,
|
|
1663
1815
|
minWidth: 60,
|
|
1664
1816
|
alignItems: 'center',
|
|
1665
1817
|
justifyContent: 'center'
|
|
@@ -1672,20 +1824,24 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
1672
1824
|
editingHeaderBottom: {
|
|
1673
1825
|
flexDirection: 'column',
|
|
1674
1826
|
alignItems: 'flex-start',
|
|
1675
|
-
paddingHorizontal:
|
|
1676
|
-
paddingBottom:
|
|
1677
|
-
paddingTop:
|
|
1678
|
-
},
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1827
|
+
paddingHorizontal: 20,
|
|
1828
|
+
paddingBottom: 20,
|
|
1829
|
+
paddingTop: 24
|
|
1830
|
+
},
|
|
1831
|
+
editingIconContainer: {
|
|
1832
|
+
width: 64,
|
|
1833
|
+
height: 64,
|
|
1834
|
+
borderRadius: 20,
|
|
1835
|
+
alignItems: 'center',
|
|
1836
|
+
justifyContent: 'center',
|
|
1837
|
+
marginBottom: 16
|
|
1682
1838
|
},
|
|
1683
1839
|
editingBottomTitle: {
|
|
1684
|
-
fontSize:
|
|
1840
|
+
fontSize: 28,
|
|
1685
1841
|
fontWeight: '700',
|
|
1686
1842
|
fontFamily: _fonts.fontFamilies.phuduBold,
|
|
1687
1843
|
letterSpacing: -0.5,
|
|
1688
|
-
lineHeight:
|
|
1844
|
+
lineHeight: 34,
|
|
1689
1845
|
textAlign: 'left',
|
|
1690
1846
|
alignSelf: 'flex-start'
|
|
1691
1847
|
},
|