@oxyhq/services 5.3.2 → 5.3.3

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.
@@ -8,17 +8,26 @@ import {
8
8
  ScrollView,
9
9
  Alert,
10
10
  Platform,
11
+ Image,
12
+ Dimensions,
11
13
  } from 'react-native';
12
14
  import { BaseScreenProps } from '../navigation/types';
13
15
  import { useOxy } from '../context/OxyContext';
14
16
  import { SecureClientSession } from '../../models/secureSession';
15
17
  import { fontFamilies } from '../styles/fonts';
18
+ import { User } from '../../models/interfaces';
19
+
20
+ interface SessionWithUser extends SecureClientSession {
21
+ userProfile?: User;
22
+ isLoadingProfile?: boolean;
23
+ }
16
24
 
17
25
  const AccountSwitcherScreen: React.FC<BaseScreenProps> = ({
18
26
  onClose,
19
27
  theme,
20
28
  navigate,
21
29
  goBack,
30
+ oxyServices,
22
31
  }) => {
23
32
  const {
24
33
  user,
@@ -30,17 +39,68 @@ const AccountSwitcherScreen: React.FC<BaseScreenProps> = ({
30
39
  isLoading
31
40
  } = useOxy();
32
41
 
42
+ const [sessionsWithUsers, setSessionsWithUsers] = useState<SessionWithUser[]>([]);
33
43
  const [switchingToUserId, setSwitchingToUserId] = useState<string | null>(null);
34
44
  const [removingUserId, setRemovingUserId] = useState<string | null>(null);
35
45
 
46
+ const screenWidth = Dimensions.get('window').width;
36
47
  const isDarkTheme = theme === 'dark';
37
- const textColor = isDarkTheme ? '#FFFFFF' : '#000000';
38
- const backgroundColor = isDarkTheme ? '#121212' : '#FFFFFF';
39
- const secondaryBackgroundColor = isDarkTheme ? '#222222' : '#F5F5F5';
40
- const borderColor = isDarkTheme ? '#444444' : '#E0E0E0';
41
- const primaryColor = '#0066CC';
42
- const dangerColor = '#D32F2F';
43
- const successColor = '#2E7D32';
48
+
49
+ // Modern color scheme
50
+ const colors = {
51
+ background: isDarkTheme ? '#000000' : '#FFFFFF',
52
+ surface: isDarkTheme ? '#1C1C1E' : '#F2F2F7',
53
+ card: isDarkTheme ? '#2C2C2E' : '#FFFFFF',
54
+ text: isDarkTheme ? '#FFFFFF' : '#000000',
55
+ secondaryText: isDarkTheme ? '#8E8E93' : '#6D6D70',
56
+ accent: '#007AFF',
57
+ destructive: '#FF3B30',
58
+ success: '#34C759',
59
+ border: isDarkTheme ? '#38383A' : '#C6C6C8',
60
+ activeCard: isDarkTheme ? '#0A84FF20' : '#007AFF15',
61
+ shadow: isDarkTheme ? 'rgba(0,0,0,0.3)' : 'rgba(0,0,0,0.1)',
62
+ };
63
+
64
+ // Load user profiles for sessions
65
+ useEffect(() => {
66
+ const loadUserProfiles = async () => {
67
+ if (!sessions.length || !oxyServices) return;
68
+
69
+ const updatedSessions: SessionWithUser[] = sessions.map(session => ({
70
+ ...session,
71
+ isLoadingProfile: true,
72
+ }));
73
+ setSessionsWithUsers(updatedSessions);
74
+
75
+ // Load profiles for each session
76
+ for (let i = 0; i < sessions.length; i++) {
77
+ const session = sessions[i];
78
+ try {
79
+ // Try to get user profile using the session
80
+ const userProfile = await oxyServices.getUserBySession(session.sessionId);
81
+
82
+ setSessionsWithUsers(prev =>
83
+ prev.map(s =>
84
+ s.sessionId === session.sessionId
85
+ ? { ...s, userProfile, isLoadingProfile: false }
86
+ : s
87
+ )
88
+ );
89
+ } catch (error) {
90
+ console.error(`Failed to load profile for session ${session.sessionId}:`, error);
91
+ setSessionsWithUsers(prev =>
92
+ prev.map(s =>
93
+ s.sessionId === session.sessionId
94
+ ? { ...s, isLoadingProfile: false }
95
+ : s
96
+ )
97
+ );
98
+ }
99
+ }
100
+ };
101
+
102
+ loadUserProfiles();
103
+ }, [sessions, oxyServices]);
44
104
 
45
105
  const handleSwitchSession = async (sessionId: string) => {
46
106
  if (sessionId === user?.sessionId) return; // Already active session
@@ -134,20 +194,20 @@ const AccountSwitcherScreen: React.FC<BaseScreenProps> = ({
134
194
  style={[
135
195
  styles.userItem,
136
196
  {
137
- backgroundColor: isActive ? primaryColor + '20' : secondaryBackgroundColor,
138
- borderColor: isActive ? primaryColor : borderColor,
197
+ backgroundColor: isActive ? colors.activeCard : colors.surface,
198
+ borderColor: isActive ? colors.accent : colors.border,
139
199
  },
140
200
  ]}
141
201
  >
142
202
  <View style={styles.userInfo}>
143
- <Text style={[styles.username, { color: textColor }]}>
203
+ <Text style={[styles.username, { color: colors.text }]}>
144
204
  {isActive ? user?.username || 'Current Account' : 'Account Session'}
145
205
  </Text>
146
206
  <Text style={[styles.email, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
147
207
  Last active: {new Date(session.lastActive).toLocaleDateString()}
148
208
  </Text>
149
209
  {isActive && (
150
- <View style={[styles.activeBadge, { backgroundColor: successColor }]}>
210
+ <View style={[styles.activeBadge, { backgroundColor: colors.success }]}>
151
211
  <Text style={styles.activeBadgeText}>Active</Text>
152
212
  </View>
153
213
  )}
@@ -156,27 +216,27 @@ const AccountSwitcherScreen: React.FC<BaseScreenProps> = ({
156
216
  <View style={styles.userActions}>
157
217
  {!isActive && (
158
218
  <TouchableOpacity
159
- style={[styles.switchButton, { borderColor: primaryColor }]}
219
+ style={[styles.switchButton, { borderColor: colors.accent }]}
160
220
  onPress={() => handleSwitchSession(session.sessionId)}
161
221
  disabled={isSwitching || isRemoving}
162
222
  >
163
223
  {isSwitching ? (
164
- <ActivityIndicator color={primaryColor} size="small" />
224
+ <ActivityIndicator color={colors.accent} size="small" />
165
225
  ) : (
166
- <Text style={[styles.switchButtonText, { color: primaryColor }]}>Switch</Text>
226
+ <Text style={[styles.switchButtonText, { color: colors.accent }]}>Switch</Text>
167
227
  )}
168
228
  </TouchableOpacity>
169
229
  )}
170
230
 
171
231
  <TouchableOpacity
172
- style={[styles.removeButton, { borderColor: dangerColor }]}
232
+ style={[styles.removeButton, { borderColor: colors.destructive }]}
173
233
  onPress={() => handleRemoveSession(session.sessionId)}
174
234
  disabled={isSwitching || isRemoving || sessions.length === 1}
175
235
  >
176
236
  {isRemoving ? (
177
- <ActivityIndicator color={dangerColor} size="small" />
237
+ <ActivityIndicator color={colors.destructive} size="small" />
178
238
  ) : (
179
- <Text style={[styles.removeButtonText, { color: dangerColor }]}>Remove</Text>
239
+ <Text style={[styles.removeButtonText, { color: colors.destructive }]}>Remove</Text>
180
240
  )}
181
241
  </TouchableOpacity>
182
242
  </View>
@@ -185,12 +245,12 @@ const AccountSwitcherScreen: React.FC<BaseScreenProps> = ({
185
245
  };
186
246
 
187
247
  return (
188
- <View style={[styles.container, { backgroundColor }]}>
248
+ <View style={[styles.container, { backgroundColor: colors.background }]}>
189
249
  <View style={styles.header}>
190
250
  <TouchableOpacity style={styles.backButton} onPress={goBack}>
191
- <Text style={[styles.backButtonText, { color: primaryColor }]}>‹ Back</Text>
251
+ <Text style={[styles.backButtonText, { color: colors.accent }]}>‹ Back</Text>
192
252
  </TouchableOpacity>
193
- <Text style={[styles.title, { color: textColor }]}>Account Switcher</Text>
253
+ <Text style={[styles.title, { color: colors.text }]}>Account Switcher</Text>
194
254
  <View style={styles.placeholder} />
195
255
  </View>
196
256
 
@@ -202,7 +262,7 @@ const AccountSwitcherScreen: React.FC<BaseScreenProps> = ({
202
262
  </View>
203
263
 
204
264
  <View style={styles.usersContainer}>
205
- <Text style={[styles.sectionTitle, { color: textColor }]}>
265
+ <Text style={[styles.sectionTitle, { color: colors.text }]}>
206
266
  Sessions ({sessions.length})
207
267
  </Text>
208
268
 
@@ -211,10 +271,10 @@ const AccountSwitcherScreen: React.FC<BaseScreenProps> = ({
211
271
 
212
272
  <View style={styles.actionsContainer}>
213
273
  <TouchableOpacity
214
- style={[styles.actionButton, { borderColor }]}
274
+ style={[styles.actionButton, { borderColor: colors.border }]}
215
275
  onPress={() => navigate('SignIn')}
216
276
  >
217
- <Text style={[styles.actionButtonText, { color: textColor }]}>
277
+ <Text style={[styles.actionButtonText, { color: colors.text }]}>
218
278
  Add Another Account
219
279
  </Text>
220
280
  </TouchableOpacity>
@@ -226,9 +286,9 @@ const AccountSwitcherScreen: React.FC<BaseScreenProps> = ({
226
286
  disabled={isLoading}
227
287
  >
228
288
  {isLoading ? (
229
- <ActivityIndicator color={dangerColor} size="small" />
289
+ <ActivityIndicator color={colors.destructive} size="small" />
230
290
  ) : (
231
- <Text style={[styles.dangerButtonText, { color: dangerColor }]}>
291
+ <Text style={[styles.dangerButtonText, { color: colors.destructive }]}>
232
292
  Sign Out All Sessions
233
293
  </Text>
234
294
  )}