{decision.title}
+{decision.detail}
} + {ruling ? ( ++ {t('activity.decision.ruled', { by: ruling.by, value: ruling.value })} +
+ ) : ( +{error}
} +{composerError || sendError}
} + {warnings.length > 0 && ( +{decision.detail}
} + {ruling ? ( ++ {t('activity.decision.ruled', { by: ruling.by, value: ruling.value })} +
+ ) : ( +{error}
} +{t('inspector.workspace.noAgents')}
} diff --git a/frontend/src/v2/components/V2InviteModal.tsx b/frontend/src/v2/components/V2InviteModal.tsx index 803d85afa..8a8697068 100644 --- a/frontend/src/v2/components/V2InviteModal.tsx +++ b/frontend/src/v2/components/V2InviteModal.tsx @@ -1,5 +1,5 @@ // V2InviteModal — shared invite UI mounted at V2Layout level so both the -// chat header invite icon (V2PodChat) and the inspector "+ Invite" button +// thread starter invite action (V2Thread) and the inspector "+ Invite" button // can open the same modal. Two tabs: shareable links (people) and an agent // install shortcut (browse → install). import React, { useState, useEffect, useCallback } from 'react'; diff --git a/frontend/src/v2/components/V2Layout.tsx b/frontend/src/v2/components/V2Layout.tsx index 413dc6b05..9f5ff7019 100644 --- a/frontend/src/v2/components/V2Layout.tsx +++ b/frontend/src/v2/components/V2Layout.tsx @@ -3,12 +3,14 @@ import { useNavigate, useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import V2NavRail from './V2NavRail'; import V2PodsSidebar from './V2PodsSidebar'; -import V2PodChat from './V2PodChat'; +import V2Thread from './V2Thread'; import V2Inspector from './V2Inspector'; import V2InviteModal, { type V2InviteTab } from './V2InviteModal'; import V2FirstRunHero from './V2FirstRunHero'; +import V2MobileTabs from './V2MobileTabs'; import { useV2Pods } from '../hooks/useV2Pods'; import { useV2PodDetail } from '../hooks/useV2PodDetail'; +import { useV2PodAttention } from '../hooks/useV2PodAttention'; import { getSignedAttachmentUrl } from '../../utils/signedAttachmentUrl'; import { useAuth } from '../../context/AuthContext'; @@ -19,6 +21,11 @@ interface V2LayoutProps { const INSPECTOR_PREF_KEY = 'v2.inspectorCollapsed'; const LAST_POD_KEY = 'v2:lastPodId'; const INVITE_BLOCKED_POD_TYPES = new Set(['agent-room', 'agent-dm']); +const PHONE_MEDIA_QUERY = '(max-width: 760px)'; + +const isPhoneViewport = (): boolean => ( + typeof window !== 'undefined' && !!window.matchMedia?.(PHONE_MEDIA_QUERY).matches +); const readInspectorCollapsed = (): boolean => { try { @@ -69,8 +76,15 @@ const V2Layout: React.FC