mirror of
https://github.com/aaif-goose/goose.git
synced 2026-07-03 14:10:03 +02:00
feat: Added scroll state support for chat-session-list navigation (#4360)
This commit is contained in:
@@ -155,9 +155,10 @@ interface SearchContainerElement extends HTMLDivElement {
|
||||
interface SessionListViewProps {
|
||||
setView: (view: View, viewOptions?: ViewOptions) => void;
|
||||
onSelectSession: (sessionId: string) => void;
|
||||
selectedSessionId?: string | null;
|
||||
}
|
||||
|
||||
const SessionListView: React.FC<SessionListViewProps> = React.memo(({ onSelectSession }) => {
|
||||
const SessionListView: React.FC<SessionListViewProps> = React.memo(({ onSelectSession, selectedSessionId }) => {
|
||||
const [sessions, setSessions] = useState<Session[]>([]);
|
||||
const [filteredSessions, setFilteredSessions] = useState<Session[]>([]);
|
||||
const [dateGroups, setDateGroups] = useState<DateGroup[]>([]);
|
||||
@@ -182,6 +183,16 @@ const SessionListView: React.FC<SessionListViewProps> = React.memo(({ onSelectSe
|
||||
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// Track session to element ref
|
||||
const sessionRefs = useRef<Record<string, HTMLElement>>({});
|
||||
const setSessionRefs = (itemId: string, element: HTMLDivElement | null) => {
|
||||
if (element) {
|
||||
sessionRefs.current[itemId] = element;
|
||||
} else {
|
||||
delete sessionRefs.current[itemId];
|
||||
}
|
||||
};
|
||||
|
||||
const loadSessions = useCallback(async () => {
|
||||
setIsLoading(true);
|
||||
setShowSkeleton(true);
|
||||
@@ -240,6 +251,18 @@ const SessionListView: React.FC<SessionListViewProps> = React.memo(({ onSelectSe
|
||||
});
|
||||
}, [memoizedDateGroups]);
|
||||
|
||||
// Scroll to the selected session when returning from session history view
|
||||
useEffect(() => {
|
||||
if (selectedSessionId) {
|
||||
const element = sessionRefs.current[selectedSessionId];
|
||||
if (element) {
|
||||
element.scrollIntoView({
|
||||
block: "center"
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [selectedSessionId, sessions]);
|
||||
|
||||
// Debounced search effect - performs actual filtering
|
||||
useEffect(() => {
|
||||
if (!debouncedSearchTerm) {
|
||||
@@ -350,6 +373,7 @@ const SessionListView: React.FC<SessionListViewProps> = React.memo(({ onSelectSe
|
||||
<Card
|
||||
onClick={handleCardClick}
|
||||
className="session-item h-full py-3 px-4 hover:shadow-default cursor-pointer transition-all duration-150 flex flex-col justify-between relative group"
|
||||
ref={(el) => setSessionRefs(session.id, el)}
|
||||
>
|
||||
<button
|
||||
onClick={handleEditClick}
|
||||
|
||||
@@ -12,6 +12,7 @@ interface SessionsViewProps {
|
||||
|
||||
const SessionsView: React.FC<SessionsViewProps> = ({ setView }) => {
|
||||
const [selectedSession, setSelectedSession] = useState<SessionDetails | null>(null);
|
||||
const [showSessionHistory, setShowSessionHistory] = useState(false);
|
||||
const [isLoadingSession, setIsLoadingSession] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [initialSessionId, setInitialSessionId] = useState<string | null>(null);
|
||||
@@ -20,6 +21,7 @@ const SessionsView: React.FC<SessionsViewProps> = ({ setView }) => {
|
||||
const loadSessionDetails = async (sessionId: string) => {
|
||||
setIsLoadingSession(true);
|
||||
setError(null);
|
||||
setShowSessionHistory(true);
|
||||
try {
|
||||
const sessionDetails = await fetchSessionDetails(sessionId);
|
||||
setSelectedSession(sessionDetails);
|
||||
@@ -28,6 +30,7 @@ const SessionsView: React.FC<SessionsViewProps> = ({ setView }) => {
|
||||
setError('Failed to load session details. Please try again later.');
|
||||
// Keep the selected session null if there's an error
|
||||
setSelectedSession(null);
|
||||
setShowSessionHistory(false);
|
||||
|
||||
const errorMessage = err instanceof Error ? err.message : String(err);
|
||||
toastError({
|
||||
@@ -59,7 +62,7 @@ const SessionsView: React.FC<SessionsViewProps> = ({ setView }) => {
|
||||
}, [location.state, handleSelectSession]);
|
||||
|
||||
const handleBackToSessions = () => {
|
||||
setSelectedSession(null);
|
||||
setShowSessionHistory(false);
|
||||
setError(null);
|
||||
};
|
||||
|
||||
@@ -69,9 +72,9 @@ const SessionsView: React.FC<SessionsViewProps> = ({ setView }) => {
|
||||
}
|
||||
};
|
||||
|
||||
// If we're loading an initial session or have a selected session, show the session history view
|
||||
// If we're loading an initial session or have a selected showSessionHistory, show the session history view
|
||||
// Otherwise, show the sessions list view
|
||||
return selectedSession || (isLoadingSession && initialSessionId) ? (
|
||||
return (showSessionHistory && selectedSession) || (isLoadingSession && initialSessionId) ? (
|
||||
<SessionHistoryView
|
||||
session={
|
||||
selectedSession || {
|
||||
@@ -91,7 +94,11 @@ const SessionsView: React.FC<SessionsViewProps> = ({ setView }) => {
|
||||
onRetry={handleRetryLoadSession}
|
||||
/>
|
||||
) : (
|
||||
<SessionListView setView={setView} onSelectSession={handleSelectSession} />
|
||||
<SessionListView
|
||||
setView={setView}
|
||||
onSelectSession={handleSelectSession}
|
||||
selectedSessionId={selectedSession?.session_id ?? null}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user