diff --git a/ui/desktop/src/components/sessions/SessionHistoryView.tsx b/ui/desktop/src/components/sessions/SessionHistoryView.tsx index 12fc9e1a..2453b72c 100644 --- a/ui/desktop/src/components/sessions/SessionHistoryView.tsx +++ b/ui/desktop/src/components/sessions/SessionHistoryView.tsx @@ -1,9 +1,19 @@ import React, { useState, useEffect } from 'react'; -import { Clock, MessageSquare, Folder, Share, Copy, Check, LoaderCircle } from 'lucide-react'; +import { + Calendar, + MessageSquareText, + Folder, + Share2, + Sparkles, + Copy, + Check, + Target, + LoaderCircle, +} from 'lucide-react'; import { type SessionDetails } from '../../sessions'; -import { SessionHeaderCard, SessionMessages } from './SessionViewComponents'; +import { SessionHeaderCard, SessionMessages, formatDate } from './SessionViewComponents'; import { createSharedSession } from '../../sharedSessions'; -import { Modal, ModalContent, ModalHeader, ModalTitle, ModalFooter } from '../ui/modal'; +import { Modal, ModalContent } from '../ui/modal'; import { Button } from '../ui/button'; import { toast } from 'react-toastify'; @@ -107,27 +117,30 @@ const SessionHistoryView: React.FC = ({ {/* Session info row */}
-

+

{session.metadata.description || session.session_id}

-
+
- - {new Date(session.messages[0]?.created * 1000).toLocaleString()} + + {formatDate(session.messages[0]?.created)} + + + {session.metadata.message_count} + + {session.metadata.total_tokens !== null && ( + + + {session.metadata.total_tokens.toLocaleString()} + + )} +
+
{session.metadata.working_dir} - - - {session.metadata.message_count} messages - - {session.metadata.total_tokens !== null && ( - - {session.metadata.total_tokens.toLocaleString()} tokens - - )}
@@ -135,30 +148,30 @@ const SessionHistoryView: React.FC = ({ - - Resume Session - + +
@@ -171,18 +184,31 @@ const SessionHistoryView: React.FC = ({ {/* Share Link Modal */} - - - Share Session - -
-
-
- {shareLink} -
+ + {/* Share Icon */} +
+ +
+ + {/* Centered Title */} +
+

Share Session (beta)

+
+ + {/* Description & Link */} +
+

+ Share this session link to give others a read only view of your goose chat. +

+ +
+ + {shareLink} +
-

- Share this link with others to give them access to this session. -
- They will need to have Goose installed and session sharing configured. -

- + + {/* Footer */} +
- +
diff --git a/ui/desktop/src/components/sessions/SessionListView.tsx b/ui/desktop/src/components/sessions/SessionListView.tsx index cc955025..616b731b 100644 --- a/ui/desktop/src/components/sessions/SessionListView.tsx +++ b/ui/desktop/src/components/sessions/SessionListView.tsx @@ -1,7 +1,8 @@ import React, { useEffect, useState } from 'react'; import { ViewConfig } from '../../App'; import { - MessageSquare, + MessageSquareText, + Target, LoaderCircle, AlertCircle, Calendar, @@ -46,7 +47,7 @@ const SessionListView: React.FC = ({ setView, onSelectSess // Format date to be more readable // eg. "10:39 PM, Feb 28, 2025" - const formatDate = (dateString: string) => { + const formatDateString = (dateString: string) => { try { const date = new Date(dateString); const time = new Intl.DateTimeFormat('en-US', { @@ -114,7 +115,7 @@ const SessionListView: React.FC = ({ setView, onSelectSess
- {formatDate(session.modified)} + {formatDateString(session.modified)}
@@ -130,12 +131,13 @@ const SessionListView: React.FC = ({ setView, onSelectSess
- + {session.metadata.message_count}
{session.metadata.total_tokens !== null && (
- {session.metadata.total_tokens.toLocaleString()} tokens + + {session.metadata.total_tokens.toLocaleString()}
)}
@@ -148,7 +150,7 @@ const SessionListView: React.FC = ({ setView, onSelectSess
) : (
- +

No chat sessions found

Your chat history will appear here

diff --git a/ui/desktop/src/components/sessions/SessionViewComponents.tsx b/ui/desktop/src/components/sessions/SessionViewComponents.tsx index 85c3fd2a..adc5c781 100644 --- a/ui/desktop/src/components/sessions/SessionViewComponents.tsx +++ b/ui/desktop/src/components/sessions/SessionViewComponents.tsx @@ -9,6 +9,31 @@ import ToolCallWithResponse from '../ToolCallWithResponse'; import { ToolRequestMessageContent, ToolResponseMessageContent } from '../../types/message'; import { type Message } from '../../types/message'; +/** + * Format a timestamp into a human-readable date string + */ +export const formatDate = (timestamp: number) => { + const date = new Date(timestamp * 1000); + + const getOrdinal = (n: number) => { + const s = ['th', 'st', 'nd', 'rd']; + const v = n % 100; + return n + (s[(v - 20) % 10] || s[v] || s[0]); + }; + + const hours = date.toLocaleTimeString('en-US', { + hour: 'numeric', + minute: '2-digit', + hour12: true, + }); + + const month = date.toLocaleString('en-US', { month: 'short' }); + const day = getOrdinal(date.getDate()); + const year = date.getFullYear(); + + return `${hours}, ${month} ${day}, ${year}`; +}; + /** * Get tool responses map from messages */ @@ -50,8 +75,13 @@ export interface SessionHeaderCardProps { */ export const SessionHeaderCard: React.FC = ({ onBack, children }) => { return ( - - + + {children} ); diff --git a/ui/desktop/src/components/sessions/SharedSessionView.tsx b/ui/desktop/src/components/sessions/SharedSessionView.tsx index 2a684661..3cf3ec29 100644 --- a/ui/desktop/src/components/sessions/SharedSessionView.tsx +++ b/ui/desktop/src/components/sessions/SharedSessionView.tsx @@ -1,7 +1,7 @@ import React from 'react'; -import { Clock, Globe, MessageSquare, Folder } from 'lucide-react'; +import { Calendar, MessageSquareText, Folder, Target } from 'lucide-react'; import { type SharedSessionDetails } from '../../sharedSessions'; -import { SessionHeaderCard, SessionMessages } from './SessionViewComponents'; +import { SessionHeaderCard, SessionMessages, formatDate } from './SessionViewComponents'; interface SharedSessionViewProps { session: SharedSessionDetails | null; @@ -20,44 +20,37 @@ const SharedSessionView: React.FC = ({ }) => { return (
-
+
{/* Top Row - back, info (fixed) */} {/* Session info row */}
-

+

{session ? session.description : 'Shared Session'}

- {session && ( -
+
+ + + {formatDate(session.messages[0]?.created)} + + + + {session.message_count} + + {session.total_tokens !== null && ( - - {new Date(session.messages[0]?.created * 1000).toLocaleString()} + + {session.total_tokens.toLocaleString()} - {/* - - {session.base_url} - */} - - - {session.message_count} messages - - {session.total_tokens !== null && ( - - {session.total_tokens.toLocaleString()} tokens - - )} -
- )} - {session && ( -
- - - {session.working_dir} - -
- )} + )} +
+
+ + + {session.working_dir} + +
diff --git a/ui/desktop/src/components/ui/BackButton.tsx b/ui/desktop/src/components/ui/BackButton.tsx index 71131e2e..3867881b 100644 --- a/ui/desktop/src/components/ui/BackButton.tsx +++ b/ui/desktop/src/components/ui/BackButton.tsx @@ -5,6 +5,7 @@ interface BackButtonProps { onClick?: () => void; // Mark onClick as optional className?: string; textSize?: 'sm' | 'base' | 'md' | 'lg'; + iconSize?: 'w-3 h-3' | 'w-4 h-4' | 'w-5 h-5' | 'w-6 h-6' | 'w-7 h-7'; showText?: boolean; // Add new prop } @@ -12,6 +13,7 @@ const BackButton: React.FC = ({ onClick, className = '', textSize = 'sm', + iconSize = 'w-3 h-3', showText = true, }) => { const handleExit = () => { @@ -29,7 +31,7 @@ const BackButton: React.FC = ({ onClick={handleExit} className={`flex items-center text-${textSize} text-textSubtle group hover:text-textStandard ${className}`} > - + {showText && Exit} );