mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-30 23:14:37 +00:00
i18n: full UI coverage across 10 languages (#1986)
This commit is contained in:
@@ -4,6 +4,7 @@ import {
|
||||
type ScreenIntelligenceState,
|
||||
useScreenIntelligenceState,
|
||||
} from '../../features/screen-intelligence/useScreenIntelligenceState';
|
||||
import { useT } from '../../lib/i18n/I18nContext';
|
||||
|
||||
const formatBytes = (bytes: number | null | undefined): string => {
|
||||
if (bytes == null) return '-';
|
||||
@@ -29,6 +30,7 @@ interface ScreenIntelligenceDebugPanelProps {
|
||||
const ScreenIntelligenceDebugPanelContent = ({
|
||||
state: providedState,
|
||||
}: Required<Pick<ScreenIntelligenceDebugPanelProps, 'state'>>) => {
|
||||
const { t } = useT();
|
||||
const {
|
||||
status,
|
||||
captureTestResult,
|
||||
@@ -55,55 +57,70 @@ const ScreenIntelligenceDebugPanelContent = ({
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<h3 className="text-sm font-semibold text-stone-100">Debug & Diagnostics</h3>
|
||||
<h3 className="text-sm font-semibold text-stone-100">
|
||||
{t('intelligence.screenDebug.title')}
|
||||
</h3>
|
||||
<button
|
||||
onClick={handleRefreshStatus}
|
||||
className="rounded-lg border border-stone-700 bg-stone-800/60 px-3 py-1 text-xs text-stone-300 transition-colors hover:bg-stone-700/60">
|
||||
Refresh
|
||||
{t('common.refresh')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Permissions */}
|
||||
<div className="rounded-xl border border-stone-700 bg-stone-900/50 p-3">
|
||||
<h4 className="mb-2 text-xs font-medium uppercase tracking-wide text-stone-400">
|
||||
Permissions
|
||||
{t('intelligence.screenDebug.permissions')}
|
||||
</h4>
|
||||
{status?.platform_supported === false ? (
|
||||
<p className="text-xs text-stone-500">Platform not supported</p>
|
||||
<p className="text-xs text-stone-500">
|
||||
{t('intelligence.screenDebug.platformNotSupported')}
|
||||
</p>
|
||||
) : (
|
||||
<div className="grid grid-cols-3 gap-2 text-xs">
|
||||
<PermissionDot label="Screen" value={permissions?.screen_recording} />
|
||||
<PermissionDot label="Accessibility" value={permissions?.accessibility} />
|
||||
<PermissionDot label="Input" value={permissions?.input_monitoring} />
|
||||
<PermissionDot
|
||||
label={t('intelligence.screenDebug.permScreen')}
|
||||
value={permissions?.screen_recording}
|
||||
/>
|
||||
<PermissionDot
|
||||
label={t('intelligence.screenDebug.permAccessibility')}
|
||||
value={permissions?.accessibility}
|
||||
/>
|
||||
<PermissionDot
|
||||
label={t('intelligence.screenDebug.permInput')}
|
||||
value={permissions?.input_monitoring}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Session Status */}
|
||||
<div className="rounded-xl border border-stone-700 bg-stone-900/50 p-3">
|
||||
<h4 className="mb-2 text-xs font-medium uppercase tracking-wide text-stone-400">Session</h4>
|
||||
<h4 className="mb-2 text-xs font-medium uppercase tracking-wide text-stone-400">
|
||||
{t('intelligence.screenDebug.session')}
|
||||
</h4>
|
||||
<div className="space-y-1 text-xs text-stone-300">
|
||||
<div className="flex justify-between">
|
||||
<span>Active</span>
|
||||
<span>{t('intelligence.screenDebug.active')}</span>
|
||||
<span className={session?.active ? 'text-green-400' : 'text-stone-500'}>
|
||||
{session?.active ? 'Yes' : 'No'}
|
||||
{session?.active ? t('common.yes') : t('common.no')}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span>Frames</span>
|
||||
<span>{t('intelligence.screenDebug.frames')}</span>
|
||||
<span>{session?.frames_in_memory ?? 0}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span>Vision State</span>
|
||||
<span>{session?.vision_state ?? 'idle'}</span>
|
||||
<span>{t('intelligence.screenDebug.visionState')}</span>
|
||||
<span>{session?.vision_state ?? t('intelligence.screenDebug.idle')}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span>Vision Queue</span>
|
||||
<span>{t('intelligence.screenDebug.visionQueue')}</span>
|
||||
<span>{session?.vision_queue_depth ?? 0}</span>
|
||||
</div>
|
||||
{session?.last_context && (
|
||||
<div className="flex justify-between">
|
||||
<span>Last App</span>
|
||||
<span>{t('intelligence.screenDebug.lastApp')}</span>
|
||||
<span className="max-w-[180px] truncate">{session.last_context}</span>
|
||||
</div>
|
||||
)}
|
||||
@@ -113,49 +130,53 @@ const ScreenIntelligenceDebugPanelContent = ({
|
||||
{/* Capture Test */}
|
||||
<div className="rounded-xl border border-stone-700 bg-stone-900/50 p-3">
|
||||
<h4 className="mb-2 text-xs font-medium uppercase tracking-wide text-stone-400">
|
||||
Capture Test
|
||||
{t('intelligence.screenDebug.captureTest')}
|
||||
</h4>
|
||||
<button
|
||||
onClick={handleCaptureTest}
|
||||
disabled={isCaptureTestRunning}
|
||||
className="mb-3 w-full rounded-lg border border-primary-600/40 bg-primary-600/20 px-3 py-2 text-sm font-medium text-primary-300 transition-colors hover:bg-primary-600/30 disabled:opacity-50">
|
||||
{isCaptureTestRunning ? 'Capturing...' : 'Test Capture'}
|
||||
{isCaptureTestRunning
|
||||
? t('intelligence.screenDebug.capturing')
|
||||
: t('intelligence.screenDebug.testCapture')}
|
||||
</button>
|
||||
|
||||
{captureTestResult && (
|
||||
<div className="space-y-2">
|
||||
<div className="space-y-1 text-xs text-stone-300">
|
||||
<div className="flex justify-between">
|
||||
<span>Status</span>
|
||||
<span>{t('intelligence.screenDebug.status')}</span>
|
||||
<span className={captureTestResult.ok ? 'text-green-400' : 'text-red-400'}>
|
||||
{captureTestResult.ok ? 'Success' : 'Failed'}
|
||||
{captureTestResult.ok
|
||||
? t('intelligence.screenDebug.captureSuccess')
|
||||
: t('intelligence.screenDebug.captureFailed')}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span>Mode</span>
|
||||
<span>{t('intelligence.screenDebug.mode')}</span>
|
||||
<span>{captureTestResult.capture_mode}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span>Time</span>
|
||||
<span>{t('intelligence.screenDebug.time')}</span>
|
||||
<span>{captureTestResult.timing_ms}ms</span>
|
||||
</div>
|
||||
{captureTestResult.bytes_estimate != null && (
|
||||
<div className="flex justify-between">
|
||||
<span>Size</span>
|
||||
<span>{t('intelligence.screenDebug.size')}</span>
|
||||
<span>{formatBytes(captureTestResult.bytes_estimate)}</span>
|
||||
</div>
|
||||
)}
|
||||
{captureTestResult.context && (
|
||||
<div className="flex justify-between">
|
||||
<span>App</span>
|
||||
<span>{t('intelligence.screenDebug.app')}</span>
|
||||
<span className="max-w-[180px] truncate">
|
||||
{captureTestResult.context.app_name ?? 'Unknown'}
|
||||
{captureTestResult.context.app_name ?? t('intelligence.screenDebug.unknown')}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{captureTestResult.context?.bounds_width != null && (
|
||||
<div className="flex justify-between">
|
||||
<span>Bounds</span>
|
||||
<span>{t('intelligence.screenDebug.bounds')}</span>
|
||||
<span>
|
||||
{captureTestResult.context.bounds_width}x
|
||||
{captureTestResult.context.bounds_height} at (
|
||||
@@ -175,7 +196,7 @@ const ScreenIntelligenceDebugPanelContent = ({
|
||||
<div className="overflow-hidden rounded-lg border border-stone-700">
|
||||
<img
|
||||
src={captureTestResult.image_ref}
|
||||
alt="Capture test result"
|
||||
alt={t('intelligence.screenDebug.captureAlt')}
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
@@ -188,7 +209,7 @@ const ScreenIntelligenceDebugPanelContent = ({
|
||||
{recentVisionSummaries.length > 0 && (
|
||||
<div className="rounded-xl border border-stone-700 bg-stone-900/50 p-3">
|
||||
<h4 className="mb-2 text-xs font-medium uppercase tracking-wide text-stone-400">
|
||||
Recent Vision Summaries
|
||||
{t('intelligence.screenDebug.recentVisionSummaries')}
|
||||
</h4>
|
||||
<div className="space-y-2">
|
||||
{recentVisionSummaries.map(summary => (
|
||||
@@ -196,7 +217,7 @@ const ScreenIntelligenceDebugPanelContent = ({
|
||||
key={summary.id}
|
||||
className="rounded-lg border border-stone-700/50 bg-stone-800/30 p-2 text-xs">
|
||||
<div className="flex justify-between text-stone-400">
|
||||
<span>{summary.app_name ?? 'Unknown'}</span>
|
||||
<span>{summary.app_name ?? t('intelligence.screenDebug.unknown')}</span>
|
||||
<span>
|
||||
{new Date(summary.captured_at_ms).toLocaleTimeString()} ·{' '}
|
||||
{(summary.confidence * 100).toFixed(0)}%
|
||||
|
||||
Reference in New Issue
Block a user