fix: loading shared sessions (#3607)

This commit is contained in:
Zane
2025-07-23 12:52:37 -07:00
committed by GitHub
parent 8c8da7cf94
commit 229a49bfdc
2 changed files with 79 additions and 77 deletions
+22 -40
View File
@@ -535,17 +535,18 @@ const SharedSessionRouteWrapper = ({
const location = useLocation(); const location = useLocation();
const navigate = useNavigate(); const navigate = useNavigate();
const sessionDetails = location.state?.sessionDetails as SharedSessionDetails | null; const historyState = window.history.state;
const error = location.state?.error || sharedSessionError; const sessionDetails = (location.state?.sessionDetails ||
const shareToken = location.state?.shareToken; historyState?.sessionDetails) as SharedSessionDetails | null;
const baseUrl = location.state?.baseUrl; const error = location.state?.error || historyState?.error || sharedSessionError;
const shareToken = location.state?.shareToken || historyState?.shareToken;
const baseUrl = location.state?.baseUrl || historyState?.baseUrl;
return ( return (
<SharedSessionView <SharedSessionView
session={sessionDetails} session={sessionDetails}
isLoading={isLoadingSharedSession} isLoading={isLoadingSharedSession}
error={error} error={error}
onBack={() => navigate('/sessions')}
onRetry={async () => { onRetry={async () => {
if (shareToken && baseUrl) { if (shareToken && baseUrl) {
setIsLoadingSharedSession(true); setIsLoadingSharedSession(true);
@@ -1024,51 +1025,32 @@ export default function App() {
const handleOpenSharedSession = async (_event: IpcRendererEvent, ...args: unknown[]) => { const handleOpenSharedSession = async (_event: IpcRendererEvent, ...args: unknown[]) => {
const link = args[0] as string; const link = args[0] as string;
window.electron.logInfo(`Opening shared session from deep link ${link}`); window.electron.logInfo(`Opening shared session from deep link ${link}`);
setIsLoadingSession(true); setIsLoadingSharedSession(true);
setSharedSessionError(null); setSharedSessionError(null);
try { try {
await openSharedSessionFromDeepLink( await openSharedSessionFromDeepLink(
link, link,
(view: View, _options?: SessionLinksViewOptions) => { (_view: View, _options?: SessionLinksViewOptions) => {
// Convert view to route navigation // Navigate to shared session view with the session data
switch (view) { window.location.hash = '#/shared-session';
case 'chat': if (_options) {
window.history.replaceState({}, '', '/'); window.history.replaceState(_options, '', '#/shared-session');
break;
case 'settings':
window.history.replaceState({}, '', '/settings');
break;
case 'sessions':
window.history.replaceState({}, '', '/sessions');
break;
case 'schedules':
window.history.replaceState({}, '', '/schedules');
break;
case 'recipes':
window.history.replaceState({}, '', '/recipes');
break;
case 'permission':
window.history.replaceState({}, '', '/permission');
break;
case 'ConfigureProviders':
window.history.replaceState({}, '', '/configure-providers');
break;
case 'sharedSession':
window.history.replaceState({}, '', '/shared-session');
break;
case 'recipeEditor':
window.history.replaceState({}, '', '/recipe-editor');
break;
default:
window.history.replaceState({}, '', '/');
} }
} }
); );
} catch (error) { } catch (error) {
console.error('Unexpected error opening shared session:', error); console.error('Unexpected error opening shared session:', error);
window.history.replaceState({}, '', '/sessions'); // Navigate to shared session view with error
window.location.hash = '#/shared-session';
const shareToken = link.replace('goose://sessions/', '');
const options = {
sessionDetails: null,
error: error instanceof Error ? error.message : 'Unknown error',
shareToken,
};
window.history.replaceState(options, '', '#/shared-session');
} finally { } finally {
setIsLoadingSession(false); setIsLoadingSharedSession(false);
} }
}; };
window.electron.on('open-shared-session', handleOpenSharedSession); window.electron.on('open-shared-session', handleOpenSharedSession);
@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { Calendar, MessageSquareText, Folder, Target } from 'lucide-react'; import { Calendar, MessageSquareText, Folder, Target, LoaderCircle, Share2 } from 'lucide-react';
import { type SharedSessionDetails } from '../../sharedSessions'; import { type SharedSessionDetails } from '../../sharedSessions';
import { SessionHeaderCard, SessionMessages } from './SessionViewComponents'; import { SessionMessages } from './SessionViewComponents';
import { formatMessageTimestamp } from '../../utils/timeUtils'; import { formatMessageTimestamp } from '../../utils/timeUtils';
import { MainPanelLayout } from '../Layout/MainPanelLayout'; import { MainPanelLayout } from '../Layout/MainPanelLayout';
@@ -9,53 +9,73 @@ interface SharedSessionViewProps {
session: SharedSessionDetails | null; session: SharedSessionDetails | null;
isLoading: boolean; isLoading: boolean;
error: string | null; error: string | null;
onBack: () => void;
onRetry: () => void; onRetry: () => void;
} }
// Custom SessionHeader component matching SessionHistoryView style
const SessionHeader: React.FC<{
children: React.ReactNode;
title: string;
}> = ({ children, title }) => {
return (
<div className="flex flex-col pb-8 border-b">
<h1 className="text-4xl font-light mb-4 pt-6">{title}</h1>
<div className="flex items-center">{children}</div>
</div>
);
};
const SharedSessionView: React.FC<SharedSessionViewProps> = ({ const SharedSessionView: React.FC<SharedSessionViewProps> = ({
session, session,
isLoading, isLoading,
error, error,
onBack,
onRetry, onRetry,
}) => { }) => {
return ( return (
<MainPanelLayout> <MainPanelLayout>
<div className="flex flex-col h-full"> <div className="flex-1 flex flex-col min-h-0 px-8">
<div className="relative flex items-center h-14 w-full"></div> <div className="flex items-center py-4 border-b border-border-subtle mb-6">
<div className="flex items-center text-text-muted">
{/* Top Row - back, info (fixed) */} <Share2 className="w-5 h-5 mr-2" />
<SessionHeaderCard onBack={onBack}> <span className="text-sm font-medium">Shared Session</span>
{/* Session info row */}
<div className="ml-8">
<h1 className="text-lg text-textStandardInverse">
{session ? session.description : 'Shared Session'}
</h1>
<div className="flex items-center text-sm text-textSubtle mt-1 space-x-5">
<span className="flex items-center">
<Calendar className="w-4 h-4 mr-1" />
{session ? formatMessageTimestamp(session.messages[0]?.created) : 'Unknown'}
</span>
<span className="flex items-center">
<MessageSquareText className="w-4 h-4 mr-1" />
{session ? session.message_count : 0}
</span>
{session && session.total_tokens !== null && (
<span className="flex items-center">
<Target className="w-4 h-4 mr-1" />
{session.total_tokens.toLocaleString()}
</span>
)}
</div>
<div className="flex items-center text-sm text-textSubtle space-x-5">
<span className="flex items-center">
<Folder className="w-4 h-4 mr-1" />
{session ? session.working_dir : 'Unknown'}
</span>
</div>
</div> </div>
</SessionHeaderCard> </div>
<SessionHeader title={session ? session.description : 'Shared Session'}>
<div className="flex flex-col">
{!isLoading && session && session.messages.length > 0 ? (
<>
<div className="flex items-center text-text-muted text-sm space-x-5 font-mono">
<span className="flex items-center">
<Calendar className="w-4 h-4 mr-1" />
{formatMessageTimestamp(session.messages[0]?.created)}
</span>
<span className="flex items-center">
<MessageSquareText className="w-4 h-4 mr-1" />
{session.message_count}
</span>
{session.total_tokens !== null && (
<span className="flex items-center">
<Target className="w-4 h-4 mr-1" />
{session.total_tokens.toLocaleString()}
</span>
)}
</div>
<div className="flex items-center text-text-muted text-sm mt-1 font-mono">
<span className="flex items-center">
<Folder className="w-4 h-4 mr-1" />
{session.working_dir}
</span>
</div>
</>
) : (
<div className="flex items-center text-text-muted text-sm">
<LoaderCircle className="w-4 h-4 mr-2 animate-spin" />
<span>Loading session details...</span>
</div>
)}
</div>
</SessionHeader>
<SessionMessages <SessionMessages
messages={session?.messages || []} messages={session?.messages || []}