fix: loading shared sessions (#3607)
This commit is contained in:
+22
-40
@@ -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 || []}
|
||||||
|
|||||||
Reference in New Issue
Block a user