@oxyhq/services 5.3.5 → 5.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/lib/commonjs/core/index.js +12 -1
  2. package/lib/commonjs/core/index.js.map +1 -1
  3. package/lib/commonjs/ui/context/OxyContext.js +17 -2
  4. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  5. package/lib/commonjs/ui/navigation/OxyRouter.js +0 -5
  6. package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -1
  7. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +479 -313
  8. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
  9. package/lib/module/core/index.js +12 -1
  10. package/lib/module/core/index.js.map +1 -1
  11. package/lib/module/ui/context/OxyContext.js +17 -2
  12. package/lib/module/ui/context/OxyContext.js.map +1 -1
  13. package/lib/module/ui/navigation/OxyRouter.js +0 -5
  14. package/lib/module/ui/navigation/OxyRouter.js.map +1 -1
  15. package/lib/module/ui/screens/AccountSwitcherScreen.js +480 -314
  16. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
  17. package/lib/typescript/core/index.d.ts.map +1 -1
  18. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  19. package/lib/typescript/ui/navigation/OxyRouter.d.ts.map +1 -1
  20. package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts +2 -2
  21. package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
  22. package/package.json +1 -1
  23. package/src/core/index.ts +13 -1
  24. package/src/ui/context/OxyContext.tsx +19 -2
  25. package/src/ui/navigation/OxyRouter.tsx +0 -5
  26. package/src/ui/screens/AccountSwitcherScreen.tsx +502 -304
  27. package/lib/commonjs/ui/screens/ModernAccountSwitcherScreen.js +0 -532
  28. package/lib/commonjs/ui/screens/ModernAccountSwitcherScreen.js.map +0 -1
  29. package/lib/module/ui/screens/ModernAccountSwitcherScreen.js +0 -527
  30. package/lib/module/ui/screens/ModernAccountSwitcherScreen.js.map +0 -1
  31. package/lib/typescript/ui/screens/ModernAccountSwitcherScreen.d.ts +0 -5
  32. package/lib/typescript/ui/screens/ModernAccountSwitcherScreen.d.ts.map +0 -1
  33. package/src/ui/screens/ModernAccountSwitcherScreen.tsx +0 -552
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
 
3
3
  import React, { useState, useEffect } from 'react';
4
- import { View, Text, TouchableOpacity, StyleSheet, ActivityIndicator, ScrollView, Alert, Platform, Dimensions } from 'react-native';
4
+ import { View, Text, TouchableOpacity, StyleSheet, ActivityIndicator, ScrollView, Alert, Image, Dimensions } from 'react-native';
5
5
  import { useOxy } from '../context/OxyContext';
6
6
  import { fontFamilies } from '../styles/fonts';
