-
Notifications
You must be signed in to change notification settings - Fork 434
Expand file tree
/
Copy pathScreenState.tsx
More file actions
118 lines (108 loc) · 4.84 KB
/
ScreenState.tsx
File metadata and controls
118 lines (108 loc) · 4.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import type { UseChatHelpers } from '@ai-sdk/react';
import type { AutocompleteApi, AutocompleteState, BaseItem } from '@algolia/autocomplete-core';
import React from 'react';
import type { AskAiScreenTranslations } from './AskAiScreen';
import { AskAiScreen } from './AskAiScreen';
import { ConversationHistoryScreen } from './ConversationHistoryScreen';
import type { DocSearchProps } from './DocSearch';
import type { ErrorScreenTranslations } from './ErrorScreen';
import { ErrorScreen } from './ErrorScreen';
import type { NewConversationTranslations } from './NewConversationScreen';
import { NewConversationScreen } from './NewConversationScreen';
import type { NoResultsScreenTranslations } from './NoResultsScreen';
import { NoResultsScreen } from './NoResultsScreen';
import type { ResultsScreenTranslations } from './ResultsScreen';
import { ResultsScreen } from './ResultsScreen';
import type { StartScreenTranslations } from './StartScreen';
import { StartScreen } from './StartScreen';
import type { StoredSearchPlugin } from './stored-searches';
import type { InternalDocSearchHit, StoredAskAiState, StoredDocSearchHit } from './types';
import type { AIMessage, AskAiState } from './types/AskiAi';
export type ScreenStateTranslations = Partial<{
errorScreen: ErrorScreenTranslations;
startScreen: StartScreenTranslations;
noResultsScreen: NoResultsScreenTranslations;
resultsScreen: ResultsScreenTranslations;
askAiScreen: AskAiScreenTranslations;
newConversation: NewConversationTranslations;
}>;
export interface ScreenStateProps<TItem extends BaseItem>
extends AutocompleteApi<TItem, React.FormEvent, React.MouseEvent, React.KeyboardEvent> {
state: AutocompleteState<TItem>;
recentSearches: StoredSearchPlugin<StoredDocSearchHit>;
favoriteSearches: StoredSearchPlugin<StoredDocSearchHit>;
conversations: StoredSearchPlugin<StoredAskAiState>;
onItemClick: (item: InternalDocSearchHit, event: KeyboardEvent | MouseEvent) => void;
onAskAiToggle: (toggle: boolean) => void;
isAskAiActive: boolean;
canHandleAskAi: boolean;
inputRef: React.MutableRefObject<HTMLInputElement | null>;
hitComponent: DocSearchProps['hitComponent'];
indexName: DocSearchProps['indexName'];
messages: UseChatHelpers<AIMessage>['messages'];
status: UseChatHelpers<AIMessage>['status'];
askAiStreamError: Error | null;
askAiFetchError: Error | undefined;
disableUserPersonalization: boolean;
resultsFooterComponent: DocSearchProps['resultsFooterComponent'];
translations: ScreenStateTranslations;
getMissingResultsUrl?: DocSearchProps['getMissingResultsUrl'];
hasCollections: boolean;
onFeedback?: (messageId: string, thumbs: 0 | 1) => Promise<void>;
askAiState: AskAiState;
selectAskAiQuestion: (toggle: boolean, query: string) => void;
}
export const ScreenState = React.memo(
({ translations = {}, ...props }: ScreenStateProps<InternalDocSearchHit>) => {
if (props.canHandleAskAi && props.isAskAiActive && props.askAiState === 'conversation-history') {
return <ConversationHistoryScreen {...props} />;
}
if (props.canHandleAskAi && props.isAskAiActive && props.askAiState === 'new-conversation') {
return (
<NewConversationScreen
translations={translations?.newConversation}
selectSuggestedQuestion={(query: string) => {
props.selectAskAiQuestion(true, query);
}}
/>
);
}
if (props.isAskAiActive && props.canHandleAskAi) {
return (
<AskAiScreen
{...props}
messages={props.messages}
status={props.status}
askAiStreamError={props.askAiStreamError}
askAiFetchError={props.askAiFetchError}
translations={translations?.askAiScreen}
/>
);
}
if (props.state?.status === 'error') {
return <ErrorScreen translations={translations?.errorScreen} />;
}
if (!props.state.query) {
return <StartScreen {...props} hasCollections={props.hasCollections} translations={translations?.startScreen} />;
}
if (!props.hasCollections && !props.canHandleAskAi) {
return <NoResultsScreen {...props} translations={translations?.noResultsScreen} />;
}
return (
<>
<ResultsScreen {...props} translations={translations?.resultsScreen} />
{props.canHandleAskAi && props.state.collections.length === 1 && (
// if there's one collection it is the ask ai action, show the no results screen
<NoResultsScreen {...props} translations={translations?.noResultsScreen} />
)}
</>
);
},
function areEqual(_prevProps, nextProps) {
// We don't update the screen when Autocomplete is loading or stalled to
// avoid UI flashes:
// - Empty screen → Results screen
// - NoResults screen → NoResults screen with another query
return nextProps.state.status === 'loading' || nextProps.state.status === 'stalled';
},
);