@oxyhq/services 5.4.5 → 5.4.6
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/index.js +59 -0
- package/lib/commonjs/core/index.js.map +1 -1
- package/lib/commonjs/ui/components/FollowButton.js +23 -8
- package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
- package/lib/commonjs/ui/hooks/useFollow.js +29 -10
- package/lib/commonjs/ui/hooks/useFollow.js.map +1 -1
- package/lib/commonjs/ui/screens/AppInfoScreen.js +19 -37
- package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FileManagementScreen.js +9 -27
- package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/store/index.js +5 -1
- package/lib/commonjs/ui/store/index.js.map +1 -1
- package/lib/module/core/index.js +59 -0
- package/lib/module/core/index.js.map +1 -1
- package/lib/module/ui/components/FollowButton.js +23 -8
- package/lib/module/ui/components/FollowButton.js.map +1 -1
- package/lib/module/ui/hooks/useFollow.js +29 -10
- package/lib/module/ui/hooks/useFollow.js.map +1 -1
- package/lib/module/ui/screens/AppInfoScreen.js +19 -37
- package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
- package/lib/module/ui/screens/FileManagementScreen.js +9 -27
- package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/module/ui/store/index.js +5 -1
- package/lib/module/ui/store/index.js.map +1 -1
- package/lib/typescript/core/index.d.ts +28 -0
- package/lib/typescript/core/index.d.ts.map +1 -1
- package/lib/typescript/ui/components/FollowButton.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/useFollow.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AppInfoScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/FileManagementScreen.d.ts.map +1 -1
- package/lib/typescript/ui/store/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/ui/components/FollowButton.tsx +25 -11
- package/src/ui/hooks/useFollow.ts +30 -10
- package/src/ui/screens/AppInfoScreen.tsx +23 -40
- package/src/ui/screens/FileManagementScreen.tsx +248 -268
- package/src/ui/store/index.ts +6 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFollow.d.ts","sourceRoot":"","sources":["../../../../src/ui/hooks/useFollow.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useFollow.d.ts","sourceRoot":"","sources":["../../../../src/ui/hooks/useFollow.ts"],"names":[],"mappings":"AAuDA;;;;GAIG;AACH,eAAO,MAAM,SAAS,GAAI,SAAS,MAAM,GAAG,MAAM,EAAE;;;;;iCA8CF,OAAO;;;;;;;;;;;;;;;wCAqBM,MAAM;2CAcT,MAAM,aAAa,OAAO;uCAIxB,MAAM;;sCAiBb,MAAM;;;;;;;;;;;;CA8B5D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppInfoScreen.d.ts","sourceRoot":"","sources":["../../../../src/ui/screens/AppInfoScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAanD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAoBtD,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,
|
|
1
|
+
{"version":3,"file":"AppInfoScreen.d.ts","sourceRoot":"","sources":["../../../../src/ui/screens/AppInfoScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAanD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAoBtD,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CA8jB5C,CAAC;AA2FF,eAAe,aAAa,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileManagementScreen.d.ts","sourceRoot":"","sources":["../../../../src/ui/screens/FileManagementScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoD,MAAM,OAAO,CAAC;AAezE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAOtD,UAAU,yBAA0B,SAAQ,eAAe;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,QAAA,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,
|
|
1
|
+
{"version":3,"file":"FileManagementScreen.d.ts","sourceRoot":"","sources":["../../../../src/ui/screens/FileManagementScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoD,MAAM,OAAO,CAAC;AAezE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAOtD,UAAU,yBAA0B,SAAQ,eAAe;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,QAAA,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAyxD7D,CAAC;AA4qBF,eAAe,oBAAoB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/store/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAEpD,UAAU,SAAS;IACjB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,UAAU,WAAW;IAEnB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAExC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEtC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;CACvC;AAiBD,eAAO,MAAM,iBAAiB;;;;YAEc,MAAM;iBAAe,GAAG;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/store/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAEpD,UAAU,SAAS;IACjB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,UAAU,WAAW;IAEnB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAExC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEtC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;CACvC;AAiBD,eAAO,MAAM,iBAAiB;;;;YAEc,MAAM;iBAAe,GAAG;;;;;;;;;;EAkCnE,CAAC;AAGF,eAAO,MAAM,gBAAgB;;;;;YAGjB,MAAM;iBACD,GAAG;0BACM,OAAO;;;;;;;;;;EAkEhC,CAAC;AAwFF,eAAO,MAAQ,UAAU,6EAAE,YAAY,kFAAE,YAAY,oFAAE,MAAM,uEAAsB,CAAC;AACpF,eAAO,MAAQ,kBAAkB;YA3D0C,MAAM;iBAAe,OAAO;iCA2DpE,gBAAgB,0FAAE,gBAAgB,mFAAwB,CAAC;AAG9F,eAAO,MAAM,wBAAwB,GAAI,OAAO,SAAS,EAAE,QAAQ,MAAM,YACzB,CAAC;AAEjD,eAAO,MAAM,KAAK;;;;;;;;oCAKhB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC;AAC1D,MAAM,MAAM,WAAW,GAAG,OAAO,KAAK,CAAC,QAAQ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxyhq/services",
|
|
3
|
-
"version": "5.4.
|
|
3
|
+
"version": "5.4.6",
|
|
4
4
|
"description": "Reusable OxyHQ module to handle authentication, user management, karma system, device-based session management and more 🚀",
|
|
5
5
|
"main": "lib/commonjs/node/index.js",
|
|
6
6
|
"module": "lib/module/node/index.js",
|
|
@@ -142,17 +142,31 @@ const FollowButton: React.FC<FollowButtonProps> = ({
|
|
|
142
142
|
const dispatch = useDispatch();
|
|
143
143
|
const { oxyServices, isAuthenticated } = useOxy();
|
|
144
144
|
|
|
145
|
-
// Optimized single selector to prevent multiple re-renders
|
|
146
|
-
const followState = useSelector((state: RootState) =>
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
145
|
+
// Optimized single selector to prevent multiple re-renders with defensive checks
|
|
146
|
+
const followState = useSelector((state: RootState) => {
|
|
147
|
+
// Defensive check to handle cases where follow state might not be initialized yet
|
|
148
|
+
if (!state.follow) {
|
|
149
|
+
return {
|
|
150
|
+
isFollowing: initiallyFollowing ?? false,
|
|
151
|
+
isLoading: false,
|
|
152
|
+
error: null
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
isFollowing: state.follow.followingUsers?.[userId] ?? initiallyFollowing ?? false,
|
|
158
|
+
isLoading: state.follow.loadingUsers?.[userId] ?? false,
|
|
159
|
+
error: state.follow.errors?.[userId] ?? null
|
|
160
|
+
};
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// Whether the follow status has been loaded from the store with defensive check
|
|
164
|
+
const isStatusKnown = useSelector((state: RootState) => {
|
|
165
|
+
if (!state.follow?.followingUsers) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
return Object.prototype.hasOwnProperty.call(state.follow.followingUsers, userId);
|
|
169
|
+
});
|
|
156
170
|
|
|
157
171
|
const { isFollowing, isLoading, error } = followState;
|
|
158
172
|
|
|
@@ -6,9 +6,9 @@ import { useOxy } from '../context/OxyContext';
|
|
|
6
6
|
|
|
7
7
|
// Memoized selector to prevent unnecessary re-renders
|
|
8
8
|
const createFollowSelector = (userId: string) => (state: RootState) => ({
|
|
9
|
-
isFollowing: state.follow
|
|
10
|
-
isLoading: state.follow
|
|
11
|
-
error: state.follow
|
|
9
|
+
isFollowing: state.follow?.followingUsers?.[userId] ?? false,
|
|
10
|
+
isLoading: state.follow?.loadingUsers?.[userId] ?? false,
|
|
11
|
+
error: state.follow?.errors?.[userId] ?? null,
|
|
12
12
|
});
|
|
13
13
|
|
|
14
14
|
// Memoized selector for multiple users
|
|
@@ -16,20 +16,40 @@ const createMultipleFollowSelector = (userIds: string[]) => (state: RootState) =
|
|
|
16
16
|
const followData: Record<string, { isFollowing: boolean; isLoading: boolean; error: string | null }> = {};
|
|
17
17
|
const followState = state.follow;
|
|
18
18
|
|
|
19
|
+
// Defensive check for follow state
|
|
20
|
+
if (!followState) {
|
|
21
|
+
// Return default values if follow state is not initialized
|
|
22
|
+
for (const userId of userIds) {
|
|
23
|
+
followData[userId] = {
|
|
24
|
+
isFollowing: false,
|
|
25
|
+
isLoading: false,
|
|
26
|
+
error: null,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
followData,
|
|
32
|
+
isAnyLoading: false,
|
|
33
|
+
hasAnyError: false,
|
|
34
|
+
allFollowing: false,
|
|
35
|
+
allNotFollowing: true,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
19
39
|
for (const userId of userIds) {
|
|
20
40
|
followData[userId] = {
|
|
21
|
-
isFollowing: followState.followingUsers[userId] ?? false,
|
|
22
|
-
isLoading: followState.loadingUsers[userId] ?? false,
|
|
23
|
-
error: followState.errors[userId] ?? null,
|
|
41
|
+
isFollowing: followState.followingUsers?.[userId] ?? false,
|
|
42
|
+
isLoading: followState.loadingUsers?.[userId] ?? false,
|
|
43
|
+
error: followState.errors?.[userId] ?? null,
|
|
24
44
|
};
|
|
25
45
|
}
|
|
26
46
|
|
|
27
47
|
return {
|
|
28
48
|
followData,
|
|
29
|
-
isAnyLoading: userIds.some(uid => followState.loadingUsers[uid]),
|
|
30
|
-
hasAnyError: userIds.some(uid => followState.errors[uid]),
|
|
31
|
-
allFollowing: userIds.every(uid => followState.followingUsers[uid]),
|
|
32
|
-
allNotFollowing: userIds.every(uid => !followState.followingUsers[uid]),
|
|
49
|
+
isAnyLoading: userIds.some(uid => followState.loadingUsers?.[uid]),
|
|
50
|
+
hasAnyError: userIds.some(uid => followState.errors?.[uid]),
|
|
51
|
+
allFollowing: userIds.every(uid => followState.followingUsers?.[uid]),
|
|
52
|
+
allNotFollowing: userIds.every(uid => !followState.followingUsers?.[uid]),
|
|
33
53
|
};
|
|
34
54
|
};
|
|
35
55
|
|
|
@@ -69,18 +69,15 @@ const AppInfoScreen: React.FC<BaseScreenProps> = ({
|
|
|
69
69
|
// Check API connection on mount
|
|
70
70
|
const checkConnection = async () => {
|
|
71
71
|
setConnectionStatus('checking');
|
|
72
|
-
|
|
72
|
+
|
|
73
|
+
if (!oxyServices) {
|
|
74
|
+
setConnectionStatus('disconnected');
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
73
78
|
try {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
timeout: 3000,
|
|
77
|
-
} as any);
|
|
78
|
-
|
|
79
|
-
if (response.ok) {
|
|
80
|
-
setConnectionStatus('connected');
|
|
81
|
-
} else {
|
|
82
|
-
setConnectionStatus('disconnected');
|
|
83
|
-
}
|
|
79
|
+
await oxyServices.healthCheck();
|
|
80
|
+
setConnectionStatus('connected');
|
|
84
81
|
} catch (error) {
|
|
85
82
|
setConnectionStatus('disconnected');
|
|
86
83
|
}
|
|
@@ -121,22 +118,11 @@ const AppInfoScreen: React.FC<BaseScreenProps> = ({
|
|
|
121
118
|
toast.info('Running system checks...', { duration: 2000 });
|
|
122
119
|
|
|
123
120
|
try {
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
if (response.ok) {
|
|
130
|
-
const data = await response.json();
|
|
131
|
-
checks.push('✅ API server is responding');
|
|
132
|
-
checks.push(`📊 Server stats: ${data.users || 0} users`);
|
|
133
|
-
checks.push(`🌐 API URL: ${apiBaseUrl}`);
|
|
134
|
-
setConnectionStatus('connected');
|
|
135
|
-
} else {
|
|
136
|
-
checks.push('❌ API server returned error status');
|
|
137
|
-
checks.push(` Status: ${response.status} ${response.statusText}`);
|
|
138
|
-
setConnectionStatus('disconnected');
|
|
139
|
-
}
|
|
121
|
+
const data = await oxyServices.healthCheck();
|
|
122
|
+
checks.push('✅ API server is responding');
|
|
123
|
+
checks.push(`📊 Server stats: ${data.users || 0} users`);
|
|
124
|
+
checks.push(`🌐 API URL: ${apiBaseUrl}`);
|
|
125
|
+
setConnectionStatus('connected');
|
|
140
126
|
} catch (error) {
|
|
141
127
|
checks.push('❌ API server connection failed');
|
|
142
128
|
checks.push(` Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
@@ -514,20 +500,17 @@ const AppInfoScreen: React.FC<BaseScreenProps> = ({
|
|
|
514
500
|
}
|
|
515
501
|
onPress={async () => {
|
|
516
502
|
setConnectionStatus('checking');
|
|
517
|
-
|
|
503
|
+
|
|
504
|
+
if (!oxyServices) {
|
|
505
|
+
setConnectionStatus('disconnected');
|
|
506
|
+
toast.error('OxyServices not initialized');
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
|
|
518
510
|
try {
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
} as any);
|
|
523
|
-
|
|
524
|
-
if (response.ok) {
|
|
525
|
-
setConnectionStatus('connected');
|
|
526
|
-
toast.success('API connection successful');
|
|
527
|
-
} else {
|
|
528
|
-
setConnectionStatus('disconnected');
|
|
529
|
-
toast.error(`API server error: ${response.status}`);
|
|
530
|
-
}
|
|
511
|
+
await oxyServices.healthCheck();
|
|
512
|
+
setConnectionStatus('connected');
|
|
513
|
+
toast.success('API connection successful');
|
|
531
514
|
} catch (error) {
|
|
532
515
|
setConnectionStatus('disconnected');
|
|
533
516
|
toast.error('Failed to connect to API server');
|