@oxyhq/services 6.9.44 → 6.9.45
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/ui/components/OxyPayButton.js +4 -2
- package/lib/commonjs/ui/components/OxyPayButton.js.map +1 -1
- package/lib/commonjs/ui/components/OxySignInButton.js +83 -82
- package/lib/commonjs/ui/components/OxySignInButton.js.map +1 -1
- package/lib/commonjs/ui/components/SettingRow.js +11 -5
- package/lib/commonjs/ui/components/SettingRow.js.map +1 -1
- package/lib/commonjs/ui/components/fileManagement/FileDetailsModal.js +76 -121
- package/lib/commonjs/ui/components/fileManagement/FileDetailsModal.js.map +1 -1
- package/lib/commonjs/ui/components/fileManagement/UploadPreview.js +32 -18
- package/lib/commonjs/ui/components/fileManagement/UploadPreview.js.map +1 -1
- package/lib/commonjs/ui/components/icon/OxyIcon.js +5 -4
- package/lib/commonjs/ui/components/icon/OxyIcon.js.map +1 -1
- package/lib/commonjs/ui/components/internal/GroupedPillButtons.js +11 -9
- package/lib/commonjs/ui/components/internal/GroupedPillButtons.js.map +1 -1
- package/lib/commonjs/ui/components/internal/PinInput.js +3 -2
- package/lib/commonjs/ui/components/internal/PinInput.js.map +1 -1
- package/lib/commonjs/ui/components/modals/DeleteAccountModal.js +83 -219
- package/lib/commonjs/ui/components/modals/DeleteAccountModal.js.map +1 -1
- package/lib/commonjs/ui/constants/theme.js +2 -2
- package/lib/commonjs/ui/constants/theme.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountCenterScreen.js +12 -10
- package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js +70 -79
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js +22 -10
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +141 -81
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountVerificationScreen.js +21 -9
- package/lib/commonjs/ui/screens/AccountVerificationScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FileManagementScreen.js +83 -50
- package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/HistoryViewScreen.js +80 -101
- package/lib/commonjs/ui/screens/HistoryViewScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +66 -93
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SessionManagementScreen.js +101 -66
- package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/utils/fileManagement.js +0 -21
- package/lib/commonjs/ui/utils/fileManagement.js.map +1 -1
- package/lib/module/ui/components/OxyPayButton.js +4 -2
- package/lib/module/ui/components/OxyPayButton.js.map +1 -1
- package/lib/module/ui/components/OxySignInButton.js +84 -83
- package/lib/module/ui/components/OxySignInButton.js.map +1 -1
- package/lib/module/ui/components/SettingRow.js +11 -5
- package/lib/module/ui/components/SettingRow.js.map +1 -1
- package/lib/module/ui/components/fileManagement/FileDetailsModal.js +76 -122
- package/lib/module/ui/components/fileManagement/FileDetailsModal.js.map +1 -1
- package/lib/module/ui/components/fileManagement/UploadPreview.js +32 -19
- package/lib/module/ui/components/fileManagement/UploadPreview.js.map +1 -1
- package/lib/module/ui/components/icon/OxyIcon.js +5 -4
- package/lib/module/ui/components/icon/OxyIcon.js.map +1 -1
- package/lib/module/ui/components/internal/GroupedPillButtons.js +11 -9
- package/lib/module/ui/components/internal/GroupedPillButtons.js.map +1 -1
- package/lib/module/ui/components/internal/PinInput.js +3 -2
- package/lib/module/ui/components/internal/PinInput.js.map +1 -1
- package/lib/module/ui/components/modals/DeleteAccountModal.js +83 -220
- package/lib/module/ui/components/modals/DeleteAccountModal.js.map +1 -1
- package/lib/module/ui/constants/theme.js +2 -2
- package/lib/module/ui/constants/theme.js.map +1 -1
- package/lib/module/ui/screens/AccountCenterScreen.js +11 -10
- package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountOverviewScreen.js +71 -80
- package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSettingsScreen.js +22 -10
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSwitcherScreen.js +140 -81
- package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountVerificationScreen.js +22 -10
- package/lib/module/ui/screens/AccountVerificationScreen.js.map +1 -1
- package/lib/module/ui/screens/FileManagementScreen.js +85 -52
- package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/HistoryViewScreen.js +80 -101
- package/lib/module/ui/screens/HistoryViewScreen.js.map +1 -1
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js +66 -94
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/module/ui/screens/SessionManagementScreen.js +101 -67
- package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
- package/lib/module/ui/utils/fileManagement.js +0 -20
- package/lib/module/ui/utils/fileManagement.js.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxyPayButton.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxySignInButton.d.ts +0 -1
- package/lib/typescript/commonjs/ui/components/OxySignInButton.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/SettingRow.d.ts +2 -2
- package/lib/typescript/commonjs/ui/components/SettingRow.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/fileManagement/FileDetailsModal.d.ts +3 -4
- package/lib/typescript/commonjs/ui/components/fileManagement/FileDetailsModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/fileManagement/UploadPreview.d.ts +2 -3
- package/lib/typescript/commonjs/ui/components/fileManagement/UploadPreview.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/icon/OxyIcon.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/internal/GroupedPillButtons.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/internal/PinInput.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/modals/DeleteAccountModal.d.ts +2 -2
- package/lib/typescript/commonjs/ui/components/modals/DeleteAccountModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/AccountCenterScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/AccountOverviewScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/AccountVerificationScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/FileManagementScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/HistoryViewScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/SessionManagementScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts +0 -4
- package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyPayButton.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxySignInButton.d.ts +0 -1
- package/lib/typescript/module/ui/components/OxySignInButton.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/SettingRow.d.ts +2 -2
- package/lib/typescript/module/ui/components/SettingRow.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/fileManagement/FileDetailsModal.d.ts +3 -4
- package/lib/typescript/module/ui/components/fileManagement/FileDetailsModal.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/fileManagement/UploadPreview.d.ts +2 -3
- package/lib/typescript/module/ui/components/fileManagement/UploadPreview.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/icon/OxyIcon.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/internal/GroupedPillButtons.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/internal/PinInput.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/modals/DeleteAccountModal.d.ts +2 -2
- package/lib/typescript/module/ui/components/modals/DeleteAccountModal.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/AccountCenterScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/AccountOverviewScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/AccountVerificationScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/FileManagementScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/HistoryViewScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/SessionManagementScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/utils/fileManagement.d.ts +0 -4
- package/lib/typescript/module/ui/utils/fileManagement.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/ui/components/OxyPayButton.tsx +5 -3
- package/src/ui/components/OxySignInButton.tsx +82 -81
- package/src/ui/components/SettingRow.tsx +14 -7
- package/src/ui/components/fileManagement/FileDetailsModal.tsx +69 -99
- package/src/ui/components/fileManagement/UploadPreview.tsx +58 -46
- package/src/ui/components/icon/OxyIcon.tsx +5 -4
- package/src/ui/components/internal/GroupedPillButtons.tsx +15 -12
- package/src/ui/components/internal/PinInput.tsx +4 -3
- package/src/ui/components/modals/DeleteAccountModal.tsx +79 -221
- package/src/ui/constants/theme.ts +2 -2
- package/src/ui/screens/AccountCenterScreen.tsx +34 -136
- package/src/ui/screens/AccountOverviewScreen.tsx +63 -98
- package/src/ui/screens/AccountSettingsScreen.tsx +21 -7
- package/src/ui/screens/AccountSwitcherScreen.tsx +135 -87
- package/src/ui/screens/AccountVerificationScreen.tsx +24 -16
- package/src/ui/screens/FileManagementScreen.tsx +62 -54
- package/src/ui/screens/HistoryViewScreen.tsx +57 -204
- package/src/ui/screens/PremiumSubscriptionScreen.tsx +73 -93
- package/src/ui/screens/SessionManagementScreen.tsx +101 -73
- package/src/ui/utils/fileManagement.ts +0 -30
- package/lib/commonjs/ui/utils/confirmAction.js +0 -28
- package/lib/commonjs/ui/utils/confirmAction.js.map +0 -1
- package/lib/module/ui/utils/confirmAction.js +0 -25
- package/lib/module/ui/utils/confirmAction.js.map +0 -1
- package/lib/typescript/commonjs/ui/utils/confirmAction.d.ts +0 -7
- package/lib/typescript/commonjs/ui/utils/confirmAction.d.ts.map +0 -1
- package/lib/typescript/module/ui/utils/confirmAction.d.ts +0 -7
- package/lib/typescript/module/ui/utils/confirmAction.d.ts.map +0 -1
- package/src/ui/utils/confirmAction.ts +0 -23
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
StyleSheet,
|
|
8
8
|
ActivityIndicator,
|
|
9
9
|
ScrollView,
|
|
10
|
-
Alert,
|
|
11
10
|
Platform,
|
|
12
11
|
Image,
|
|
13
12
|
Dimensions,
|
|
@@ -17,7 +16,8 @@ import type { ClientSession } from '@oxyhq/core';
|
|
|
17
16
|
import { fontFamilies } from '../styles/fonts';
|
|
18
17
|
import type { User } from '@oxyhq/core';
|
|
19
18
|
import { toast } from '../../lib/sonner';
|
|
20
|
-
import
|
|
19
|
+
import * as Prompt from '@oxyhq/bloom/prompt';
|
|
20
|
+
import { usePromptControl } from '@oxyhq/bloom/prompt';
|
|
21
21
|
import OxyIcon from '../components/icon/OxyIcon';
|
|
22
22
|
import { Ionicons } from '@expo/vector-icons';
|
|
23
23
|
import Avatar from '../components/Avatar';
|
|
@@ -77,6 +77,16 @@ const ModernAccountSwitcherScreen: React.FC<BaseScreenProps> = ({
|
|
|
77
77
|
const [remotingLogoutSessionId, setRemoteLogoutSessionId] = useState<string | null>(null);
|
|
78
78
|
const [loggingOutAllDevices, setLoggingOutAllDevices] = useState(false);
|
|
79
79
|
|
|
80
|
+
// Pending state for prompts
|
|
81
|
+
const [pendingRemoveSession, setPendingRemoveSession] = useState<{ sessionId: string; displayName: string } | null>(null);
|
|
82
|
+
const [pendingRemoteLogout, setPendingRemoteLogout] = useState<{ sessionId: string; deviceName: string } | null>(null);
|
|
83
|
+
|
|
84
|
+
// Prompt controls
|
|
85
|
+
const removeSessionPrompt = usePromptControl();
|
|
86
|
+
const logoutAllPrompt = usePromptControl();
|
|
87
|
+
const remoteLogoutPrompt = usePromptControl();
|
|
88
|
+
const logoutAllDevicesPrompt = usePromptControl();
|
|
89
|
+
|
|
80
90
|
const screenWidth = Dimensions.get('window').width;
|
|
81
91
|
const { t } = useI18n();
|
|
82
92
|
|
|
@@ -171,47 +181,48 @@ const ModernAccountSwitcherScreen: React.FC<BaseScreenProps> = ({
|
|
|
171
181
|
}
|
|
172
182
|
}, [activeSessionId, switchSession, onClose, t, switchingToUserId]);
|
|
173
183
|
|
|
174
|
-
const
|
|
175
|
-
if (removingUserId) return;
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
setRemovingUserId(null);
|
|
191
|
-
}
|
|
184
|
+
const confirmRemoveSession = useCallback((sessionId: string, displayName: string) => {
|
|
185
|
+
if (removingUserId) return;
|
|
186
|
+
setPendingRemoveSession({ sessionId, displayName });
|
|
187
|
+
removeSessionPrompt.open();
|
|
188
|
+
}, [removingUserId, removeSessionPrompt]);
|
|
189
|
+
|
|
190
|
+
const handleRemoveSession = useCallback(async () => {
|
|
191
|
+
if (!pendingRemoveSession) return;
|
|
192
|
+
const { sessionId } = pendingRemoveSession;
|
|
193
|
+
setRemovingUserId(sessionId);
|
|
194
|
+
try {
|
|
195
|
+
await removeSession(sessionId);
|
|
196
|
+
toast.success(t('accountSwitcher.toasts.removeSuccess') || 'Account removed successfully!');
|
|
197
|
+
} catch (error) {
|
|
198
|
+
if (__DEV__) {
|
|
199
|
+
console.error('Remove session failed:', error);
|
|
192
200
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
211
|
-
toast.error(t('accountSwitcher.toasts.signOutAllFailed', { error: errorMessage }) || `There was a problem signing out: ${errorMessage}`);
|
|
212
|
-
}
|
|
201
|
+
toast.error(t('accountSwitcher.toasts.removeFailed') || 'There was a problem removing the account. Please try again.');
|
|
202
|
+
} finally {
|
|
203
|
+
setRemovingUserId(null);
|
|
204
|
+
setPendingRemoveSession(null);
|
|
205
|
+
}
|
|
206
|
+
}, [pendingRemoveSession, removeSession, t]);
|
|
207
|
+
|
|
208
|
+
const confirmLogoutAll = useCallback(() => {
|
|
209
|
+
logoutAllPrompt.open();
|
|
210
|
+
}, [logoutAllPrompt]);
|
|
211
|
+
|
|
212
|
+
const handleLogoutAll = useCallback(async () => {
|
|
213
|
+
try {
|
|
214
|
+
await logoutAll();
|
|
215
|
+
toast.success(t('accountSwitcher.toasts.signOutAllSuccess') || 'All accounts signed out successfully!');
|
|
216
|
+
if (onClose) {
|
|
217
|
+
onClose();
|
|
213
218
|
}
|
|
214
|
-
)
|
|
219
|
+
} catch (error) {
|
|
220
|
+
if (__DEV__) {
|
|
221
|
+
console.error('Logout all failed:', error);
|
|
222
|
+
}
|
|
223
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
224
|
+
toast.error(t('accountSwitcher.toasts.signOutAllFailed', { error: errorMessage }) || `There was a problem signing out: ${errorMessage}`);
|
|
225
|
+
}
|
|
215
226
|
}, [logoutAll, onClose, t]);
|
|
216
227
|
|
|
217
228
|
const handleSwitchToManagedAccount = useCallback(async (accountId: string) => {
|
|
@@ -257,30 +268,32 @@ const ModernAccountSwitcherScreen: React.FC<BaseScreenProps> = ({
|
|
|
257
268
|
}
|
|
258
269
|
}, [oxyServices, activeSessionId, t]);
|
|
259
270
|
|
|
260
|
-
const
|
|
261
|
-
if (remotingLogoutSessionId) return;
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
setRemoteLogoutSessionId(null);
|
|
278
|
-
}
|
|
271
|
+
const confirmRemoteSessionLogout = useCallback((sessionId: string, deviceName: string) => {
|
|
272
|
+
if (remotingLogoutSessionId) return;
|
|
273
|
+
setPendingRemoteLogout({ sessionId, deviceName });
|
|
274
|
+
remoteLogoutPrompt.open();
|
|
275
|
+
}, [remotingLogoutSessionId, remoteLogoutPrompt]);
|
|
276
|
+
|
|
277
|
+
const handleRemoteSessionLogout = useCallback(async () => {
|
|
278
|
+
if (!pendingRemoteLogout) return;
|
|
279
|
+
const { sessionId } = pendingRemoteLogout;
|
|
280
|
+
setRemoteLogoutSessionId(sessionId);
|
|
281
|
+
try {
|
|
282
|
+
await oxyServices?.logoutSession((activeSessionId ?? null) || '', sessionId);
|
|
283
|
+
await loadAllDeviceSessions();
|
|
284
|
+
toast.success(t('accountSwitcher.toasts.remoteSignOutSuccess', { deviceName: pendingRemoteLogout.deviceName }) || `Signed out from ${pendingRemoteLogout.deviceName} successfully!`);
|
|
285
|
+
} catch (error) {
|
|
286
|
+
if (__DEV__) {
|
|
287
|
+
console.error('Remote logout failed:', error);
|
|
279
288
|
}
|
|
280
|
-
|
|
281
|
-
|
|
289
|
+
toast.error(t('accountSwitcher.toasts.remoteSignOutFailed') || 'There was a problem signing out from the device. Please try again.');
|
|
290
|
+
} finally {
|
|
291
|
+
setRemoteLogoutSessionId(null);
|
|
292
|
+
setPendingRemoteLogout(null);
|
|
293
|
+
}
|
|
294
|
+
}, [pendingRemoteLogout, activeSessionId, oxyServices, loadAllDeviceSessions, t]);
|
|
282
295
|
|
|
283
|
-
const
|
|
296
|
+
const confirmLogoutAllDevices = useCallback(() => {
|
|
284
297
|
const otherDevicesCount = deviceSessions.filter(session => !session.isCurrent).length;
|
|
285
298
|
|
|
286
299
|
if (otherDevicesCount === 0) {
|
|
@@ -288,27 +301,25 @@ const ModernAccountSwitcherScreen: React.FC<BaseScreenProps> = ({
|
|
|
288
301
|
return;
|
|
289
302
|
}
|
|
290
303
|
|
|
291
|
-
if (loggingOutAllDevices) return;
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
}
|
|
305
|
-
toast.error(t('accountSwitcher.toasts.signOutOthersFailed') || 'There was a problem signing out from other devices. Please try again.');
|
|
306
|
-
} finally {
|
|
307
|
-
setLoggingOutAllDevices(false);
|
|
308
|
-
}
|
|
304
|
+
if (loggingOutAllDevices) return;
|
|
305
|
+
logoutAllDevicesPrompt.open();
|
|
306
|
+
}, [deviceSessions, loggingOutAllDevices, logoutAllDevicesPrompt, t]);
|
|
307
|
+
|
|
308
|
+
const handleLogoutAllDevices = useCallback(async () => {
|
|
309
|
+
setLoggingOutAllDevices(true);
|
|
310
|
+
try {
|
|
311
|
+
await oxyServices?.logoutAllDeviceSessions((activeSessionId ?? null) || '');
|
|
312
|
+
await loadAllDeviceSessions();
|
|
313
|
+
toast.success(t('accountSwitcher.toasts.signOutOthersSuccess') || 'Signed out from all other devices successfully!');
|
|
314
|
+
} catch (error) {
|
|
315
|
+
if (__DEV__) {
|
|
316
|
+
console.error('Logout all devices failed:', error);
|
|
309
317
|
}
|
|
310
|
-
|
|
311
|
-
|
|
318
|
+
toast.error(t('accountSwitcher.toasts.signOutOthersFailed') || 'There was a problem signing out from other devices. Please try again.');
|
|
319
|
+
} finally {
|
|
320
|
+
setLoggingOutAllDevices(false);
|
|
321
|
+
}
|
|
322
|
+
}, [activeSessionId, oxyServices, loadAllDeviceSessions, t]);
|
|
312
323
|
|
|
313
324
|
// Memoize filtered sessions for performance
|
|
314
325
|
const otherSessions = useMemo(
|
|
@@ -316,6 +327,11 @@ const ModernAccountSwitcherScreen: React.FC<BaseScreenProps> = ({
|
|
|
316
327
|
[sessionsWithUsers, activeSessionId]
|
|
317
328
|
);
|
|
318
329
|
|
|
330
|
+
const otherDevicesCount = useMemo(
|
|
331
|
+
() => deviceSessions.filter(session => !session.isCurrent).length,
|
|
332
|
+
[deviceSessions]
|
|
333
|
+
);
|
|
334
|
+
|
|
319
335
|
return (
|
|
320
336
|
<View style={[styles.container, { backgroundColor: bloomTheme.colors.background }]}>
|
|
321
337
|
{/* Header */}
|
|
@@ -440,7 +456,7 @@ const ModernAccountSwitcherScreen: React.FC<BaseScreenProps> = ({
|
|
|
440
456
|
</TouchableOpacity>
|
|
441
457
|
<TouchableOpacity
|
|
442
458
|
style={styles.removeButton}
|
|
443
|
-
onPress={() =>
|
|
459
|
+
onPress={() => confirmRemoveSession(sessionWithUser.sessionId, displayName)}
|
|
444
460
|
disabled={isSwitching || isRemoving}
|
|
445
461
|
>
|
|
446
462
|
{isRemoving ? (
|
|
@@ -629,7 +645,7 @@ const ModernAccountSwitcherScreen: React.FC<BaseScreenProps> = ({
|
|
|
629
645
|
iconColor: '#FF3B30',
|
|
630
646
|
title: 'Sign Out All Accounts',
|
|
631
647
|
subtitle: 'Remove all accounts from this device',
|
|
632
|
-
onPress:
|
|
648
|
+
onPress: confirmLogoutAll,
|
|
633
649
|
disabled: sessionsWithUsers.length === 0,
|
|
634
650
|
},
|
|
635
651
|
]}
|
|
@@ -681,12 +697,12 @@ const ModernAccountSwitcherScreen: React.FC<BaseScreenProps> = ({
|
|
|
681
697
|
iconColor: session.isCurrent ? '#34C759' : '#8E8E93',
|
|
682
698
|
title: `${session.deviceName} ${session.isCurrent ? `(${t('accountSwitcher.device.thisDevice') || 'This device'})` : ''}`,
|
|
683
699
|
subtitle: t('accountSwitcher.device.lastActive', { date: new Date(session.lastActive).toLocaleDateString() }) || `Last active: ${new Date(session.lastActive).toLocaleDateString()}`,
|
|
684
|
-
onPress: session.isCurrent ? undefined : () =>
|
|
700
|
+
onPress: session.isCurrent ? undefined : () => confirmRemoteSessionLogout(session.sessionId, session.deviceName),
|
|
685
701
|
disabled: session.isCurrent || remotingLogoutSessionId === session.sessionId,
|
|
686
702
|
customContent: !session.isCurrent ? (
|
|
687
703
|
<TouchableOpacity
|
|
688
704
|
style={styles.removeButton}
|
|
689
|
-
onPress={() =>
|
|
705
|
+
onPress={() => confirmRemoteSessionLogout(session.sessionId, session.deviceName)}
|
|
690
706
|
disabled={remotingLogoutSessionId === session.sessionId}
|
|
691
707
|
>
|
|
692
708
|
{remotingLogoutSessionId === session.sessionId ? (
|
|
@@ -739,6 +755,38 @@ const ModernAccountSwitcherScreen: React.FC<BaseScreenProps> = ({
|
|
|
739
755
|
</>
|
|
740
756
|
)}
|
|
741
757
|
</ScrollView>
|
|
758
|
+
<Prompt.Basic
|
|
759
|
+
control={removeSessionPrompt}
|
|
760
|
+
title={t('accountSwitcher.confirms.removeTitle') || 'Remove Account'}
|
|
761
|
+
description={pendingRemoveSession ? (t('accountSwitcher.confirms.remove', { displayName: pendingRemoveSession.displayName }) || `Are you sure you want to remove ${pendingRemoveSession.displayName} from this device? You'll need to sign in again to access this account.`) : ''}
|
|
762
|
+
onConfirm={handleRemoveSession}
|
|
763
|
+
confirmButtonCta={t('common.remove') || 'Remove'}
|
|
764
|
+
confirmButtonColor='negative'
|
|
765
|
+
/>
|
|
766
|
+
<Prompt.Basic
|
|
767
|
+
control={logoutAllPrompt}
|
|
768
|
+
title={t('accountSwitcher.confirms.logoutAllTitle') || 'Sign Out All'}
|
|
769
|
+
description={t('accountSwitcher.confirms.logoutAll') || 'Are you sure you want to sign out of all accounts? This will remove all saved accounts from this device.'}
|
|
770
|
+
onConfirm={handleLogoutAll}
|
|
771
|
+
confirmButtonCta={t('common.signOutAll') || 'Sign Out All'}
|
|
772
|
+
confirmButtonColor='negative'
|
|
773
|
+
/>
|
|
774
|
+
<Prompt.Basic
|
|
775
|
+
control={remoteLogoutPrompt}
|
|
776
|
+
title={t('accountSwitcher.confirms.remoteLogoutTitle') || 'Remote Sign Out'}
|
|
777
|
+
description={pendingRemoteLogout ? (t('accountSwitcher.confirms.remoteLogout', { deviceName: pendingRemoteLogout.deviceName }) || `Are you sure you want to sign out from "${pendingRemoteLogout.deviceName}"? This will end the session on that device.`) : ''}
|
|
778
|
+
onConfirm={handleRemoteSessionLogout}
|
|
779
|
+
confirmButtonCta={t('common.signOut') || 'Sign Out'}
|
|
780
|
+
confirmButtonColor='negative'
|
|
781
|
+
/>
|
|
782
|
+
<Prompt.Basic
|
|
783
|
+
control={logoutAllDevicesPrompt}
|
|
784
|
+
title={t('accountSwitcher.confirms.logoutOthersTitle') || 'Sign Out Other Devices'}
|
|
785
|
+
description={t('accountSwitcher.confirms.logoutOthers', { count: otherDevicesCount }) || `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.`}
|
|
786
|
+
onConfirm={handleLogoutAllDevices}
|
|
787
|
+
confirmButtonCta={t('common.signOutAll') || 'Sign Out All'}
|
|
788
|
+
confirmButtonColor='negative'
|
|
789
|
+
/>
|
|
742
790
|
</View>
|
|
743
791
|
);
|
|
744
792
|
};
|
|
@@ -7,10 +7,11 @@ import {
|
|
|
7
7
|
TextInput,
|
|
8
8
|
TouchableOpacity,
|
|
9
9
|
ActivityIndicator,
|
|
10
|
-
Alert,
|
|
11
10
|
} from 'react-native';
|
|
12
11
|
import type { BaseScreenProps } from '../types/navigation';
|
|
13
12
|
import { toast } from '../../lib/sonner';
|
|
13
|
+
import * as Prompt from '@oxyhq/bloom/prompt';
|
|
14
|
+
import { usePromptControl } from '@oxyhq/bloom/prompt';
|
|
14
15
|
import { Header, Section } from '../components';
|
|
15
16
|
import { useI18n } from '../hooks/useI18n';
|
|
16
17
|
import { useTheme } from '@oxyhq/bloom/theme';
|
|
@@ -27,9 +28,19 @@ const AccountVerificationScreen: React.FC<BaseScreenProps> = ({
|
|
|
27
28
|
const [reason, setReason] = useState('');
|
|
28
29
|
const [evidence, setEvidence] = useState('');
|
|
29
30
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
31
|
+
const [successMessage, setSuccessMessage] = useState('');
|
|
30
32
|
|
|
31
33
|
const bloomTheme = useTheme();
|
|
32
34
|
|
|
35
|
+
// Prompt controls
|
|
36
|
+
const successPrompt = usePromptControl();
|
|
37
|
+
|
|
38
|
+
const handleSuccessAcknowledged = useCallback(() => {
|
|
39
|
+
setReason('');
|
|
40
|
+
setEvidence('');
|
|
41
|
+
goBack?.();
|
|
42
|
+
}, [goBack]);
|
|
43
|
+
|
|
33
44
|
const handleSubmit = useCallback(async () => {
|
|
34
45
|
if (!reason.trim()) {
|
|
35
46
|
toast.error(t('accountVerification.reasonRequired') || 'Please provide a reason for verification');
|
|
@@ -48,20 +59,10 @@ const AccountVerificationScreen: React.FC<BaseScreenProps> = ({
|
|
|
48
59
|
evidence.trim() || undefined
|
|
49
60
|
);
|
|
50
61
|
|
|
51
|
-
|
|
52
|
-
t('accountVerification.
|
|
53
|
-
t('accountVerification.successMessage') || `Your verification request has been submitted. Request ID: ${result.requestId}`,
|
|
54
|
-
[
|
|
55
|
-
{
|
|
56
|
-
text: t('accountVerification.ok') || 'OK',
|
|
57
|
-
onPress: () => {
|
|
58
|
-
setReason('');
|
|
59
|
-
setEvidence('');
|
|
60
|
-
goBack?.();
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
]
|
|
62
|
+
setSuccessMessage(
|
|
63
|
+
t('accountVerification.successMessage') || `Your verification request has been submitted. Request ID: ${result.requestId}`
|
|
64
64
|
);
|
|
65
|
+
successPrompt.open();
|
|
65
66
|
} catch (error: unknown) {
|
|
66
67
|
if (__DEV__) {
|
|
67
68
|
console.error('Failed to submit verification request:', error);
|
|
@@ -72,7 +73,7 @@ const AccountVerificationScreen: React.FC<BaseScreenProps> = ({
|
|
|
72
73
|
} finally {
|
|
73
74
|
setIsSubmitting(false);
|
|
74
75
|
}
|
|
75
|
-
}, [reason, evidence, oxyServices, t,
|
|
76
|
+
}, [reason, evidence, oxyServices, t, successPrompt]);
|
|
76
77
|
|
|
77
78
|
return (
|
|
78
79
|
<View style={[styles.container, { backgroundColor: bloomTheme.colors.background }]}>
|
|
@@ -158,6 +159,14 @@ const AccountVerificationScreen: React.FC<BaseScreenProps> = ({
|
|
|
158
159
|
</Text>
|
|
159
160
|
</Section>
|
|
160
161
|
</ScrollView>
|
|
162
|
+
<Prompt.Basic
|
|
163
|
+
control={successPrompt}
|
|
164
|
+
title={t('accountVerification.successTitle') || 'Request Submitted'}
|
|
165
|
+
description={successMessage}
|
|
166
|
+
onConfirm={handleSuccessAcknowledged}
|
|
167
|
+
confirmButtonCta={t('accountVerification.ok') || 'OK'}
|
|
168
|
+
showCancel={false}
|
|
169
|
+
/>
|
|
161
170
|
</View>
|
|
162
171
|
);
|
|
163
172
|
};
|
|
@@ -214,4 +223,3 @@ const styles = StyleSheet.create({
|
|
|
214
223
|
});
|
|
215
224
|
|
|
216
225
|
export default React.memo(AccountVerificationScreen);
|
|
217
|
-
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
Image,
|
|
12
12
|
Animated,
|
|
13
13
|
Easing,
|
|
14
|
-
Alert,
|
|
15
14
|
} from 'react-native';
|
|
16
15
|
import { Image as ExpoImage } from 'expo-image';
|
|
17
16
|
import type { FileManagementScreenProps } from '../types/fileManagement';
|
|
@@ -29,6 +28,8 @@ const loadDocumentPicker = async () => {
|
|
|
29
28
|
}
|
|
30
29
|
};
|
|
31
30
|
import { toast } from '../../lib/sonner';
|
|
31
|
+
import * as Prompt from '@oxyhq/bloom/prompt';
|
|
32
|
+
import { usePromptControl } from '@oxyhq/bloom/prompt';
|
|
32
33
|
import { Ionicons } from '@expo/vector-icons';
|
|
33
34
|
// @ts-ignore - MaterialCommunityIcons is available at runtime
|
|
34
35
|
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
|
@@ -42,7 +43,6 @@ import { useOxy } from '../context/OxyContext';
|
|
|
42
43
|
import { useI18n } from '../hooks/useI18n';
|
|
43
44
|
import { useUploadFile } from '../hooks/mutations/useAccountMutations';
|
|
44
45
|
import {
|
|
45
|
-
confirmAction,
|
|
46
46
|
convertDocumentPickerAssetToFile,
|
|
47
47
|
formatFileSize,
|
|
48
48
|
getFileIcon,
|
|
@@ -51,6 +51,7 @@ import {
|
|
|
51
51
|
import { FileViewer } from '../components/fileManagement/FileViewer';
|
|
52
52
|
import { FileDetailsModal } from '../components/fileManagement/FileDetailsModal';
|
|
53
53
|
import { UploadPreview } from '../components/fileManagement/UploadPreview';
|
|
54
|
+
import { useDialogControl } from '@oxyhq/bloom/dialog';
|
|
54
55
|
import { fileManagementStyles } from '../components/fileManagement/styles';
|
|
55
56
|
import type { OnConfirmFileSelection } from '../types/fileManagement';
|
|
56
57
|
|
|
@@ -133,6 +134,11 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
133
134
|
const { user, oxyServices } = useOxy();
|
|
134
135
|
const { t } = useI18n();
|
|
135
136
|
const uploadFileMutation = useUploadFile();
|
|
137
|
+
// Prompt controls
|
|
138
|
+
const fileDeletePrompt = usePromptControl();
|
|
139
|
+
const bulkDeletePrompt = usePromptControl();
|
|
140
|
+
const visibilityChangePrompt = usePromptControl();
|
|
141
|
+
const [pendingDeleteFile, setPendingDeleteFile] = useState<{ id: string; name: string } | null>(null);
|
|
136
142
|
const files = useFiles();
|
|
137
143
|
// Ensure containerWidth is a number (TypeScript guard)
|
|
138
144
|
const safeContainerWidth: number = typeof containerWidth === 'number' ? containerWidth : 400;
|
|
@@ -143,7 +149,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
143
149
|
const [refreshing, setRefreshing] = useState(false);
|
|
144
150
|
const [paging, setPaging] = useState({ offset: 0, limit: 40, total: 0, hasMore: true, loadingMore: false });
|
|
145
151
|
const [selectedFile, setSelectedFile] = useState<FileMetadata | null>(null);
|
|
146
|
-
const
|
|
152
|
+
const fileDetailsControl = useDialogControl();
|
|
147
153
|
// In selectMode we never open the detailed viewer
|
|
148
154
|
const [openedFile, setOpenedFile] = useState<FileMetadata | null>(null);
|
|
149
155
|
const [fileContent, setFileContent] = useState<string | null>(null);
|
|
@@ -889,18 +895,14 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
889
895
|
}
|
|
890
896
|
};
|
|
891
897
|
|
|
892
|
-
const
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
t('fileManagement.deleteFile'),
|
|
897
|
-
t('fileManagement.confirm'),
|
|
898
|
-
t('common.cancel')
|
|
899
|
-
);
|
|
898
|
+
const confirmFileDelete = useCallback((fileId: string, filename: string) => {
|
|
899
|
+
setPendingDeleteFile({ id: fileId, name: filename });
|
|
900
|
+
fileDeletePrompt.open();
|
|
901
|
+
}, [fileDeletePrompt]);
|
|
900
902
|
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
}
|
|
903
|
+
const handleFileDelete = useCallback(async () => {
|
|
904
|
+
if (!pendingDeleteFile) return;
|
|
905
|
+
const { id: fileId } = pendingDeleteFile;
|
|
904
906
|
|
|
905
907
|
try {
|
|
906
908
|
storeSetDeleting(fileId);
|
|
@@ -927,24 +929,17 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
927
929
|
}
|
|
928
930
|
} finally {
|
|
929
931
|
storeSetDeleting(null);
|
|
932
|
+
setPendingDeleteFile(null);
|
|
930
933
|
}
|
|
931
|
-
};
|
|
934
|
+
}, [pendingDeleteFile, storeSetDeleting, oxyServices, loadFiles, t]);
|
|
932
935
|
|
|
933
|
-
const
|
|
936
|
+
const confirmBulkDelete = useCallback(() => {
|
|
934
937
|
if (selectedIds.size === 0) return;
|
|
938
|
+
bulkDeletePrompt.open();
|
|
939
|
+
}, [selectedIds.size, bulkDeletePrompt]);
|
|
935
940
|
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
const selectedFiles = Array.from(selectedIds).map(id => fileMap[id]).filter(Boolean);
|
|
939
|
-
|
|
940
|
-
const confirmed = await confirmAction(
|
|
941
|
-
t('fileManagement.confirms.deleteFiles', { count: selectedFiles.length }),
|
|
942
|
-
t('fileManagement.deleteFiles'),
|
|
943
|
-
t('fileManagement.confirm'),
|
|
944
|
-
t('common.cancel')
|
|
945
|
-
);
|
|
946
|
-
|
|
947
|
-
if (!confirmed) return;
|
|
941
|
+
const handleBulkDelete = useCallback(async () => {
|
|
942
|
+
if (selectedIds.size === 0) return;
|
|
948
943
|
|
|
949
944
|
try {
|
|
950
945
|
const deletePromises = Array.from(selectedIds).map(async (fileId) => {
|
|
@@ -1119,7 +1114,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1119
1114
|
|
|
1120
1115
|
const showFileDetailsModal = (file: FileMetadata) => {
|
|
1121
1116
|
setSelectedFile(file);
|
|
1122
|
-
|
|
1117
|
+
fileDetailsControl.open();
|
|
1123
1118
|
};
|
|
1124
1119
|
|
|
1125
1120
|
const renderSimplePhotoItem = useCallback((photo: FileMetadata, index: number) => {
|
|
@@ -1350,9 +1345,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1350
1345
|
{/* Always show delete button for debugging */}
|
|
1351
1346
|
<TouchableOpacity
|
|
1352
1347
|
style={[fileManagementStyles.actionButton, { backgroundColor: bloomTheme.isDark ? '#400000' : '#FFEBEE' }]}
|
|
1353
|
-
onPress={() =>
|
|
1354
|
-
handleFileDelete(file.id, file.filename);
|
|
1355
|
-
}}
|
|
1348
|
+
onPress={() => confirmFileDelete(file.id, file.filename)}
|
|
1356
1349
|
disabled={deleting === file.id}
|
|
1357
1350
|
>
|
|
1358
1351
|
{deleting === file.id ? (
|
|
@@ -1480,7 +1473,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1480
1473
|
</TouchableOpacity>
|
|
1481
1474
|
<TouchableOpacity
|
|
1482
1475
|
style={[fileManagementStyles.groupedActionBtn, { backgroundColor: bloomTheme.isDark ? '#400000' : '#FFEBEE' }]}
|
|
1483
|
-
onPress={() =>
|
|
1476
|
+
onPress={() => confirmFileDelete(file.id, file.filename)}
|
|
1484
1477
|
disabled={deleting === file.id}
|
|
1485
1478
|
>
|
|
1486
1479
|
{deleting === file.id ? (
|
|
@@ -1498,7 +1491,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1498
1491
|
) : undefined,
|
|
1499
1492
|
};
|
|
1500
1493
|
});
|
|
1501
|
-
}, [filteredFiles, theme, deleting, handleFileDownload,
|
|
1494
|
+
}, [filteredFiles, theme, deleting, handleFileDownload, confirmFileDelete, handleFileOpen, getSafeDownloadUrlCallback, selectMode, selectedIds]);
|
|
1502
1495
|
|
|
1503
1496
|
// Scroll to selected file after selection
|
|
1504
1497
|
useEffect(() => {
|
|
@@ -1952,15 +1945,14 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1952
1945
|
onToggleDetails={() => setShowFileDetailsInViewer(!showFileDetailsInViewer)}
|
|
1953
1946
|
onClose={handleCloseFile}
|
|
1954
1947
|
onDownload={handleFileDownload}
|
|
1955
|
-
onDelete={
|
|
1948
|
+
onDelete={confirmFileDelete}
|
|
1956
1949
|
isOwner={user?.id === targetUserId}
|
|
1957
1950
|
/>
|
|
1958
1951
|
<FileDetailsModal
|
|
1959
|
-
|
|
1952
|
+
control={fileDetailsControl}
|
|
1960
1953
|
file={selectedFile}
|
|
1961
|
-
onClose={() => setShowFileDetails(false)}
|
|
1962
1954
|
onDownload={handleFileDownload}
|
|
1963
|
-
onDelete={
|
|
1955
|
+
onDelete={confirmFileDelete}
|
|
1964
1956
|
isOwner={user?.id === targetUserId}
|
|
1965
1957
|
/>
|
|
1966
1958
|
</>
|
|
@@ -1981,7 +1973,6 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1981
1973
|
titleAlignment="left"
|
|
1982
1974
|
/>
|
|
1983
1975
|
<UploadPreview
|
|
1984
|
-
visible={true}
|
|
1985
1976
|
pendingFiles={pendingFiles}
|
|
1986
1977
|
onConfirm={handleConfirmUpload}
|
|
1987
1978
|
onCancel={handleCancelUpload}
|
|
@@ -2019,24 +2010,14 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
2019
2010
|
{
|
|
2020
2011
|
key: 'delete',
|
|
2021
2012
|
text: t('fileManagement.delete', { count: selectedIds.size }),
|
|
2022
|
-
onPress:
|
|
2013
|
+
onPress: confirmBulkDelete,
|
|
2023
2014
|
icon: 'delete',
|
|
2024
2015
|
},
|
|
2025
2016
|
{
|
|
2026
2017
|
key: 'visibility',
|
|
2027
2018
|
text: t('fileManagement.visibility'),
|
|
2028
2019
|
onPress: () => {
|
|
2029
|
-
|
|
2030
|
-
Alert.alert(
|
|
2031
|
-
t('fileManagement.changeVisibility'),
|
|
2032
|
-
t('fileManagement.changeVisibilityConfirm', { count: selectedIds.size }),
|
|
2033
|
-
[
|
|
2034
|
-
{ text: t('common.cancel'), style: 'cancel' },
|
|
2035
|
-
{ text: t('fileManagement.private'), onPress: () => handleBulkVisibilityChange('private') },
|
|
2036
|
-
{ text: t('fileManagement.public'), onPress: () => handleBulkVisibilityChange('public') },
|
|
2037
|
-
{ text: t('fileManagement.unlisted'), onPress: () => handleBulkVisibilityChange('unlisted') },
|
|
2038
|
-
]
|
|
2039
|
-
);
|
|
2020
|
+
visibilityChangePrompt.open();
|
|
2040
2021
|
},
|
|
2041
2022
|
icon: 'eye',
|
|
2042
2023
|
}
|
|
@@ -2273,11 +2254,10 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
2273
2254
|
|
|
2274
2255
|
{!selectMode && (
|
|
2275
2256
|
<FileDetailsModal
|
|
2276
|
-
|
|
2257
|
+
control={fileDetailsControl}
|
|
2277
2258
|
file={selectedFile}
|
|
2278
|
-
onClose={() => setShowFileDetails(false)}
|
|
2279
2259
|
onDownload={handleFileDownload}
|
|
2280
|
-
onDelete={
|
|
2260
|
+
onDelete={confirmFileDelete}
|
|
2281
2261
|
isOwner={user?.id === targetUserId}
|
|
2282
2262
|
/>
|
|
2283
2263
|
)}
|
|
@@ -2312,6 +2292,34 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
2312
2292
|
|
|
2313
2293
|
{/* Selection bar removed; actions are now in header */}
|
|
2314
2294
|
{/* Global loadingMore bar removed; now inline in scroll areas */}
|
|
2295
|
+
<Prompt.Basic
|
|
2296
|
+
control={fileDeletePrompt}
|
|
2297
|
+
title={t('fileManagement.deleteFile') || 'Delete File'}
|
|
2298
|
+
description={pendingDeleteFile ? t('fileManagement.confirms.deleteFile', { filename: pendingDeleteFile.name }) : ''}
|
|
2299
|
+
onConfirm={handleFileDelete}
|
|
2300
|
+
confirmButtonCta={t('fileManagement.confirm') || 'Delete'}
|
|
2301
|
+
confirmButtonColor='negative'
|
|
2302
|
+
/>
|
|
2303
|
+
<Prompt.Basic
|
|
2304
|
+
control={bulkDeletePrompt}
|
|
2305
|
+
title={t('fileManagement.deleteFiles') || 'Delete Files'}
|
|
2306
|
+
description={t('fileManagement.confirms.deleteFiles', { count: selectedIds.size })}
|
|
2307
|
+
onConfirm={handleBulkDelete}
|
|
2308
|
+
confirmButtonCta={t('fileManagement.confirm') || 'Delete'}
|
|
2309
|
+
confirmButtonColor='negative'
|
|
2310
|
+
/>
|
|
2311
|
+
<Prompt.Outer control={visibilityChangePrompt}>
|
|
2312
|
+
<Prompt.Content>
|
|
2313
|
+
<Prompt.TitleText>{t('fileManagement.changeVisibility') || 'Change Visibility'}</Prompt.TitleText>
|
|
2314
|
+
<Prompt.DescriptionText>{t('fileManagement.changeVisibilityConfirm', { count: selectedIds.size })}</Prompt.DescriptionText>
|
|
2315
|
+
</Prompt.Content>
|
|
2316
|
+
<Prompt.Actions>
|
|
2317
|
+
<Prompt.Action cta={t('fileManagement.private') || 'Private'} onPress={() => handleBulkVisibilityChange('private')} color='primary' />
|
|
2318
|
+
<Prompt.Action cta={t('fileManagement.public') || 'Public'} onPress={() => handleBulkVisibilityChange('public')} color='primary_subtle' />
|
|
2319
|
+
<Prompt.Action cta={t('fileManagement.unlisted') || 'Unlisted'} onPress={() => handleBulkVisibilityChange('unlisted')} color='primary_subtle' />
|
|
2320
|
+
<Prompt.Cancel cta={t('common.cancel') || 'Cancel'} />
|
|
2321
|
+
</Prompt.Actions>
|
|
2322
|
+
</Prompt.Outer>
|
|
2315
2323
|
</View>
|
|
2316
2324
|
);
|
|
2317
2325
|
};
|