7
7
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
8
- const AccountSwitcherScreen = ({
8
+ const ModernAccountSwitcherScreen = ({
9
9
  onClose,
10
10
  theme,
11
11
  navigate,
@@ -21,11 +21,16 @@ const AccountSwitcherScreen = ({
21
21
  logoutAll,
22
22
  isLoading
23
23
  } = useOxy();
24
- const [allDeviceSessions, setAllDeviceSessions] = useState([]);
25
- const [loadingDeviceSessions, setLoadingDeviceSessions] = useState(false);
24
+ const [sessionsWithUsers, setSessionsWithUsers] = useState([]);
26
25
  const [switchingToUserId, setSwitchingToUserId] = useState(null);
27
26
  const [removingUserId, setRemovingUserId] = useState(null);
28
- const [showRemoteDevices, setShowRemoteDevices] = useState(false);
27
+
28
+ // Device session management state
29
+ const [showDeviceManagement, setShowDeviceManagement] = useState(false);
30
+ const [deviceSessions, setDeviceSessions] = useState([]);
31
+ const [loadingDeviceSessions, setLoadingDeviceSessions] = useState(false);
32
+ const [remotingLogoutSessionId, setRemoteLogoutSessionId] = useState(null);
33
+ const [loggingOutAllDevices, setLoggingOutAllDevices] = useState(false);
29
34
  const screenWidth = Dimensions.get('window').width;
30
35
  const isDarkTheme = theme === 'dark';
31
36
 
@@ -44,36 +49,38 @@ const AccountSwitcherScreen = ({
44
49
  shadow: isDarkTheme ? 'rgba(0,0,0,0.3)' : 'rgba(0,0,0,0.1)'
45
50
  };
46
51
 
47
- // Load all device sessions for remote management
48
- const loadAllDeviceSessions = async () => {
49
- if (!activeSessionId || !oxyServices) return;
50
- setLoadingDeviceSessions(true);
51
- try {
52
- const allSessions = await oxyServices.getSessionsBySessionId(activeSessionId);
53
- const deviceSessions = allSessions.map(session => ({
54
- sessionId: session.sessionId,
55
- deviceId: session.deviceId,
56
- deviceName: session.deviceName || 'Unknown Device',
57
- isActive: session.isActive,
58
- lastActive: session.lastActive || new Date().toISOString(),
59
- expiresAt: session.expiresAt || new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
60
- isCurrent: session.sessionId === activeSessionId
52
+ // Load user profiles for sessions
53
+ useEffect(() => {
54
+ const loadUserProfiles = async () => {
55
+ if (!sessions.length || !oxyServices) return;
56
+ const updatedSessions = sessions.map(session => ({
57
+ ...session,
58
+ isLoadingProfile: true
61
59
  }));
62
- setAllDeviceSessions(deviceSessions);
63
- } catch (error) {
64
- console.error('Failed to load device sessions:', error);
65
- Alert.alert('Error', 'Failed to load device sessions');
66
- } finally {
67
- setLoadingDeviceSessions(false);
68
- }
69
- };
60
+ setSessionsWithUsers(updatedSessions);
70
61
 
71
- // Load device sessions when showing remote devices
72
- useEffect(() => {
73
- if (showRemoteDevices) {
74
- loadAllDeviceSessions();
75
- }
76
- }, [showRemoteDevices, activeSessionId, oxyServices]);
62
+ // Load profiles for each session
63
+ for (let i = 0; i < sessions.length; i++) {
64
+ const session = sessions[i];
65
+ try {
66
+ // Try to get user profile using the session
67
+ const userProfile = await oxyServices.getUserBySession(session.sessionId);
68
+ setSessionsWithUsers(prev => prev.map(s => s.sessionId === session.sessionId ? {
69
+ ...s,
70
+ userProfile,
71
+ isLoadingProfile: false
72
+ } : s));
73
+ } catch (error) {
74
+ console.error(`Failed to load profile for session ${session.sessionId}:`, error);
75
+ setSessionsWithUsers(prev => prev.map(s => s.sessionId === session.sessionId ? {
76
+ ...s,
77
+ isLoadingProfile: false
78
+ } : s));
79
+ }
80
+ }
81
+ };
82
+ loadUserProfiles();
83
+ }, [sessions, oxyServices]);
77
84
  const handleSwitchSession = async sessionId => {
78
85
  if (sessionId === user?.sessionId) return; // Already active session
79
86
 
@@ -92,9 +99,10 @@ const AccountSwitcherScreen = ({
92
99
  }
93
100
  };
94
101
  const handleRemoveSession = async sessionId => {
95
- const sessionToRemove = sessions.find(s => s.sessionId === sessionId);
102
+ const sessionToRemove = sessionsWithUsers.find(s => s.sessionId === sessionId);
96
103
  if (!sessionToRemove) return;
97
- Alert.alert('Remove Account', `Are you sure you want to remove this session from this device? You'll need to sign in again to access this account.`, [{
104
+ const displayName = typeof sessionToRemove.userProfile?.name === 'object' ? sessionToRemove.userProfile.name.full || sessionToRemove.userProfile.name.first || sessionToRemove.userProfile.username : sessionToRemove.userProfile?.name || sessionToRemove.userProfile?.username || 'this account';
105
+ Alert.alert('Remove Account', `Are you sure you want to remove ${displayName} from this device? You'll need to sign in again to access this account.`, [{
98
106
  text: 'Cancel',
99
107
  style: 'cancel'
100
108
  }, {
@@ -117,6 +125,9 @@ const AccountSwitcherScreen = ({
117
125
  });
118
126
  };
119
127
  const handleLogoutAll = async () => {
128
+ console.log('handleLogoutAll called, current user:', user);
129
+ console.log('activeSessionId:', activeSessionId);
130
+ console.log('sessions count:', sessions.length);
120
131
  Alert.alert('Sign Out All', 'Are you sure you want to sign out of all accounts on this device?', [{
121
132
  text: 'Cancel',
122
133
  style: 'cancel'
@@ -124,37 +135,60 @@ const AccountSwitcherScreen = ({
124
135
  text: 'Sign Out All',
125
136
  style: 'destructive',
126
137
  onPress: async () => {
138
+ console.log('User confirmed logout all');
127
139
  try {
140
+ console.log('About to call logoutAll()');
128
141
  await logoutAll();
142
+ console.log('logoutAll() completed successfully');
129
143
  Alert.alert('Success', 'All accounts signed out successfully!');
130
144
  if (onClose) {
131
145
  onClose();
132
146
  }
133
147
  } catch (error) {
134
148
  console.error('Logout all failed:', error);
135
- Alert.alert('Logout Failed', 'There was a problem signing out. Please try again.');
149
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
150
+ Alert.alert('Logout Failed', `There was a problem signing out: ${errorMessage}`);
136
151
  }
137
152
  }
138
153
  }], {
139
154
  cancelable: true
140
155
  });
141
156
  };
157
+
158
+ // Device session management functions
159
+ const loadAllDeviceSessions = async () => {
160
+ if (!oxyServices || !user?.sessionId) return;
161
+ setLoadingDeviceSessions(true);
162
+ try {
163
+ // This would call the API to get all device sessions for the current user
164
+ const allSessions = await oxyServices.getDeviceSessions(user.sessionId);
165
+ setDeviceSessions(allSessions || []);
166
+ } catch (error) {
167
+ console.error('Failed to load device sessions:', error);
168
+ Alert.alert('Error', 'Failed to load device sessions. Please try again.');
169
+ } finally {
170
+ setLoadingDeviceSessions(false);
171
+ }
172
+ };
142
173
  const handleRemoteSessionLogout = async (sessionId, deviceName) => {
143
- Alert.alert('Logout Remote Session', `Are you sure you want to logout from "${deviceName}"?`, [{
174
+ Alert.alert('Remove Device Session', `Are you sure you want to sign out from "${deviceName}"? This will end the session on that device.`, [{
144
175
  text: 'Cancel',
145
176
  style: 'cancel'
146
177
  }, {
147
- text: 'Logout',
178
+ text: 'Sign Out',
148
179
  style: 'destructive',
149
180
  onPress: async () => {
181
+ setRemoteLogoutSessionId(sessionId);
150
182
  try {
151
- await oxyServices.logoutSecureSession(activeSessionId, sessionId);
152
- Alert.alert('Success', 'Remote session logged out successfully!');
153
- // Refresh the device sessions list
183
+ await oxyServices?.logoutSecureSession(user?.sessionId || '', sessionId);
184
+ // Refresh device sessions list
154
185
  await loadAllDeviceSessions();
186
+ Alert.alert('Success', `Signed out from ${deviceName} successfully!`);
155
187
  } catch (error) {
156
188
  console.error('Remote logout failed:', error);
157
- Alert.alert('Logout Failed', 'There was a problem logging out the remote session. Please try again.');
189
+ Alert.alert('Logout Failed', 'There was a problem signing out from the device. Please try again.');
190
+ } finally {
191
+ setRemoteLogoutSessionId(null);
158
192
  }
159
193
  }
160
194
  }], {
@@ -162,64 +196,182 @@ const AccountSwitcherScreen = ({
162
196
  });
163
197
  };
164
198
  const handleLogoutAllDevices = async () => {
165
- Alert.alert('Logout All Devices', 'Are you sure you want to logout from all other devices? This will keep your current session active.', [{
199
+ const otherDevicesCount = deviceSessions.filter(session => !session.isCurrent).length;
200
+ if (otherDevicesCount === 0) {
201
+ Alert.alert('No Other Devices', 'No other device sessions found to sign out from.');
202
+ return;
203
+ }
204
+ Alert.alert('Sign Out All Other Devices', `Are you sure you want to sign out from all ${otherDevicesCount} other device(s)? This will end sessions on all other devices except this one.`, [{
166
205
  text: 'Cancel',
167
206
  style: 'cancel'
168
207
  }, {
169
- text: 'Logout All Others',
208
+ text: 'Sign Out All',
170
209
  style: 'destructive',
171
210
  onPress: async () => {
211
+ setLoggingOutAllDevices(true);
172
212
  try {
173
- await oxyServices.logoutAllDeviceSessions(activeSessionId, undefined, true);
174
- Alert.alert('Success', 'All other device sessions logged out successfully!');
175
- // Refresh the device sessions list
213
+ await oxyServices?.logoutAllDeviceSessions(user?.sessionId || '', undefined, true);
214
+ // Refresh device sessions list
176
215
  await loadAllDeviceSessions();
216
+ Alert.alert('Success', `Signed out from all other devices successfully!`);
177
217
  } catch (error) {
178
218
  console.error('Logout all devices failed:', error);
179
- Alert.alert('Logout Failed', 'There was a problem logging out other devices. Please try again.');
219
+ Alert.alert('Logout Failed', 'There was a problem signing out from other devices. Please try again.');
220
+ } finally {
221
+ setLoggingOutAllDevices(false);
180
222
  }
181
223
  }
182
224
  }], {
183
225
  cancelable: true
184
226
  });
185
227
  };
186
- const renderSessionItem = session => {
187
- const isActive = session.sessionId === activeSessionId;
188
- const isSwitching = switchingToUserId === session.sessionId;
189
- const isRemoving = removingUserId === session.sessionId;
190
- return /*#__PURE__*/_jsxs(View, {
191
- style: [styles.userItem, {
192
- backgroundColor: isActive ? colors.activeCard : colors.surface,
193
- borderColor: isActive ? colors.accent : colors.border
228
+ const renderDeviceSessionItem = deviceSession => {
229
+ const isLoggingOut = remotingLogoutSessionId === deviceSession.sessionId;
230
+ return /*#__PURE__*/_jsx(View, {
231
+ style: [styles.sessionCard, {
232
+ backgroundColor: deviceSession.isCurrent ? colors.activeCard : colors.card,
233
+ borderColor: deviceSession.isCurrent ? colors.accent : colors.border,
234
+ borderWidth: deviceSession.isCurrent ? 2 : 1
194
235
  }],
195
- children: [/*#__PURE__*/_jsxs(View, {
196
- style: styles.userInfo,
197
- children: [/*#__PURE__*/_jsx(Text, {
198
- style: [styles.username, {
199
- color: colors.text
200
- }],
201
- children: isActive ? user?.username || 'Current Account' : 'Account Session'
202
- }), /*#__PURE__*/_jsxs(Text, {
203
- style: [styles.email, {
204
- color: isDarkTheme ? '#BBBBBB' : '#666666'
205
- }],
206
- children: ["Last active: ", new Date(session.lastActive).toLocaleDateString()]
207
- }), isActive && /*#__PURE__*/_jsx(View, {
208
- style: [styles.activeBadge, {
209
- backgroundColor: colors.success
236
+ children: /*#__PURE__*/_jsxs(View, {
237
+ style: styles.sessionHeader,
238
+ children: [/*#__PURE__*/_jsxs(View, {
239
+ style: styles.userInfo,
240
+ children: [/*#__PURE__*/_jsxs(Text, {
241
+ style: [styles.displayName, {
242
+ color: colors.text
243
+ }],
244
+ numberOfLines: 1,
245
+ children: [deviceSession.deviceName, deviceSession.isCurrent && /*#__PURE__*/_jsx(Text, {
246
+ style: [styles.username, {
247
+ color: colors.accent
248
+ }],
249
+ children: ' (This Device)'
250
+ })]
251
+ }), /*#__PURE__*/_jsxs(Text, {
252
+ style: [styles.username, {
253
+ color: colors.secondaryText
254
+ }],
255
+ numberOfLines: 1,
256
+ children: ["ID: ...", deviceSession.deviceId.slice(-8)]
257
+ }), /*#__PURE__*/_jsxs(Text, {
258
+ style: [styles.lastActive, {
259
+ color: colors.secondaryText
260
+ }],
261
+ numberOfLines: 1,
262
+ children: ["Last active: ", new Date(deviceSession.lastActive).toLocaleDateString()]
263
+ })]
264
+ }), !deviceSession.isCurrent && /*#__PURE__*/_jsx(TouchableOpacity, {
265
+ style: [styles.removeButton, {
266
+ borderColor: colors.destructive,
267
+ backgroundColor: colors.background
210
268
  }],
211
- children: /*#__PURE__*/_jsx(Text, {
212
- style: styles.activeBadgeText,
213
- children: "Active"
269
+ onPress: () => handleRemoteSessionLogout(deviceSession.sessionId, deviceSession.deviceName),
270
+ disabled: isLoggingOut,
271
+ children: isLoggingOut ? /*#__PURE__*/_jsx(ActivityIndicator, {
272
+ color: colors.destructive,
273
+ size: "small"
274
+ }) : /*#__PURE__*/_jsx(Text, {
275
+ style: [styles.removeButtonText, {
276
+ color: colors.destructive
277
+ }],
278
+ children: "Sign Out"
214
279
  })
215
280
  })]
281
+ })
282
+ }, deviceSession.sessionId);
283
+ };
284
+
285
+ // Load device sessions when device management is shown
286
+ useEffect(() => {
287
+ if (showDeviceManagement && deviceSessions.length === 0) {
288
+ loadAllDeviceSessions();
289
+ }
290
+ }, [showDeviceManagement]);
291
+ const renderSessionItem = sessionWithUser => {
292
+ const isActive = sessionWithUser.sessionId === activeSessionId;
293
+ const isSwitching = switchingToUserId === sessionWithUser.sessionId;
294
+ const isRemoving = removingUserId === sessionWithUser.sessionId;
295
+ const {
296
+ userProfile,
297
+ isLoadingProfile
298
+ } = sessionWithUser;
299
+ const displayName = typeof userProfile?.name === 'object' ? userProfile.name.full || userProfile.name.first || userProfile.username : userProfile?.name || userProfile?.username || 'Unknown User';
300
+ const username = userProfile?.username || 'unknown';
301
+ const avatarUrl = userProfile?.avatar?.url;
302
+ return /*#__PURE__*/_jsxs(View, {
303
+ style: [styles.sessionCard, {
304
+ backgroundColor: isActive ? colors.activeCard : colors.card,
305
+ borderColor: isActive ? colors.accent : colors.border,
306
+ borderWidth: isActive ? 2 : 1,
307
+ shadowColor: colors.shadow
308
+ }],
309
+ children: [/*#__PURE__*/_jsxs(View, {
310
+ style: styles.sessionHeader,
311
+ children: [/*#__PURE__*/_jsxs(View, {
312
+ style: styles.avatarContainer,
313
+ children: [isLoadingProfile ? /*#__PURE__*/_jsx(View, {
314
+ style: [styles.avatarPlaceholder, {
315
+ backgroundColor: colors.surface
316
+ }],
317
+ children: /*#__PURE__*/_jsx(ActivityIndicator, {
318
+ size: "small",
319
+ color: colors.accent
320
+ })
321
+ }) : avatarUrl ? /*#__PURE__*/_jsx(Image, {
322
+ source: {
323
+ uri: avatarUrl
324
+ },
325
+ style: styles.avatar
326
+ }) : /*#__PURE__*/_jsx(View, {
327
+ style: [styles.avatarPlaceholder, {
328
+ backgroundColor: colors.surface
329
+ }],
330
+ children: /*#__PURE__*/_jsx(Text, {
331
+ style: [styles.avatarText, {
332
+ color: colors.accent
333
+ }],
334
+ children: displayName.charAt(0).toUpperCase()
335
+ })
336
+ }), isActive && /*#__PURE__*/_jsx(View, {
337
+ style: [styles.activeBadge, {
338
+ backgroundColor: colors.success
339
+ }],
340
+ children: /*#__PURE__*/_jsx(Text, {
341
+ style: styles.activeBadgeText,
342
+ children: "\u2713"
343
+ })
344
+ })]
345
+ }), /*#__PURE__*/_jsxs(View, {
346
+ style: styles.userInfo,
347
+ children: [/*#__PURE__*/_jsx(Text, {
348
+ style: [styles.displayName, {
349
+ color: colors.text
350
+ }],
351
+ numberOfLines: 1,
352
+ children: displayName
353
+ }), /*#__PURE__*/_jsxs(Text, {
354
+ style: [styles.username, {
355
+ color: colors.secondaryText
356
+ }],
357
+ numberOfLines: 1,
358
+ children: ["@", username]
359
+ }), /*#__PURE__*/_jsxs(Text, {
360
+ style: [styles.lastActive, {
361
+ color: colors.secondaryText
362
+ }],
363
+ numberOfLines: 1,
364
+ children: ["Last active: ", new Date(sessionWithUser.lastActive).toLocaleDateString()]
365
+ })]
366
+ })]
216
367
  }), /*#__PURE__*/_jsxs(View, {
217
- style: styles.userActions,
368
+ style: styles.sessionActions,
218
369
  children: [!isActive && /*#__PURE__*/_jsx(TouchableOpacity, {
219
370
  style: [styles.switchButton, {
220
- borderColor: colors.accent
371
+ borderColor: colors.accent,
372
+ backgroundColor: colors.background
221
373
  }],
222
- onPress: () => handleSwitchSession(session.sessionId),
374
+ onPress: () => handleSwitchSession(sessionWithUser.sessionId),
223
375
  disabled: isSwitching || isRemoving,
224
376
  children: isSwitching ? /*#__PURE__*/_jsx(ActivityIndicator, {
225
377
  color: colors.accent,
@@ -232,10 +384,11 @@ const AccountSwitcherScreen = ({
232
384
  })
233
385
  }), /*#__PURE__*/_jsx(TouchableOpacity, {
234
386
  style: [styles.removeButton, {
235
- borderColor: colors.destructive
387
+ borderColor: colors.destructive,
388
+ backgroundColor: colors.background
236
389
  }],
237
- onPress: () => handleRemoveSession(session.sessionId),
238
- disabled: isSwitching || isRemoving || sessions.length === 1,
390
+ onPress: () => handleRemoveSession(sessionWithUser.sessionId),
391
+ disabled: isSwitching || isRemoving,
239
392
  children: isRemoving ? /*#__PURE__*/_jsx(ActivityIndicator, {
240
393
  color: colors.destructive,
241
394
  size: "small"
@@ -247,57 +400,7 @@ const AccountSwitcherScreen = ({
247
400
  })
248
401
  })]
249
402
  })]
250
- }, session.sessionId);
251
- };
252
- const renderDeviceSessionItem = deviceSession => {
253
- const isCurrentSession = deviceSession.isCurrent;
254
- return /*#__PURE__*/_jsxs(View, {
255
- style: [styles.userItem, {
256
- backgroundColor: isCurrentSession ? colors.activeCard : colors.surface,
257
- borderColor: isCurrentSession ? colors.accent : colors.border
258
- }],
259
- children: [/*#__PURE__*/_jsxs(View, {
260
- style: styles.userInfo,
261
- children: [/*#__PURE__*/_jsxs(Text, {
262
- style: [styles.username, {
263
- color: colors.text
264
- }],
265
- children: [deviceSession.deviceName, isCurrentSession && ' (This Device)']
266
- }), /*#__PURE__*/_jsxs(Text, {
267
- style: [styles.email, {
268
- color: isDarkTheme ? '#BBBBBB' : '#666666'
269
- }],
270
- children: ["Last active: ", new Date(deviceSession.lastActive).toLocaleDateString()]
271
- }), /*#__PURE__*/_jsxs(Text, {
272
- style: [styles.email, {
273
- color: isDarkTheme ? '#BBBBBB' : '#666666'
274
- }],
275
- children: ["Device ID: ", deviceSession.deviceId.substring(0, 8), "..."]
276
- }), isCurrentSession && /*#__PURE__*/_jsx(View, {
277
- style: [styles.activeBadge, {
278
- backgroundColor: colors.success
279
- }],
280
- children: /*#__PURE__*/_jsx(Text, {
281
- style: styles.activeBadgeText,
282
- children: "Current"
283
- })
284
- })]
285
- }), /*#__PURE__*/_jsx(View, {
286
- style: styles.userActions,
287
- children: !isCurrentSession && /*#__PURE__*/_jsx(TouchableOpacity, {
288
- style: [styles.removeButton, {
289
- borderColor: colors.destructive
290
- }],
291
- onPress: () => handleRemoteSessionLogout(deviceSession.sessionId, deviceSession.deviceName),
292
- children: /*#__PURE__*/_jsx(Text, {
293
- style: [styles.removeButtonText, {
294
- color: colors.destructive
295
- }],
296
- children: "Logout"
297
- })
298
- })
299
- })]
300
- }, deviceSession.sessionId);
403
+ }, sessionWithUser.sessionId);
301
404
  };
302
405
  return /*#__PURE__*/_jsxs(View, {
303
406
  style: [styles.container, {
@@ -318,115 +421,159 @@ const AccountSwitcherScreen = ({
318
421
  style: [styles.title, {
319
422
  color: colors.text
320
423
  }],
321
- children: "Account Switcher"
424
+ children: "Accounts"
322
425
  }), /*#__PURE__*/_jsx(View, {
323
- style: styles.placeholder
426
+ style: styles.headerSpacer
324
427
  })]
325
- }), /*#__PURE__*/_jsxs(ScrollView, {
326
- style: styles.scrollView,
327
- contentContainerStyle: styles.scrollContainer,
328
- children: [/*#__PURE__*/_jsx(View, {
329
- style: styles.description,
330
- children: /*#__PURE__*/_jsx(Text, {
331
- style: [styles.descriptionText, {
332
- color: isDarkTheme ? '#BBBBBB' : '#666666'
428
+ }), /*#__PURE__*/_jsx(ScrollView, {
429
+ style: styles.content,
430
+ showsVerticalScrollIndicator: false,
431
+ contentContainerStyle: styles.scrollContent,
432
+ children: isLoading ? /*#__PURE__*/_jsxs(View, {
433
+ style: styles.loadingContainer,
434
+ children: [/*#__PURE__*/_jsx(ActivityIndicator, {
435
+ size: "large",
436
+ color: colors.accent
437
+ }), /*#__PURE__*/_jsx(Text, {
438
+ style: [styles.loadingText, {
439
+ color: colors.secondaryText
333
440
  }],
334
- children: "Manage multiple accounts on this device. Switch between accounts or remove them from this device."
335
- })
336
- }), /*#__PURE__*/_jsxs(View, {
337
- style: styles.usersContainer,
441
+ children: "Loading accounts..."
442
+ })]
443
+ }) : /*#__PURE__*/_jsxs(_Fragment, {
338
444
  children: [/*#__PURE__*/_jsxs(Text, {
339
445
  style: [styles.sectionTitle, {
340
446
  color: colors.text
341
447
  }],
342
- children: ["Local Sessions (", sessions.length, ")"]
343
- }), sessions.map(renderSessionItem)]
344
- }), /*#__PURE__*/_jsxs(View, {
345
- style: styles.usersContainer,
346
- children: [/*#__PURE__*/_jsxs(View, {
347
- style: styles.sectionHeader,
348
- children: [/*#__PURE__*/_jsx(Text, {
349
- style: [styles.sectionTitle, {
350
- color: colors.text
448
+ children: ["Saved Accounts (", sessionsWithUsers.length, ")"]
449
+ }), sessionsWithUsers.length === 0 ? /*#__PURE__*/_jsx(View, {
450
+ style: styles.emptyState,
451
+ children: /*#__PURE__*/_jsx(Text, {
452
+ style: [styles.emptyText, {
453
+ color: colors.secondaryText
351
454
  }],
352
- children: "All Devices & Sessions"
353
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
354
- style: [styles.toggleButton, {
355
- borderColor: colors.accent
455
+ children: "No saved accounts found"
456
+ })
457
+ }) : sessionsWithUsers.map(renderSessionItem), /*#__PURE__*/_jsxs(View, {
458
+ style: styles.actionsSection,
459
+ children: [/*#__PURE__*/_jsx(TouchableOpacity, {
460
+ style: [styles.actionButton, {
461
+ borderColor: colors.border,
462
+ backgroundColor: colors.card
356
463
  }],
357
- onPress: () => setShowRemoteDevices(!showRemoteDevices),
464
+ onPress: () => navigate?.('SignIn'),
358
465
  children: /*#__PURE__*/_jsx(Text, {
359
- style: [styles.toggleButtonText, {
360
- color: colors.accent
466
+ style: [styles.actionButtonText, {
467
+ color: colors.text
468
+ }],
469
+ children: "+ Add Another Account"
470
+ })
471
+ }), sessionsWithUsers.length > 0 && /*#__PURE__*/_jsx(TouchableOpacity, {
472
+ style: [styles.actionButton, styles.dangerButton, {
473
+ borderColor: colors.destructive,
474
+ backgroundColor: colors.background
475
+ }],
476
+ onPress: handleLogoutAll,
477
+ children: /*#__PURE__*/_jsx(Text, {
478
+ style: [styles.dangerButtonText, {
479
+ color: colors.destructive
361
480
  }],
362
- children: showRemoteDevices ? 'Hide' : 'Show'
481
+ children: "Sign Out All Accounts"
363
482
  })
364
483
  })]
365
- }), showRemoteDevices && /*#__PURE__*/_jsx(_Fragment, {
366
- children: loadingDeviceSessions ? /*#__PURE__*/_jsxs(View, {
484
+ }), /*#__PURE__*/_jsx(View, {
485
+ style: styles.actionsSection,
486
+ children: /*#__PURE__*/_jsx(TouchableOpacity, {
487
+ style: [styles.actionButton, {
488
+ borderColor: colors.border,
489
+ backgroundColor: colors.card
490
+ }],
491
+ onPress: () => setShowDeviceManagement(!showDeviceManagement),
492
+ children: /*#__PURE__*/_jsx(Text, {
493
+ style: [styles.actionButtonText, {
494
+ color: colors.text
495
+ }],
496
+ children: showDeviceManagement ? '− Hide Device Management' : '+ Manage Device Sessions'
497
+ })
498
+ })
499
+ }), showDeviceManagement && /*#__PURE__*/_jsxs(View, {
500
+ style: [styles.deviceManagementSection, {
501
+ backgroundColor: colors.card,
502
+ borderColor: colors.border
503
+ }],
504
+ children: [/*#__PURE__*/_jsx(Text, {
505
+ style: [styles.sectionTitle, {
506
+ color: colors.text
507
+ }],
508
+ children: "Device Sessions"
509
+ }), loadingDeviceSessions ? /*#__PURE__*/_jsxs(View, {
367
510
  style: styles.loadingContainer,
368
511
  children: [/*#__PURE__*/_jsx(ActivityIndicator, {
369
- color: colors.accent,
370
- size: "small"
512
+ size: "large",
513
+ color: colors.accent
371
514
  }), /*#__PURE__*/_jsx(Text, {
372
515
  style: [styles.loadingText, {
373
516
  color: colors.secondaryText
374
517
  }],
375
518
  children: "Loading device sessions..."
376
519
  })]
377
- }) : /*#__PURE__*/_jsx(_Fragment, {
378
- children: allDeviceSessions.length > 0 ? /*#__PURE__*/_jsxs(_Fragment, {
379
- children: [allDeviceSessions.map(renderDeviceSessionItem), allDeviceSessions.filter(s => !s.isCurrent).length > 0 && /*#__PURE__*/_jsx(TouchableOpacity, {
380
- style: [styles.actionButton, {
381
- borderColor: colors.destructive,
382
- marginTop: 12
383
- }],
384
- onPress: handleLogoutAllDevices,
385
- children: /*#__PURE__*/_jsx(Text, {
386
- style: [styles.actionButtonText, {
387
- color: colors.destructive
388
- }],
389
- children: "Logout All Other Devices"
390
- })
391
- })]
392
- }) : /*#__PURE__*/_jsx(Text, {
520
+ }) : deviceSessions.length === 0 ? /*#__PURE__*/_jsx(View, {
521
+ style: styles.emptyState,
522
+ children: /*#__PURE__*/_jsx(Text, {
393
523
  style: [styles.emptyText, {
394
524
  color: colors.secondaryText
395
525
  }],
396
- children: "No other device sessions found"
526
+ children: "No device sessions found"
397
527
  })
398
- })
399
- })]
400
- }), /*#__PURE__*/_jsxs(View, {
401
- style: styles.actionsContainer,
402
- children: [/*#__PURE__*/_jsx(TouchableOpacity, {
403
- style: [styles.actionButton, {
404
- borderColor: colors.border
405
- }],
406
- onPress: () => navigate('SignIn'),
407
- children: /*#__PURE__*/_jsx(Text, {
408
- style: [styles.actionButtonText, {
409
- color: colors.text
528
+ }) : /*#__PURE__*/_jsxs(_Fragment, {
529
+ children: [deviceSessions.map(renderDeviceSessionItem), deviceSessions.filter(session => !session.isCurrent).length > 0 && /*#__PURE__*/_jsx(TouchableOpacity, {
530
+ style: [styles.actionButton, styles.dangerButton, {
531
+ borderColor: colors.destructive,
532
+ backgroundColor: colors.background,
533
+ marginTop: 20
534
+ }],
535
+ onPress: handleLogoutAllDevices,
536
+ disabled: loggingOutAllDevices,
537
+ children: loggingOutAllDevices ? /*#__PURE__*/_jsx(ActivityIndicator, {
538
+ color: colors.destructive,
539
+ size: "small"
540
+ }) : /*#__PURE__*/_jsx(Text, {
541
+ style: [styles.dangerButtonText, {
542
+ color: colors.destructive
543
+ }],
544
+ children: "Sign Out All Other Devices"
545
+ })
546
+ })]
547
+ })]
548
+ }), /*#__PURE__*/_jsxs(View, {
549
+ style: styles.actionsSection,
550
+ children: [/*#__PURE__*/_jsx(TouchableOpacity, {
551
+ style: [styles.actionButton, {
552
+ borderColor: colors.border,
553
+ backgroundColor: colors.card
410
554
  }],
411
- children: "Add Another Account"
412
- })
413
- }), sessions.length > 1 && /*#__PURE__*/_jsx(TouchableOpacity, {
414
- style: [styles.dangerButton, {
415
- backgroundColor: isDarkTheme ? '#300000' : '#FFEBEE'
416
- }],
417
- onPress: handleLogoutAll,
418
- disabled: isLoading,
419
- children: isLoading ? /*#__PURE__*/_jsx(ActivityIndicator, {
420
- color: colors.destructive,
421
- size: "small"
422
- }) : /*#__PURE__*/_jsx(Text, {
423
- style: [styles.dangerButtonText, {
424
- color: colors.destructive
555
+ onPress: () => navigate?.('SignIn'),
556
+ children: /*#__PURE__*/_jsx(Text, {
557
+ style: [styles.actionButtonText, {
558
+ color: colors.text
559
+ }],
560
+ children: "+ Add Another Account"
561
+ })
562
+ }), sessionsWithUsers.length > 0 && /*#__PURE__*/_jsx(TouchableOpacity, {
563
+ style: [styles.actionButton, styles.dangerButton, {
564
+ borderColor: colors.destructive,
565
+ backgroundColor: colors.background
425
566
  }],
426
- children: "Sign Out All Sessions"
427
- })
567
+ onPress: handleLogoutAll,
568
+ children: /*#__PURE__*/_jsx(Text, {
569
+ style: [styles.dangerButtonText, {
570
+ color: colors.destructive
571
+ }],
572
+ children: "Sign Out All Accounts"
573
+ })
574
+ })]
428
575
  })]
429
- })]
576
+ })
430
577
  })]
431
578
  });
432
579
  };
@@ -439,168 +586,187 @@ const styles = StyleSheet.create({
439
586
  alignItems: 'center',
440
587
  justifyContent: 'space-between',
441
588
  paddingHorizontal: 20,
442
- paddingTop: Platform.OS === 'ios' ? 50 : 20,
443
- paddingBottom: 20,
444
- borderBottomWidth: 1,
445
- borderBottomColor: 'rgba(0, 0, 0, 0.1)'
589
+ paddingTop: 20,
590
+ paddingBottom: 10
446
591
  },
447
592
  backButton: {
448
- paddingVertical: 8,
449
- paddingHorizontal: 4
593
+ padding: 8
450
594
  },
451
595
  backButtonText: {
452
596
  fontSize: 18,
453
- fontFamily: fontFamilies.phudu
597
+ fontFamily: fontFamilies.phuduMedium
454
598
  },
455
599
  title: {
456
- fontSize: 20,
457
- fontFamily: fontFamilies.phuduSemiBold,
600
+ fontSize: 24,
601
+ fontFamily: fontFamilies.phuduBold,
458
602
  textAlign: 'center'
459
603
  },
460
- placeholder: {
461
- width: 60 // Same as back button to center title
604
+ headerSpacer: {
605
+ width: 40
462
606
  },
463
- scrollView: {
464
- flex: 1
465
- },
466
- scrollContainer: {
467
- padding: 20
607
+ content: {
608
+ flex: 1,
609
+ paddingHorizontal: 20
468
610
  },
469
- description: {
470
- marginBottom: 24
611
+ scrollContent: {
612
+ paddingBottom: 40
471
613
  },
472
- descriptionText: {
473
- fontSize: 14,
474
- fontFamily: fontFamilies.phudu,
475
- lineHeight: 20
614
+ loadingContainer: {
615
+ flex: 1,
616
+ justifyContent: 'center',
617
+ alignItems: 'center',
618
+ paddingTop: 60
476
619
  },
477
- usersContainer: {
478
- marginBottom: 32
620
+ loadingText: {
621
+ marginTop: 16,
622
+ fontSize: 16,
623
+ fontFamily: fontFamilies.phudu
479
624
  },
480
625
  sectionTitle: {
481
- fontSize: 16,
626
+ fontSize: 20,
482
627
  fontFamily: fontFamilies.phuduSemiBold,
483
- marginBottom: 16
628
+ marginBottom: 20,
629
+ marginTop: 10
630
+ },
631
+ emptyState: {
632
+ alignItems: 'center',
633
+ paddingVertical: 40
634
+ },
635
+ emptyText: {
636
+ fontSize: 16,
637
+ fontFamily: fontFamilies.phudu,
638
+ textAlign: 'center'
484
639
  },
485
- userItem: {
640
+ sessionCard: {
641
+ borderRadius: 16,
642
+ marginBottom: 16,
643
+ padding: 20,
644
+ shadowOffset: {
645
+ width: 0,
646
+ height: 2
647
+ },
648
+ shadowOpacity: 0.1,
649
+ shadowRadius: 8,
650
+ elevation: 3
651
+ },
652
+ sessionHeader: {
486
653
  flexDirection: 'row',
487
654
  alignItems: 'center',
488
- justifyContent: 'space-between',
489
- padding: 16,
490
- borderRadius: 12,
491
- borderWidth: 1,
492
- marginBottom: 12
655
+ marginBottom: 16
656
+ },
657
+ avatarContainer: {
658
+ position: 'relative',
659
+ marginRight: 16
660
+ },
661
+ avatar: {
662
+ width: 60,
663
+ height: 60,
664
+ borderRadius: 30
665
+ },
666
+ avatarPlaceholder: {
667
+ width: 60,
668
+ height: 60,
669
+ borderRadius: 30,
670
+ justifyContent: 'center',
671
+ alignItems: 'center'
672
+ },
673
+ avatarText: {
674
+ fontSize: 24,
675
+ fontFamily: fontFamilies.phuduBold
676
+ },
677
+ activeBadge: {
678
+ position: 'absolute',
679
+ bottom: -2,
680
+ right: -2,
681
+ width: 20,
682
+ height: 20,
683
+ borderRadius: 10,
684
+ justifyContent: 'center',
685
+ alignItems: 'center'
686
+ },
687
+ activeBadgeText: {
688
+ color: 'white',
689
+ fontSize: 12,
690
+ fontFamily: fontFamilies.phuduBold
493
691
  },
494
692
  userInfo: {
495
- flex: 1
693
+ flex: 1,
694
+ justifyContent: 'center'
496
695
  },
497
- username: {
498
- fontSize: 16,
696
+ displayName: {
697
+ fontSize: 18,
499
698
  fontFamily: fontFamilies.phuduSemiBold,
500
699
  marginBottom: 4
501
700
  },
502
- email: {
701
+ username: {
503
702
  fontSize: 14,
504
703
  fontFamily: fontFamilies.phudu,
505
- marginBottom: 8
506
- },
507
- activeBadge: {
508
- paddingHorizontal: 8,
509
- paddingVertical: 4,
510
- borderRadius: 6,
511
- alignSelf: 'flex-start'
704
+ marginBottom: 4
512
705
  },
513
- activeBadgeText: {
514
- color: '#FFFFFF',
706
+ lastActive: {
515
707
  fontSize: 12,
516
- fontFamily: fontFamilies.phuduMedium
708
+ fontFamily: fontFamilies.phudu
517
709
  },
518
- userActions: {
710
+ sessionActions: {
519
711
  flexDirection: 'row',
520
- gap: 8
712
+ justifyContent: 'space-between',
713
+ gap: 12
521
714
  },
522
715
  switchButton: {
523
- paddingHorizontal: 16,
524
- paddingVertical: 8,
525
- borderRadius: 8,
716
+ flex: 1,
717
+ paddingVertical: 12,
718
+ paddingHorizontal: 20,
526
719
  borderWidth: 1,
527
- minWidth: 70,
528
- alignItems: 'center'
720
+ borderRadius: 8,
721
+ alignItems: 'center',
722
+ justifyContent: 'center'
529
723
  },
530
724
  switchButtonText: {
531
725
  fontSize: 14,
532
- fontFamily: fontFamilies.phuduMedium
726
+ fontFamily: fontFamilies.phuduSemiBold
533
727
  },
534
728
  removeButton: {
535
- paddingHorizontal: 16,
536
- paddingVertical: 8,
537
- borderRadius: 8,
729
+ flex: 1,
730
+ paddingVertical: 12,
731
+ paddingHorizontal: 20,
538
732
  borderWidth: 1,
539
- minWidth: 70,
540
- alignItems: 'center'
733
+ borderRadius: 8,
734
+ alignItems: 'center',
735
+ justifyContent: 'center'
541
736
  },
542
737
  removeButtonText: {
543
738
  fontSize: 14,
544
- fontFamily: fontFamilies.phuduMedium
739
+ fontFamily: fontFamilies.phuduSemiBold
545
740
  },
546
- actionsContainer: {
741
+ actionsSection: {
742
+ marginTop: 40,
547
743
  gap: 16
548
744
  },
549
745
  actionButton: {
550
746
  paddingVertical: 16,
551
747
  paddingHorizontal: 20,
552
- borderRadius: 12,
553
748
  borderWidth: 1,
554
- alignItems: 'center'
749
+ borderRadius: 12,
750
+ alignItems: 'center',
751
+ justifyContent: 'center'
555
752
  },
556
753
  actionButtonText: {
557
754
  fontSize: 16,
558
- fontFamily: fontFamilies.phuduMedium
755
+ fontFamily: fontFamilies.phuduSemiBold
559
756
  },
560
757
  dangerButton: {
561
- paddingVertical: 16,
562
- paddingHorizontal: 20,
563
- borderRadius: 12,
564
- alignItems: 'center'
758
+ // Additional styles for danger buttons if needed
565
759
  },
566
760
  dangerButtonText: {
567
761
  fontSize: 16,
568
- fontFamily: fontFamilies.phuduMedium
569
- },
570
- sectionHeader: {
571
- flexDirection: 'row',
572
- alignItems: 'center',
573
- justifyContent: 'space-between',
574
- marginBottom: 16
762
+ fontFamily: fontFamilies.phuduSemiBold
575
763
  },
576
- toggleButton: {
577
- paddingHorizontal: 12,
578
- paddingVertical: 6,
579
- borderRadius: 6,
764
+ deviceManagementSection: {
765
+ marginTop: 20,
766
+ padding: 16,
767
+ borderRadius: 12,
580
768
  borderWidth: 1
581
- },
582
- toggleButtonText: {
583
- fontSize: 14,
584
- fontFamily: fontFamilies.phuduMedium
585
- },
586
- loadingContainer: {
587
- flexDirection: 'row',
588
- alignItems: 'center',
589
- justifyContent: 'center',
590
- paddingVertical: 20,
591
- gap: 8
592
- },
593
- loadingText: {
594
- fontSize: 14,
595
- fontFamily: fontFamilies.phudu
596
- },
597
- emptyText: {
598
- fontSize: 14,
599
- fontFamily: fontFamilies.phudu,
600
- textAlign: 'center',
601
- paddingVertical: 20,
602
- fontStyle: 'italic'
603
769
  }
604
770
  });
605
- export default AccountSwitcherScreen;
771
+ export default ModernAccountSwitcherScreen;
606
772
  //# sourceMappingURL=AccountSwitcherScreen.js.map