@oxyhq/services
Version:
224 lines (219 loc) • 9.27 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = _interopRequireWildcard(require("react"));
var _reactNative = require("react-native");
var _sonner = require("../../lib/sonner");
var _confirmAction = require("../utils/confirmAction.js");
var _index = require("../components/index.js");
var _useI18n = require("../hooks/useI18n.js");
var _useThemeStyles = require("../hooks/useThemeStyles.js");
var _useColorScheme = require("../hooks/useColorScheme.js");
var _OxyContext = require("../context/OxyContext.js");
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
const HistoryViewScreen = ({
onClose,
theme,
goBack
}) => {
// Use useOxy() hook for OxyContext values
const {
user
} = (0, _OxyContext.useOxy)();
const {
t
} = (0, _useI18n.useI18n)();
const colorScheme = (0, _useColorScheme.useColorScheme)();
const themeStyles = (0, _useThemeStyles.useThemeStyles)(theme || 'light', colorScheme);
const [history, setHistory] = (0, _react.useState)([]);
const [isLoading, setIsLoading] = (0, _react.useState)(true);
const [isDeleting, setIsDeleting] = (0, _react.useState)(false);
// Helper to get storage
const getStorage = async () => {
const isReactNative = typeof navigator !== 'undefined' && navigator.product === 'ReactNative';
if (isReactNative) {
try {
const asyncStorageModule = await Promise.resolve().then(() => _interopRequireWildcard(require('@react-native-async-storage/async-storage')));
const storage = asyncStorageModule.default;
return {
getItem: storage.getItem.bind(storage),
setItem: storage.setItem.bind(storage),
removeItem: storage.removeItem.bind(storage)
};
} catch (error) {
if (__DEV__) {
console.error('AsyncStorage not available:', error);
}
throw new Error('AsyncStorage is required in React Native environment');
}
} else {
// Use localStorage for web
return {
getItem: async key => {
if (typeof window !== 'undefined' && window.localStorage) {
return window.localStorage.getItem(key);
}
return null;
},
setItem: async (key, value) => {
if (typeof window !== 'undefined' && window.localStorage) {
window.localStorage.setItem(key, value);
}
},
removeItem: async key => {
if (typeof window !== 'undefined' && window.localStorage) {
window.localStorage.removeItem(key);
}
}
};
}
};
// TODO: Integrate with backend API for history storage
// Currently uses local storage only. Should fetch from backend API and sync across devices.
// Load history from storage
_react.default.useEffect(() => {
const loadHistory = async () => {
try {
setIsLoading(true);
const storage = await getStorage();
const historyKey = `history_${user?.id || 'guest'}`;
const stored = await storage.getItem(historyKey);
if (stored) {
const parsed = JSON.parse(stored);
setHistory(parsed.map(item => ({
...item,
timestamp: new Date(item.timestamp)
})));
} else {
setHistory([]);
}
} catch (error) {
setHistory([]);
} finally {
setIsLoading(false);
}
};
loadHistory();
}, [user?.id]);
const handleDeleteLast15Minutes = (0, _react.useCallback)(async () => {
(0, _confirmAction.confirmAction)(t('history.deleteLast15Minutes.confirm') || 'Delete last 15 minutes of history?', async () => {
try {
setIsDeleting(true);
const fifteenMinutesAgo = new Date(Date.now() - 15 * 60 * 1000);
const filtered = history.filter(item => item.timestamp < fifteenMinutesAgo);
setHistory(filtered);
// Save to storage
const storage = await getStorage();
const historyKey = `history_${user?.id || 'guest'}`;
await storage.setItem(historyKey, JSON.stringify(filtered));
_sonner.toast.success(t('history.deleteLast15Minutes.success') || 'Last 15 minutes deleted');
} catch (error) {
if (__DEV__) {
console.error('Failed to delete history:', error);
}
_sonner.toast.error(t('history.deleteLast15Minutes.error') || 'Failed to delete history');
} finally {
setIsDeleting(false);
}
});
}, [history, user?.id, t]);
const handleClearAll = (0, _react.useCallback)(async () => {
(0, _confirmAction.confirmAction)(t('history.clearAll.confirm') || 'Clear all history? This cannot be undone.', async () => {
try {
setIsDeleting(true);
setHistory([]);
// Clear from storage
const storage = await getStorage();
const historyKey = `history_${user?.id || 'guest'}`;
await storage.removeItem(historyKey);
_sonner.toast.success(t('history.clearAll.success') || 'History cleared');
} catch (error) {
if (__DEV__) {
console.error('Failed to clear history:', error);
}
_sonner.toast.error(t('history.clearAll.error') || 'Failed to clear history');
} finally {
setIsDeleting(false);
}
});
}, [user?.id, t]);
const formatTime = date => {
const now = new Date();
const diff = now.getTime() - date.getTime();
const minutes = Math.floor(diff / 60000);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
if (minutes < 1) return t('history.justNow') || 'Just now';
if (minutes < 60) return `${minutes} ${t('history.minutesAgo') || 'minutes ago'}`;
if (hours < 24) return `${hours} ${t('history.hoursAgo') || 'hours ago'}`;
if (days < 7) return `${days} ${t('history.daysAgo') || 'days ago'}`;
return date.toLocaleDateString();
};
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: [styles.container, {
backgroundColor: themeStyles.backgroundColor
}],
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_index.Header, {
title: t('history.title') || 'History',
onBack: goBack || onClose,
variant: "minimal",
elevation: "subtle"
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
style: styles.content,
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_index.Section, {
title: t('history.actions') || 'Actions',
isFirst: true,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.GroupedSection, {
items: [{
id: 'delete-last-15',
icon: 'clock-outline',
iconColor: themeStyles.colors.iconStorage,
title: t('history.deleteLast15Minutes.title') || 'Delete Last 15 Minutes',
subtitle: t('history.deleteLast15Minutes.subtitle') || 'Remove recent history entries',
onPress: handleDeleteLast15Minutes,
disabled: isDeleting || history.length === 0
}, {
id: 'clear-all',
icon: 'delete-outline',
iconColor: themeStyles.colors.iconSharing,
title: t('history.clearAll.title') || 'Clear All History',
subtitle: t('history.clearAll.subtitle') || 'Remove all history entries',
onPress: handleClearAll,
disabled: isDeleting || history.length === 0
}]
})
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.Section, {
title: t('history.recent') || 'Recent History',
children: isLoading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.LoadingState, {
message: t('history.loading') || 'Loading history...',
color: themeStyles.textColor
}) : history.length === 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.EmptyState, {
message: t('history.empty') || 'No history yet',
textColor: themeStyles.textColor
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.GroupedSection, {
items: history.map(item => ({
id: item.id,
icon: item.type === 'search' ? 'search' : 'globe',
iconColor: item.type === 'search' ? themeStyles.colors.iconSecurity : themeStyles.colors.iconPersonalInfo,
title: item.query,
subtitle: formatTime(item.timestamp)
}))
})
})]
})]
});
};
const styles = _reactNative.StyleSheet.create({
container: {
flex: 1
},
content: {
flex: 1,
padding: 16
}
});
var _default = exports.default = /*#__PURE__*/_react.default.memo(HistoryViewScreen);
//# sourceMappingURL=HistoryViewScreen.js.map