@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
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import React, { useState, useCallback } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
View,
|
|
4
|
-
StyleSheet,
|
|
5
|
-
ScrollView,
|
|
6
|
-
} from 'react-native';
|
|
2
|
+
import { View, StyleSheet, ScrollView } from 'react-native';
|
|
7
3
|
import type { BaseScreenProps } from '../types/navigation';
|
|
8
4
|
import { toast } from '../../lib/sonner';
|
|
9
|
-
import { confirmAction } from '../utils/confirmAction';
|
|
10
5
|
import { Header, Section, GroupedSection, LoadingState, EmptyState } from '../components';
|
|
11
6
|
import { useI18n } from '../hooks/useI18n';
|
|
12
7
|
import { useTheme } from '@oxyhq/bloom/theme';
|
|
@@ -14,20 +9,12 @@ import { useColorScheme } from '../hooks/useColorScheme';
|
|
|
14
9
|
import { Colors } from '../constants/theme';
|
|
15
10
|
import { normalizeColorScheme } from '../utils/themeUtils';
|
|
16
11
|
import { useOxy } from '../context/OxyContext';
|
|
12
|
+
import * as Prompt from '@oxyhq/bloom/prompt';
|
|
13
|
+
import { usePromptControl } from '@oxyhq/bloom/prompt';
|
|
17
14
|
|
|
18
|
-
interface HistoryItem {
|
|
19
|
-
id: string;
|
|
20
|
-
query: string;
|
|
21
|
-
type: 'search' | 'browse';
|
|
22
|
-
timestamp: Date;
|
|
23
|
-
}
|
|
15
|
+
interface HistoryItem { id: string; query: string; type: 'search' | 'browse'; timestamp: Date; }
|
|
24
16
|
|
|
25
|
-
const HistoryViewScreen: React.FC<BaseScreenProps> = ({
|
|
26
|
-
onClose,
|
|
27
|
-
theme,
|
|
28
|
-
goBack,
|
|
29
|
-
}) => {
|
|
30
|
-
// Use useOxy() hook for OxyContext values
|
|
17
|
+
const HistoryViewScreen: React.FC<BaseScreenProps> = ({ onClose, theme, goBack }) => {
|
|
31
18
|
const { user } = useOxy();
|
|
32
19
|
const { t } = useI18n();
|
|
33
20
|
const bloomTheme = useTheme();
|
|
@@ -37,227 +24,93 @@ const HistoryViewScreen: React.FC<BaseScreenProps> = ({
|
|
|
37
24
|
const [history, setHistory] = useState<HistoryItem[]>([]);
|
|
38
25
|
const [isLoading, setIsLoading] = useState(true);
|
|
39
26
|
const [isDeleting, setIsDeleting] = useState(false);
|
|
27
|
+
const deleteLast15Prompt = usePromptControl();
|
|
28
|
+
const clearAllPrompt = usePromptControl();
|
|
40
29
|
|
|
41
|
-
// Helper to get storage
|
|
42
30
|
const getStorage = async () => {
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
if (isReactNative) {
|
|
31
|
+
const isRN = typeof navigator !== 'undefined' && navigator.product === 'ReactNative';
|
|
32
|
+
if (isRN) {
|
|
46
33
|
try {
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
removeItem: (key: string) => Promise<void>;
|
|
52
|
-
};
|
|
53
|
-
return {
|
|
54
|
-
getItem: storage.getItem.bind(storage),
|
|
55
|
-
setItem: storage.setItem.bind(storage),
|
|
56
|
-
removeItem: storage.removeItem.bind(storage),
|
|
57
|
-
};
|
|
58
|
-
} catch (error) {
|
|
59
|
-
if (__DEV__) {
|
|
60
|
-
console.error('AsyncStorage not available:', error);
|
|
61
|
-
}
|
|
62
|
-
throw new Error('AsyncStorage is required in React Native environment');
|
|
63
|
-
}
|
|
64
|
-
} else {
|
|
65
|
-
// Use localStorage for web
|
|
66
|
-
return {
|
|
67
|
-
getItem: async (key: string) => {
|
|
68
|
-
if (typeof window !== 'undefined' && window.localStorage) {
|
|
69
|
-
return window.localStorage.getItem(key);
|
|
70
|
-
}
|
|
71
|
-
return null;
|
|
72
|
-
},
|
|
73
|
-
setItem: async (key: string, value: string) => {
|
|
74
|
-
if (typeof window !== 'undefined' && window.localStorage) {
|
|
75
|
-
window.localStorage.setItem(key, value);
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
removeItem: async (key: string) => {
|
|
79
|
-
if (typeof window !== 'undefined' && window.localStorage) {
|
|
80
|
-
window.localStorage.removeItem(key);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
};
|
|
34
|
+
const mod = await import('@react-native-async-storage/async-storage');
|
|
35
|
+
const s = mod.default as unknown as { getItem: (k: string) => Promise<string | null>; setItem: (k: string, v: string) => Promise<void>; removeItem: (k: string) => Promise<void> };
|
|
36
|
+
return { getItem: s.getItem.bind(s), setItem: s.setItem.bind(s), removeItem: s.removeItem.bind(s) };
|
|
37
|
+
} catch (e) { if (__DEV__) console.error('AsyncStorage not available:', e); throw new Error('AsyncStorage required'); }
|
|
84
38
|
}
|
|
39
|
+
return {
|
|
40
|
+
getItem: async (k: string) => typeof window !== 'undefined' && window.localStorage ? window.localStorage.getItem(k) : null,
|
|
41
|
+
setItem: async (k: string, v: string) => { if (typeof window !== 'undefined' && window.localStorage) window.localStorage.setItem(k, v); },
|
|
42
|
+
removeItem: async (k: string) => { if (typeof window !== 'undefined' && window.localStorage) window.localStorage.removeItem(k); },
|
|
43
|
+
};
|
|
85
44
|
};
|
|
86
45
|
|
|
87
|
-
// TODO: Integrate with backend API for history storage
|
|
88
|
-
// Currently uses local storage only. Should fetch from backend API and sync across devices.
|
|
89
|
-
// Load history from storage
|
|
90
46
|
React.useEffect(() => {
|
|
91
|
-
const
|
|
47
|
+
const load = async () => {
|
|
92
48
|
try {
|
|
93
49
|
setIsLoading(true);
|
|
94
50
|
const storage = await getStorage();
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const parsed = JSON.parse(stored);
|
|
100
|
-
setHistory(parsed.map((item: any) => ({
|
|
101
|
-
...item,
|
|
102
|
-
timestamp: new Date(item.timestamp),
|
|
103
|
-
})));
|
|
104
|
-
} else {
|
|
105
|
-
setHistory([]);
|
|
106
|
-
}
|
|
107
|
-
} catch (error) {
|
|
108
|
-
setHistory([]);
|
|
109
|
-
} finally {
|
|
110
|
-
setIsLoading(false);
|
|
111
|
-
}
|
|
51
|
+
const stored = await storage.getItem(`history_${user?.id || 'guest'}`);
|
|
52
|
+
if (stored) { const parsed = JSON.parse(stored); setHistory(parsed.map((i: HistoryItem) => ({ ...i, timestamp: new Date(i.timestamp) }))); }
|
|
53
|
+
else setHistory([]);
|
|
54
|
+
} catch { setHistory([]); } finally { setIsLoading(false); }
|
|
112
55
|
};
|
|
113
|
-
|
|
114
|
-
loadHistory();
|
|
56
|
+
load();
|
|
115
57
|
}, [user?.id]);
|
|
116
58
|
|
|
117
59
|
const handleDeleteLast15Minutes = useCallback(async () => {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
// Save to storage
|
|
129
|
-
const storage = await getStorage();
|
|
130
|
-
const historyKey = `history_${user?.id || 'guest'}`;
|
|
131
|
-
await storage.setItem(historyKey, JSON.stringify(filtered));
|
|
132
|
-
|
|
133
|
-
toast.success(t('history.deleteLast15Minutes.success') || 'Last 15 minutes deleted');
|
|
134
|
-
} catch (error) {
|
|
135
|
-
if (__DEV__) {
|
|
136
|
-
console.error('Failed to delete history:', error);
|
|
137
|
-
}
|
|
138
|
-
toast.error(t('history.deleteLast15Minutes.error') || 'Failed to delete history');
|
|
139
|
-
} finally {
|
|
140
|
-
setIsDeleting(false);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
);
|
|
60
|
+
try {
|
|
61
|
+
setIsDeleting(true);
|
|
62
|
+
const cutoff = new Date(Date.now() - 15 * 60 * 1000);
|
|
63
|
+
const filtered = history.filter(item => item.timestamp < cutoff);
|
|
64
|
+
setHistory(filtered);
|
|
65
|
+
const storage = await getStorage();
|
|
66
|
+
await storage.setItem(`history_${user?.id || 'guest'}`, JSON.stringify(filtered));
|
|
67
|
+
toast.success(t('history.deleteLast15Minutes.success') || 'Last 15 minutes deleted');
|
|
68
|
+
} catch (e) { if (__DEV__) console.error('Failed to delete history:', e); toast.error(t('history.deleteLast15Minutes.error') || 'Failed to delete history'); }
|
|
69
|
+
finally { setIsDeleting(false); }
|
|
144
70
|
}, [history, user?.id, t]);
|
|
145
71
|
|
|
146
72
|
const handleClearAll = useCallback(async () => {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
// Clear from storage
|
|
155
|
-
const storage = await getStorage();
|
|
156
|
-
const historyKey = `history_${user?.id || 'guest'}`;
|
|
157
|
-
await storage.removeItem(historyKey);
|
|
158
|
-
|
|
159
|
-
toast.success(t('history.clearAll.success') || 'History cleared');
|
|
160
|
-
} catch (error) {
|
|
161
|
-
if (__DEV__) {
|
|
162
|
-
console.error('Failed to clear history:', error);
|
|
163
|
-
}
|
|
164
|
-
toast.error(t('history.clearAll.error') || 'Failed to clear history');
|
|
165
|
-
} finally {
|
|
166
|
-
setIsDeleting(false);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
);
|
|
73
|
+
try {
|
|
74
|
+
setIsDeleting(true); setHistory([]);
|
|
75
|
+
const storage = await getStorage();
|
|
76
|
+
await storage.removeItem(`history_${user?.id || 'guest'}`);
|
|
77
|
+
toast.success(t('history.clearAll.success') || 'History cleared');
|
|
78
|
+
} catch (e) { if (__DEV__) console.error('Failed to clear history:', e); toast.error(t('history.clearAll.error') || 'Failed to clear history'); }
|
|
79
|
+
finally { setIsDeleting(false); }
|
|
170
80
|
}, [user?.id, t]);
|
|
171
81
|
|
|
172
82
|
const formatTime = (date: Date) => {
|
|
173
|
-
const
|
|
174
|
-
const diff =
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
if (minutes < 1) return t('history.justNow') || 'Just now';
|
|
180
|
-
if (minutes < 60) return `${minutes} ${t('history.minutesAgo') || 'minutes ago'}`;
|
|
181
|
-
if (hours < 24) return `${hours} ${t('history.hoursAgo') || 'hours ago'}`;
|
|
83
|
+
const diff = new Date().getTime() - date.getTime();
|
|
84
|
+
const min = Math.floor(diff / 60000); const hrs = Math.floor(min / 60); const days = Math.floor(hrs / 24);
|
|
85
|
+
if (min < 1) return t('history.justNow') || 'Just now';
|
|
86
|
+
if (min < 60) return `${min} ${t('history.minutesAgo') || 'minutes ago'}`;
|
|
87
|
+
if (hrs < 24) return `${hrs} ${t('history.hoursAgo') || 'hours ago'}`;
|
|
182
88
|
if (days < 7) return `${days} ${t('history.daysAgo') || 'days ago'}`;
|
|
183
89
|
return date.toLocaleDateString();
|
|
184
90
|
};
|
|
185
91
|
|
|
186
92
|
return (
|
|
187
93
|
<View style={[styles.container, { backgroundColor: bloomTheme.colors.background }]}>
|
|
188
|
-
<Header
|
|
189
|
-
title={t('history.title') || 'History'}
|
|
190
|
-
onBack={goBack || onClose}
|
|
191
|
-
variant="minimal"
|
|
192
|
-
elevation="subtle"
|
|
193
|
-
/>
|
|
194
|
-
|
|
94
|
+
<Header title={t('history.title') || 'History'} onBack={goBack || onClose} variant="minimal" elevation="subtle" />
|
|
195
95
|
<ScrollView style={styles.content}>
|
|
196
|
-
{/* Actions */}
|
|
197
96
|
<Section title={t('history.actions') || 'Actions'} isFirst={true}>
|
|
198
|
-
<GroupedSection
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
icon: 'clock-outline',
|
|
203
|
-
iconColor: themeColors.iconStorage,
|
|
204
|
-
title: t('history.deleteLast15Minutes.title') || 'Delete Last 15 Minutes',
|
|
205
|
-
subtitle: t('history.deleteLast15Minutes.subtitle') || 'Remove recent history entries',
|
|
206
|
-
onPress: handleDeleteLast15Minutes,
|
|
207
|
-
disabled: isDeleting || history.length === 0,
|
|
208
|
-
},
|
|
209
|
-
{
|
|
210
|
-
id: 'clear-all',
|
|
211
|
-
icon: 'delete-outline',
|
|
212
|
-
iconColor: themeColors.iconSharing,
|
|
213
|
-
title: t('history.clearAll.title') || 'Clear All History',
|
|
214
|
-
subtitle: t('history.clearAll.subtitle') || 'Remove all history entries',
|
|
215
|
-
onPress: handleClearAll,
|
|
216
|
-
disabled: isDeleting || history.length === 0,
|
|
217
|
-
},
|
|
218
|
-
]}
|
|
219
|
-
|
|
220
|
-
/>
|
|
97
|
+
<GroupedSection items={[
|
|
98
|
+
{ id: 'delete-last-15', icon: 'clock-outline', iconColor: themeColors.iconStorage, title: t('history.deleteLast15Minutes.title') || 'Delete Last 15 Minutes', subtitle: t('history.deleteLast15Minutes.subtitle') || 'Remove recent history entries', onPress: () => deleteLast15Prompt.open(), disabled: isDeleting || history.length === 0 },
|
|
99
|
+
{ id: 'clear-all', icon: 'delete-outline', iconColor: themeColors.iconSharing, title: t('history.clearAll.title') || 'Clear All History', subtitle: t('history.clearAll.subtitle') || 'Remove all history entries', onPress: () => clearAllPrompt.open(), disabled: isDeleting || history.length === 0 },
|
|
100
|
+
]} />
|
|
221
101
|
</Section>
|
|
222
|
-
|
|
223
|
-
{/* History List */}
|
|
224
102
|
<Section title={t('history.recent') || 'Recent History'}>
|
|
225
|
-
{isLoading ? (
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
color={bloomTheme.colors.text}
|
|
229
|
-
/>
|
|
230
|
-
) : history.length === 0 ? (
|
|
231
|
-
<EmptyState
|
|
232
|
-
message={t('history.empty') || 'No history yet'}
|
|
233
|
-
textColor={bloomTheme.colors.text}
|
|
234
|
-
/>
|
|
235
|
-
) : (
|
|
236
|
-
<GroupedSection
|
|
237
|
-
items={history.map((item) => ({
|
|
238
|
-
id: item.id,
|
|
239
|
-
icon: item.type === 'search' ? 'search' : 'globe',
|
|
240
|
-
iconColor: item.type === 'search' ? themeColors.iconSecurity : themeColors.iconPersonalInfo,
|
|
241
|
-
title: item.query,
|
|
242
|
-
subtitle: formatTime(item.timestamp),
|
|
243
|
-
}))}
|
|
244
|
-
/>
|
|
245
|
-
)}
|
|
103
|
+
{isLoading ? <LoadingState message={t('history.loading') || 'Loading history...'} color={bloomTheme.colors.text} />
|
|
104
|
+
: history.length === 0 ? <EmptyState message={t('history.empty') || 'No history yet'} textColor={bloomTheme.colors.text} />
|
|
105
|
+
: <GroupedSection items={history.map(item => ({ id: item.id, icon: item.type === 'search' ? 'search' : 'globe', iconColor: item.type === 'search' ? themeColors.iconSecurity : themeColors.iconPersonalInfo, title: item.query, subtitle: formatTime(item.timestamp) }))} />}
|
|
246
106
|
</Section>
|
|
247
107
|
</ScrollView>
|
|
108
|
+
<Prompt.Basic control={deleteLast15Prompt} title={t('history.deleteLast15Minutes.title') || 'Delete Last 15 Minutes'} description={t('history.deleteLast15Minutes.confirm') || 'Delete last 15 minutes of history?'} onConfirm={handleDeleteLast15Minutes} confirmButtonCta={t('common.actions.delete') || 'Delete'} confirmButtonColor="negative" />
|
|
109
|
+
<Prompt.Basic control={clearAllPrompt} title={t('history.clearAll.title') || 'Clear All History'} description={t('history.clearAll.confirm') || 'Clear all history? This cannot be undone.'} onConfirm={handleClearAll} confirmButtonCta={t('history.clearAll.title') || 'Clear All'} confirmButtonColor="negative" />
|
|
248
110
|
</View>
|
|
249
111
|
);
|
|
250
112
|
};
|
|
251
113
|
|
|
252
|
-
const styles = StyleSheet.create({
|
|
253
|
-
container: {
|
|
254
|
-
flex: 1,
|
|
255
|
-
},
|
|
256
|
-
content: {
|
|
257
|
-
flex: 1,
|
|
258
|
-
padding: 16,
|
|
259
|
-
},
|
|
260
|
-
});
|
|
114
|
+
const styles = StyleSheet.create({ container: { flex: 1 }, content: { flex: 1, padding: 16 } });
|
|
261
115
|
|
|
262
116
|
export default React.memo(HistoryViewScreen);
|
|
263
|
-
|