revert the chat tabs and panes work, back to one conversation
Andre asked for zero, not another fix on top. Reverts ec4f06a..7726c9f — the ten commits from "tabs and panes" onward: the tab bar and pane splitting, tab renaming and its page title, the per-server directory picker, the render-loop fix, pane transcript resolution, the send queue, the two socket fixes from the other session, the pane-socket notes, and my own socket-set change from tonight. He is rebuilding from here. Deliberately KEPT:dc6b623, "talk to two officers at once from one browser". That was a separate ask that predates the tabs one, and the multi-server client, the server chips and the connections store stand on their own without panes. Reverting it too is one more command if that was the intent. Collateral, worth naming:cb7ab55carried an unrelated MusicPlayerHost change alongside its socket instrumentation, so that came out with it. Reverts, not a reset — every one of these is pushed and a second session is live in this repo. Typecheck clean. 600 pass, 2 fail — cliamp path-escape and the pty transport test, both failing identically before this and unrelated to chat. What is NOT explained by this revert: the browser symptoms tonight. The server was verified good throughout — two real turns streamed back through the public URL on both models, and the full 2,281-message history came through nginx intact. Whatever the client fault is, it is still unfound, and the pre-tabs code is where it now has to be looked for. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,12 +1,15 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { useParams, useNavigate } from 'react-router';
|
||||
import type { SelectedSession } from 'officerdev';
|
||||
import { ChatTabs, chatListPath, cwdFromSplat, useSelectedChatSession } from 'officerdev';
|
||||
import type { LayoutNode, SelectedSession } from 'officerdev';
|
||||
import { WorkspaceView, chatListPath, cwdFromSplat, useSelectedChatSession } from 'officerdev';
|
||||
import { toast } from '@/components/ui/sonner';
|
||||
import { useIsMobile } from 'hooks/useIsMobile';
|
||||
import { useClient } from 'hooks/useClient';
|
||||
import { serverClient } from 'hooks/useServerClient';
|
||||
import { errorText } from 'helpers/error-text';
|
||||
import { useDashboardState } from 'state/useDashboardState';
|
||||
import type { ClaudeSessionDetail } from 'state/useClaudeSessions';
|
||||
import { defaultLayout, hasAppType } from './defaultLayout';
|
||||
|
||||
// How many messages to render on first open (anchored to the bottom); scroll-up pages older ones in.
|
||||
const CHAT_TAIL = 20;
|
||||
@@ -25,7 +28,26 @@ export const SessionListPage = ({ isNew }: SessionListPageProps) => {
|
||||
selectedRef.current = selected;
|
||||
// A layout persisted before the chat panels were renamed still names `officerdev/chat`, which no
|
||||
// longer resolves; `appTypes` lands anything unknown on the detail panel.
|
||||
const workspace = useDashboardState<LayoutNode>('screens/chat', defaultLayout);
|
||||
const isMobile = useIsMobile();
|
||||
const navigate = useNavigate();
|
||||
const mobilePanelId = isMobile && (sessionId || isNew) ? 'chat-detail' : undefined;
|
||||
|
||||
// Adopt a structural change to this screen's layout.
|
||||
//
|
||||
// `useDashboardState` seeds its default ONLY when the key is absent, so anyone who has ever opened
|
||||
// /chat keeps the shape it had then — for good. `appTypes`/`normalizeLayout` does not help: it repairs
|
||||
// which app a panel runs, never the tree, so adding the Live panel above the list would have been
|
||||
// invisible to every existing user and visible only on a fresh account.
|
||||
//
|
||||
// Replacing outright is safe *here* specifically because the screen is `locked`: its structure is
|
||||
// dictated by code and the only thing a user can have contributed is the column sizes, which is a
|
||||
// cheap thing to lose once. Terminates because the replacement contains the panel it tests for.
|
||||
useEffect(() => {
|
||||
if (!workspace.isLoaded) return;
|
||||
if (hasAppType(workspace.value, 'chat-live')) return;
|
||||
workspace.setValue(defaultLayout);
|
||||
}, [workspace.isLoaded, workspace.value, workspace.setValue]);
|
||||
|
||||
// Retire a legacy `?cwd=`. Nothing reads it any more and nothing writes it, but a refresh re-requests
|
||||
// the address bar verbatim — so one left over from before the path-based groups sits there forever,
|
||||
@@ -98,15 +120,20 @@ export const SessionListPage = ({ isNew }: SessionListPageProps) => {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [sessionId, isNew, groupCwd]);
|
||||
|
||||
// The tabbed, multi-pane chat replaces the fixed three-panel workspace. The panels themselves are
|
||||
// unchanged and still registered for the dashboard; what changes is that a PANE owns its conversation
|
||||
// rather than the whole screen sharing one, which is what lets two machines be live side by side.
|
||||
//
|
||||
// `useDashboardState`/`WorkspaceView` are no longer used here. The layout that matters now is the tab
|
||||
// blob in localStorage, because a tab spanning two servers cannot be stored per server.
|
||||
return (
|
||||
<div className="h-full w-full pt-2">
|
||||
<ChatTabs />
|
||||
<WorkspaceView
|
||||
workspace={workspace}
|
||||
locked
|
||||
appTypes={{ allowed: ['chat-session-list', 'chat-live', 'chat-detail'], fallback: 'chat-detail' }}
|
||||
mobilePanelId={mobilePanelId}
|
||||
onMobilePanelChange={(id) => {
|
||||
// Back goes to the group's list, not the default one. On /chat/g/* that group is in the URL;
|
||||
// on /chat/<id> it isn't (deliberately — see chat-routes.ts), so fall back to the open
|
||||
// session's own directory, which the resolve above put on the selection.
|
||||
if (!id) navigate(chatListPath(groupCwd ?? selectedRef.current?.cwd ?? null), { replace: true });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user